# Radio primitive (/components/primitives/radio)

Use the Radio primitive when a layout needs custom placement for a radio group or its options. For
the standard labelled group, use [`RadioGroup`](/components/forms/radio-group).

apps/docs/src/examples/radio-primitive/basic.tsx

```tsx
import { FieldLabel } from '@luke-ui/react/primitives/field';
import {
	RadioControl,
	RadioGroupRoot,
	RadioIndicator,
	RadioLabel,
	RadioRoot,
} from '@luke-ui/react/primitives/radio';
import { Stack } from '@luke-ui/react/stack';

export default () => {
	return (
		<RadioGroupRoot name="alignment">
			<Stack gap="space.8">
				<FieldLabel slot="label">Text alignment</FieldLabel>
				<RadioRoot value="left">
					<RadioLabel>
						<RadioControl>
							<RadioIndicator />
						</RadioControl>
						Left
					</RadioLabel>
				</RadioRoot>
				<RadioRoot value="right">
					<RadioLabel>
						<RadioControl>
							<RadioIndicator />
						</RadioControl>
						Right
					</RadioLabel>
				</RadioRoot>
			</Stack>
		</RadioGroupRoot>
	);
};
```

## Anatomy [#anatomy]

`RadioGroupRoot` owns the selection, accessible group name, validation, form value, and size.
`RadioRoot` represents one option and takes its `value`. `RadioLabel` provides the clickable option
label. Place `RadioControl` inside it, with `RadioIndicator` inside the control.

Use `FieldLabel`, `FieldDescription`, and `FieldError` inside `RadioGroupRoot` when the group label,
description, or error needs a custom position. The group root connects those parts to the group.
Place a `FieldDescription` inside `RadioRoot` to describe one option. Each option still needs a
`RadioLabel`.

## Accessibility [#accessibility]

Name `RadioGroupRoot` with `FieldLabel`, `aria-label`, or `aria-labelledby`. Put textual,
non-interactive option text inside each `RadioLabel`, and place links and buttons outside it. The
group supports arrow-key navigation between its options.

## API [#api]

### RadioGroupRootProps [#radiogrouprootprops]

### RadioGroupRootProps

Props for `RadioGroupRoot`.

`RadioGroupRootProps` also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.

| Prop                  | Type                                                              | Description                                                                                                                                                                                                                               |
| --------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `isRequired?`         | `boolean`                                                         | Whether user input is required on the input before form submission.                                                                                                                                                                       |
| `isInvalid?`          | `boolean`                                                         | Whether the input value is invalid.                                                                                                                                                                                                       |
| `validate?`           | `(value: string) => true \| ValidationError \| null \| undefined` | A function that returns an error message if a given value is invalid. Validation errors are displayed to the user when the form is submitted if `validationBehavior="native"`. For realtime validation, use the `isInvalid` prop instead. |
| `isDisabled?`         | `boolean`                                                         | Whether the input is disabled.                                                                                                                                                                                                            |
| `isReadOnly?`         | `boolean`                                                         | Whether the input can be selected but not changed by the user.                                                                                                                                                                            |
| `defaultValue?`       | `string \| null`                                                  | The default value (uncontrolled).                                                                                                                                                                                                         |
| `onChange?`           | `(value: string) => void`                                         | Handler that is called when the value changes.                                                                                                                                                                                            |
| `aria-label?`         | `string`                                                          | Defines a string value that labels the current element.                                                                                                                                                                                   |
| `aria-labelledby?`    | `string`                                                          | Identifies the element (or elements) that labels the current element.                                                                                                                                                                     |
| `aria-describedby?`   | `string`                                                          | Identifies the element (or elements) that describes the object.                                                                                                                                                                           |
| `aria-details?`       | `string`                                                          | Identifies the element (or elements) that provide a detailed, extended description for the object.                                                                                                                                        |
| `aria-errormessage?`  | `string`                                                          | Identifies the element that provides an error message for the object.                                                                                                                                                                     |
| `id?`                 | `string`                                                          | The element's unique identifier. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id).                                                                                                                       |
| `name?`               | `string`                                                          | The name of the input element, used when submitting an HTML form. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefname).                                                                             |
| `onFocus?`            | `(e: React.FocusEvent<Element, Element>) => void`                 | Handler that is called when the element receives focus.                                                                                                                                                                                   |
| `onBlur?`             | `(e: React.FocusEvent<Element, Element>) => void`                 | Handler that is called when the element loses focus.                                                                                                                                                                                      |
| `onFocusChange?`      | `(isFocused: boolean) => void`                                    | Handler that is called when the element's focus status changes.                                                                                                                                                                           |
| `orientation?`        | `Orientation`                                                     | The axis the Radio Button(s) should align with. Default: `'vertical'`                                                                                                                                                                     |
| `slot?`               | `string \| null`                                                  | A slot name for the component. Slots allow the component to receive props from a parent component. An explicit `null` value indicates that the local props completely override all props received from a parent.                          |
| `validationBehavior?` | `'native' \| 'aria'`                                              | Whether to use native HTML form validation to prevent form submission when the value is missing or invalid, or mark the field as required or invalid via ARIA. Default: `'native'`                                                        |
| `children`            | `ChildrenOrFunction<RadioGroupRenderProps>`                       | The group label, description, error, and radio options.                                                                                                                                                                                   |
| `className?`          | `ClassNameOrFunction<RadioGroupRenderProps> \| undefined`         | Class name for the group root.                                                                                                                                                                                                            |
| `value?`              | `string \| null \| undefined`                                     | Selected option value when the group is controlled.                                                                                                                                                                                       |
| `size?`               | `ControlSize`                                                     | Visual size supplied to options that do not set their own size. Default: `'medium'`                                                                                                                                                       |
| `ref?`                | `Ref<HTMLDivElement>`                                             | Forwarded to the group root element.                                                                                                                                                                                                      |

#### Type definitions

These are the types that this table's signatures and the definitions below name. TypeScript's built-in types, such as `Omit` and `ReadonlyArray`, are not listed.

##### `ControlSize`

```ts
type ControlSize = 'small' | 'medium';
```

##### `ValidationError`

Declared in [`@react-types/shared`](https://www.npmjs.com/package/@react-types/shared) (`src/inputs.d.ts`).

```ts
type ValidationError = string | string[];
```

##### `FocusEvent`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `Orientation`

Declared in [`@react-types/shared`](https://www.npmjs.com/package/@react-types/shared) (`src/orientation.d.ts`).

```ts
type Orientation = 'horizontal' | 'vertical';
```

##### `ChildrenOrFunction`

Declared in [`react-aria-components`](https://www.npmjs.com/package/react-aria-components) (`dist/types/src/utils.d.ts`).

```ts
type ChildrenOrFunction<T> = ReactNode | ((values: T & {
  defaultChildren: ReactNode | undefined;
}) => ReactNode);
```

Refers to `ReactNode`.

##### `ReactNode`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `RadioGroupRenderProps`

Declared in [`react-aria-components`](https://www.npmjs.com/package/react-aria-components) (`dist/types/src/RadioGroup.d.ts`).

##### `ClassNameOrFunction`

Declared in [`react-aria-components`](https://www.npmjs.com/package/react-aria-components) (`dist/types/src/utils.d.ts`).

```ts
type ClassNameOrFunction<T> = string | ((values: T & {
  defaultClassName: string | undefined;
}) => string);
```

##### `Ref`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

```ts
type Ref<T> = RefCallback<T>
  | RefObject<T | null>
  | null;
```

Refers to `RefCallback` and `RefObject`.

##### `RefCallback`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `RefObject`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

### RadioRootProps [#radiorootprops]

### RadioRootProps

Props for `RadioRoot`.

`RadioRootProps` also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.

| Prop                | Type                                                      | Description                                                                                                                                                                                                      |
| ------------------- | --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `aria-label?`       | `string`                                                  | Defines a string value that labels the current element.                                                                                                                                                          |
| `aria-labelledby?`  | `string`                                                  | Identifies the element (or elements) that labels the current element.                                                                                                                                            |
| `aria-describedby?` | `string`                                                  | Identifies the element (or elements) that describes the object.                                                                                                                                                  |
| `aria-details?`     | `string`                                                  | Identifies the element (or elements) that provide a detailed, extended description for the object.                                                                                                               |
| `onKeyDown?`        | `(e: KeyboardEvent) => void`                              | Handler that is called when a key is pressed.                                                                                                                                                                    |
| `onKeyUp?`          | `(e: KeyboardEvent) => void`                              | Handler that is called when a key is released.                                                                                                                                                                   |
| `onFocus?`          | `(e: React.FocusEvent<Element, Element>) => void`         | Handler that is called when the element receives focus.                                                                                                                                                          |
| `onBlur?`           | `(e: React.FocusEvent<Element, Element>) => void`         | Handler that is called when the element loses focus.                                                                                                                                                             |
| `onFocusChange?`    | `(isFocused: boolean) => void`                            | Handler that is called when the element's focus status changes.                                                                                                                                                  |
| `onPress?`          | `(e: PressEvent) => void`                                 | Handler that is called when the press is released over the target.                                                                                                                                               |
| `onPressStart?`     | `(e: PressEvent) => void`                                 | Handler that is called when a press interaction starts.                                                                                                                                                          |
| `onPressEnd?`       | `(e: PressEvent) => void`                                 | Handler that is called when a press interaction ends, either over the target or when the pointer leaves the target.                                                                                              |
| `onPressChange?`    | `(isPressed: boolean) => void`                            | Handler that is called when the press state changes.                                                                                                                                                             |
| `onPressUp?`        | `(e: PressEvent) => void`                                 | Handler that is called when a press is released over the target, regardless of whether it started on the target or not.                                                                                          |
| `autoFocus?`        | `boolean`                                                 | Whether the element should receive focus on render.                                                                                                                                                              |
| `isDisabled?`       | `boolean`                                                 | Whether the radio button is disabled or not. Shows that a selection exists, but is not available in that circumstance.                                                                                           |
| `slot?`             | `string \| null`                                          | A slot name for the component. Slots allow the component to receive props from a parent component. An explicit `null` value indicates that the local props completely override all props received from a parent. |
| `children`          | `ChildrenOrFunction<RadioFieldRenderProps>`               | Radio label, control, and optional description.                                                                                                                                                                  |
| `className?`        | `ClassNameOrFunction<RadioFieldRenderProps> \| undefined` | Class name for the option root.                                                                                                                                                                                  |
| `value`             | `string`                                                  | Value submitted when this option is selected.                                                                                                                                                                    |
| `id?`               | `string`                                                  | Element id for the option root. Use `inputId` for the radio input.                                                                                                                                               |
| `inputId?`          | `string \| undefined`                                     | Element id for the input.                                                                                                                                                                                        |
| `inputRef?`         | `Ref<HTMLInputElement \| null> \| undefined`              | Forwarded to the hidden radio input.                                                                                                                                                                             |
| `ref?`              | `Ref<HTMLDivElement>`                                     | Forwarded to the option root element.                                                                                                                                                                            |
| `size?`             | `"medium" \| "small" \| undefined`                        | Visual size of the radio option. Defaults to the group size, then `Form.controlSize`, then `medium`.                                                                                                             |

#### Type definitions

These are the types that this table's signatures and the definitions below name. TypeScript's built-in types, such as `Omit` and `ReadonlyArray`, are not listed.

##### `KeyboardEvent`

Declared in [`@react-types/shared`](https://www.npmjs.com/package/@react-types/shared) (`src/events.d.ts`).

```ts
type KeyboardEvent = BaseEvent<ReactKeyboardEvent<any>>;
```

Refers to `BaseEvent` and `KeyboardEvent` from `@types/react`.

##### `BaseEvent`

Declared in [`@react-types/shared`](https://www.npmjs.com/package/@react-types/shared) (`src/events.d.ts`).

##### `KeyboardEvent` from `@types/react` (written as `ReactKeyboardEvent`)

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `FocusEvent`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `PressEvent`

Declared in [`@react-types/shared`](https://www.npmjs.com/package/@react-types/shared) (`src/events.d.ts`).

##### `ChildrenOrFunction`

Declared in [`react-aria-components`](https://www.npmjs.com/package/react-aria-components) (`dist/types/src/utils.d.ts`).

```ts
type ChildrenOrFunction<T> = ReactNode | ((values: T & {
  defaultChildren: ReactNode | undefined;
}) => ReactNode);
```

Refers to `ReactNode`.

##### `ReactNode`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `RadioFieldRenderProps`

Declared in [`react-aria-components`](https://www.npmjs.com/package/react-aria-components) (`dist/types/src/RadioGroup.d.ts`).

##### `ClassNameOrFunction`

Declared in [`react-aria-components`](https://www.npmjs.com/package/react-aria-components) (`dist/types/src/utils.d.ts`).

```ts
type ClassNameOrFunction<T> = string | ((values: T & {
  defaultClassName: string | undefined;
}) => string);
```

##### `Ref`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

```ts
type Ref<T> = RefCallback<T>
  | RefObject<T | null>
  | null;
```

Refers to `RefCallback` and `RefObject`.

##### `RefCallback`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `RefObject`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

### RadioLabelProps [#radiolabelprops]

### RadioLabelProps

Props for `RadioLabel`.

`RadioLabelProps` also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.

| Prop             | Type                                                       | Description                                                                                                                                                                                                      |
| ---------------- | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `onHoverStart?`  | `(e: HoverEvent) => void`                                  | Handler that is called when a hover interaction starts.                                                                                                                                                          |
| `onHoverEnd?`    | `(e: HoverEvent) => void`                                  | Handler that is called when a hover interaction ends.                                                                                                                                                            |
| `onHoverChange?` | `(isHovering: boolean) => void`                            | Handler that is called when the hover state changes.                                                                                                                                                             |
| `children?`      | `ChildrenOrFunction<RadioButtonRenderProps>`               | The children of the component. A function may be provided to alter the children based on component state.                                                                                                        |
| `slot?`          | `string \| null`                                           | A slot name for the component. Slots allow the component to receive props from a parent component. An explicit `null` value indicates that the local props completely override all props received from a parent. |
| `className?`     | `ClassNameOrFunction<RadioButtonRenderProps> \| undefined` | Class name for the clickable label.                                                                                                                                                                              |
| `ref?`           | `Ref<HTMLLabelElement>`                                    | Forwarded to the clickable `<label>` element.                                                                                                                                                                    |

#### Type definitions

These are the types that this table's signatures and the definitions below name. TypeScript's built-in types, such as `Omit` and `ReadonlyArray`, are not listed.

##### `HoverEvent`

Declared in [`@react-types/shared`](https://www.npmjs.com/package/@react-types/shared) (`src/events.d.ts`).

##### `ChildrenOrFunction`

Declared in [`react-aria-components`](https://www.npmjs.com/package/react-aria-components) (`dist/types/src/utils.d.ts`).

```ts
type ChildrenOrFunction<T> = ReactNode | ((values: T & {
  defaultChildren: ReactNode | undefined;
}) => ReactNode);
```

Refers to `ReactNode`.

##### `ReactNode`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `RadioButtonRenderProps`

Declared in [`react-aria-components`](https://www.npmjs.com/package/react-aria-components) (`dist/types/src/RadioGroup.d.ts`).

##### `ClassNameOrFunction`

Declared in [`react-aria-components`](https://www.npmjs.com/package/react-aria-components) (`dist/types/src/utils.d.ts`).

```ts
type ClassNameOrFunction<T> = string | ((values: T & {
  defaultClassName: string | undefined;
}) => string);
```

##### `Ref`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

```ts
type Ref<T> = RefCallback<T>
  | RefObject<T | null>
  | null;
```

Refers to `RefCallback` and `RefObject`.

##### `RefCallback`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `RefObject`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

### RadioControlProps [#radiocontrolprops]

### RadioControlProps

Props for `RadioControl`.

`RadioControlProps` also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.

### RadioIndicatorProps [#radioindicatorprops]

### RadioIndicatorProps

Props for `RadioIndicator`.

`RadioIndicatorProps` also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.
