# Radio Group

A set of checkable buttons, known as radio buttons, where no more than one of the buttons can be checked at a time.

## Import

```
Copyts
import { RadioGroup } from "@kobalte/core/radio-group";
// or
import { Root, Label, ... } from "@kobalte/core/radio-group";
// or (deprecated)
import { RadioGroup } from "@kobalte/core";
```

```
Copyts
import { RadioGroup } from "@kobalte/core/radio-group";
// or
import { Root, Label, ... } from "@kobalte/core/radio-group";
// or (deprecated)
import { RadioGroup } from "@kobalte/core";
```

## Features

- Follow the [WAI ARIA Radio Group](https://www.w3.org/WAI/ARIA/apg/patterns/radiobutton/) design pattern.
- Each radio is built with a native HTML `<input>` element, which is visually hidden to allow custom styling.
- Syncs with form reset events.
- Group and radio labeling support for assistive technology.
- Can be controlled or uncontrolled.

## Anatomy

The radio group consists of:

- **RadioGroup**: The root container for the radio group.
- **RadioGroup.Label**: The label that gives the user information on the radio group.
- **RadioGroup.Description**: The description that gives the user more information on the radio group.
- **RadioGroup.ErrorMessage**: The error message that gives the user information about how to fix a validation error on the radio group.

The radio item consists of:

- **RadioGroup.Item**: The root container for a radio button.
- **RadioGroup.ItemInput**: The native html input that is visually hidden in the radio button.
- **RadioGroup.ItemControl**: The element that visually represents a radio button.
- **RadioGroup.ItemIndicator**: The visual indicator rendered when the radio button is in a checked state.
- **RadioGroup.ItemLabel**: The label that gives the user information on the radio button.
- **RadioGroup.ItemDescription**: The description that gives the user more information on the radio button.

```
Copytsx
<RadioGroup>
	<RadioGroup.Label />
	<RadioGroup.Item>
		<RadioGroup.ItemInput />
		<RadioGroup.ItemControl>
			<RadioGroup.ItemIndicator />
		</RadioGroup.ItemControl>
		<RadioGroup.ItemLabel />
		<RadioGroup.ItemDescription />
	</RadioGroup.Item>
	<RadioGroup.Description />
	<RadioGroup.ErrorMessage />
</RadioGroup>
```

```
Copytsx
<RadioGroup>
	<RadioGroup.Label />
	<RadioGroup.Item>
		<RadioGroup.ItemInput />
		<RadioGroup.ItemControl>
			<RadioGroup.ItemIndicator />
		</RadioGroup.ItemControl>
		<RadioGroup.ItemLabel />
		<RadioGroup.ItemDescription />
	</RadioGroup.Item>
	<RadioGroup.Description />
	<RadioGroup.ErrorMessage />
</RadioGroup>
```

## Example

Favorite fruit

Apple

Orange

Watermelon

index.tsxstyle.css

```
Copytsx
import { RadioGroup } from "@kobalte/core/radio-group";
import "./style.css";

function App() {
  return (
    <RadioGroup class="radio-group">
      <RadioGroup.Label class="radio-group__label">Favorite fruit</RadioGroup.Label>
      <div class="radio-group__items" role="presentation">
        <For each={["Apple", "Orange", "Watermelon"]}>
          {fruit => (
            <RadioGroup.Item value={fruit} class="radio">
              <RadioGroup.ItemInput class="radio__input" />
              <RadioGroup.ItemControl class="radio__control">
                <RadioGroup.ItemIndicator class="radio__indicator" />
              </RadioGroup.ItemControl>
              <RadioGroup.ItemLabel class="radio__label">{fruit}</RadioGroup.ItemLabel>
            </RadioGroup.Item>
          )}
        </For>
      </div>
    </RadioGroup>
  );
}
```

```
Copytsx
import { RadioGroup } from "@kobalte/core/radio-group";
import "./style.css";

function App() {
  return (
    <RadioGroup class="radio-group">
      <RadioGroup.Label class="radio-group__label">Favorite fruit</RadioGroup.Label>
      <div class="radio-group__items" role="presentation">
        <For each={["Apple", "Orange", "Watermelon"]}>
          {fruit => (
            <RadioGroup.Item value={fruit} class="radio">
              <RadioGroup.ItemInput class="radio__input" />
              <RadioGroup.ItemControl class="radio__control">
                <RadioGroup.ItemIndicator class="radio__indicator" />
              </RadioGroup.ItemControl>
              <RadioGroup.ItemLabel class="radio__label">{fruit}</RadioGroup.ItemLabel>
            </RadioGroup.Item>
          )}
        </For>
      </div>
    </RadioGroup>
  );
}
```

## Usage

### Default value

An initial, uncontrolled value can be provided using the `defaultValue` prop, which accepts a value corresponding with the `value` prop of each radio.

Favorite fruit

Apple

Orange

Watermelon

```
Copytsx
<RadioGroup defaultValue="Orange">
	<RadioGroup.Label>Favorite fruit</RadioGroup.Label>
	<div role="presentation">
		<For each={["Apple", "Orange", "Watermelon"]}>
			{fruit => <RadioGroup.Item value={fruit}>...</RadioGroup.Item>}
		</For>
	</div>
</RadioGroup>
```

```
Copytsx
<RadioGroup defaultValue="Orange">
	<RadioGroup.Label>Favorite fruit</RadioGroup.Label>
	<div role="presentation">
		<For each={["Apple", "Orange", "Watermelon"]}>
			{fruit => <RadioGroup.Item value={fruit}>...</RadioGroup.Item>}
		</For>
	</div>
</RadioGroup>
```

The `role="presentation"` is required for all non content elements between the `RadioGroup` and `RadioGroup.Item` due to a bug in Chromium based browsers that incorrectly parse semantics and break screen readers.

### Controlled value

The `value` prop, which accepts a value corresponding with the `value` prop of each radio, can be used to make the value controlled. The `onChange` event is fired when the user selects a radio, and receives the new value.

Favorite fruit

Apple

Orange

Watermelon

Your favorite fruit is: Orange.

```
Copytsx
import { createSignal } from "solid-js";

function ControlledExample() {
	const [value, setValue] = createSignal("Orange");

	return (
		<>
			<RadioGroup value={value()} onChange={setValue}>
				<RadioGroup.Label>Favorite fruit</RadioGroup.Label>
				<div role="presentation">
					<For each={["Apple", "Orange", "Watermelon"]}>
						{fruit => <RadioGroup.Item value={fruit}>...</RadioGroup.Item>}
					</For>
				</div>
			</RadioGroup>
			<p>Your favorite fruit is: {value()}.</p>
		</>
	);
}
```

```
Copytsx
import { createSignal } from "solid-js";

function ControlledExample() {
	const [value, setValue] = createSignal("Orange");

	return (
		<>
			<RadioGroup value={value()} onChange={setValue}>
				<RadioGroup.Label>Favorite fruit</RadioGroup.Label>
				<div role="presentation">
					<For each={["Apple", "Orange", "Watermelon"]}>
						{fruit => <RadioGroup.Item value={fruit}>...</RadioGroup.Item>}
					</For>
				</div>
			</RadioGroup>
			<p>Your favorite fruit is: {value()}.</p>
		</>
	);
}
```

### Description

The `RadioGroup.Description` component can be used to associate additional help text with a radio group.

Favorite fruit

Apple

Orange

Watermelon

Choose the fruit you like the most.

```
Copytsx
<RadioGroup>
	<RadioGroup.Label>Favorite fruit</RadioGroup.Label>
	<div role="presentation">
		<For each={["Apple", "Orange", "Watermelon"]}>
			{fruit => <RadioGroup.Item value={fruit}>...</RadioGroup.Item>}
		</For>
	</div>
	<RadioGroup.Description>Choose the fruit you like the most.</RadioGroup.Description>
</RadioGroup>
```

```
Copytsx
<RadioGroup>
	<RadioGroup.Label>Favorite fruit</RadioGroup.Label>
	<div role="presentation">
		<For each={["Apple", "Orange", "Watermelon"]}>
			{fruit => <RadioGroup.Item value={fruit}>...</RadioGroup.Item>}
		</For>
	</div>
	<RadioGroup.Description>Choose the fruit you like the most.</RadioGroup.Description>
</RadioGroup>
```

### Error message

The `RadioGroup.ErrorMessage` component can be used to help the user fix a validation error. It should be combined with the `validationState` prop to semantically mark the radio group as invalid for assistive technologies.

By default, it will render only when the `validationState` prop is set to `invalid`, use the `forceMount` prop to always render the error message (ex: for usage with animation libraries).

Favorite fruit

Apple

Orange

Watermelon

Hmm, I prefer apples.

```
Copytsx
import { createSignal } from "solid-js";

function ErrorMessageExample() {
	const [value, setValue] = createSignal("Orange");

	return (
		<RadioGroup
			value={value()}
			onChange={setValue}
			validationState={value() !== "Apple" ? "invalid" : "valid"}
		>
			<RadioGroup.Label>Favorite fruit</RadioGroup.Label>
			<div role="presentation">
				<For each={["Apple", "Orange", "Watermelon"]}>
					{fruit => <RadioGroup.Item value={fruit}>...</RadioGroup.Item>}
				</For>
			</div>
			<RadioGroup.ErrorMessage>Hmm, I prefer apples.</RadioGroup.ErrorMessage>
		</RadioGroup>
	);
}
```

```
Copytsx
import { createSignal } from "solid-js";

function ErrorMessageExample() {
	const [value, setValue] = createSignal("Orange");

	return (
		<RadioGroup
			value={value()}
			onChange={setValue}
			validationState={value() !== "Apple" ? "invalid" : "valid"}
		>
			<RadioGroup.Label>Favorite fruit</RadioGroup.Label>
			<div role="presentation">
				<For each={["Apple", "Orange", "Watermelon"]}>
					{fruit => <RadioGroup.Item value={fruit}>...</RadioGroup.Item>}
				</For>
			</div>
			<RadioGroup.ErrorMessage>Hmm, I prefer apples.</RadioGroup.ErrorMessage>
		</RadioGroup>
	);
}
```

### HTML forms

The radio group `name` prop, paired with the radio `value` prop, can be used for integration with HTML forms.

Favorite fruit

Apple

Orange

Watermelon

ResetSubmit

```
Copytsx
function HTMLFormExample() {
	const onSubmit = (e: SubmitEvent) => {
		// handle form submission.
	};

	return (
		<form onSubmit={onSubmit}>
			<RadioGroup name="favorite-fruit">
				<RadioGroup.Label>Favorite fruit</RadioGroup.Label>
				<div role="presentation">
					<For each={["Apple", "Orange", "Watermelon"]}>
						{fruit => <RadioGroup.Item value={fruit}>...</RadioGroup.Item>}
					</For>
				</div>
			</RadioGroup>
			<div>
				<button type="reset">Reset</button>
				<button type="submit">Submit</button>
			</div>
		</form>
	);
}
```

```
Copytsx
function HTMLFormExample() {
	const onSubmit = (e: SubmitEvent) => {
		// handle form submission.
	};

	return (
		<form onSubmit={onSubmit}>
			<RadioGroup name="favorite-fruit">
				<RadioGroup.Label>Favorite fruit</RadioGroup.Label>
				<div role="presentation">
					<For each={["Apple", "Orange", "Watermelon"]}>
						{fruit => <RadioGroup.Item value={fruit}>...</RadioGroup.Item>}
					</For>
				</div>
			</RadioGroup>
			<div>
				<button type="reset">Reset</button>
				<button type="submit">Submit</button>
			</div>
		</form>
	);
}
```

## API Reference

### RadioGroup

`RadioGroup` is equivalent to the `Root` import from `@kobalte/core/radio-group` (and deprecated `RadioGroup.Root`).

| Prop | Description |
| --- | --- |
| value | `string`<br> The controlled value of the radio button to check. |
| defaultValue | `string`<br> The value of the radio button that should be checked when initially rendered. Useful when you do not need to control the state of the radio buttons. |
| onChange | `(value: string) => void`<br> Event handler called when the value changes. |
| orientation | `'horizontal' | 'vertical'`<br> The axis the radio group items should align with. |
| name | `string`<br> The name of the radio group. Submitted with its owning form as part of a name/value pair. |
| validationState | `'valid' | 'invalid'`<br> Whether the radio group should display its "valid" or "invalid" visual styling. |
| required | `boolean`<br> Whether the user must check a radio group item before the owning form can be submitted. |
| disabled | `boolean`<br> Whether the radio group is disabled. |
| readOnly | `boolean`<br> Whether the radio group items can be selected but not changed by the user. |

| Data attribute | Description |
| --- | --- |
| data-valid | Present when the radio group is valid according to the validation rules. |
| data-invalid | Present when the radio group is invalid according to the validation rules. |
| data-required | Present when the user must check a radio group item before the owning form can be submitted. |
| data-disabled | Present when the radio group is disabled. |
| data-readonly | Present when the radio group is read only. |

`RadioGroup.Label`, `RadioGroup.Description` and `RadioGroup.ErrorMesssage` shares the same data-attributes.

### RadioGroup.ErrorMessage

| Prop | Description |
| --- | --- |
| forceMount | `boolean`<br> Used to force mounting when more control is needed. Useful when controlling animation with SolidJS animation libraries. |

### RadioGroup.Item

| Prop | Description |
| --- | --- |
| value | `string`<br> The value of the radio button, used when submitting an HTML form. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio#Value). |
| disabled | `boolean`<br> Whether the radio button is disabled or not. |

| Data attribute | Description |
| --- | --- |
| data-valid | Present when the parent radio group is valid according to the validation rules. |
| data-invalid | Present when the parent radio group is invalid according to the validation rules. |
| data-checked | Present when the radio is checked. |
| data-disabled | Present when the radio is disabled. |

`RadioGroup.ItemInput`, `RadioGroup.ItemControl`, `RadioGroup.ItemIndicator` and `RadioGroup.ItemLabel` shares the same data-attributes.

### RadioGroup.ItemIndicator

| Prop | Description |
| --- | --- |
| forceMount | `boolean`<br> Used to force mounting when more control is needed. Useful when controlling animation with SolidJS animation libraries. |

## Rendered elements

| Component | Default rendered element |
| --- | --- |
| `RadioGroup` | `div` |
| `RadioGroup.Label` | `span` |
| `RadioGroup.Description` | `div` |
| `RadioGroup.ErrorMessage` | `div` |
| `RadioGroup.Item` | `div` |
| `RadioGroup.ItemInput` | `input` |
| `RadioGroup.ItemControl` | `div` |
| `RadioGroup.ItemIndicator` | `div` |
| `RadioGroup.ItemLabel` | `label` |
| `RadioGroup.ItemDescription` | `div` |

## Accessibility

### Keyboard Interactions

| Key | Description |
| --- | --- |
| `Tab` | Moves focus to either the checked radio button or the first radio button in the group. |
| `Space` | When focus is on an unchecked radio button, checks it. |
| `ArrowDown` | Moves focus and checks the next radio button in the group. |
| `ArrowRight` | Moves focus and checks the next radio button in the group. |
| `ArrowUp` | Moves focus and checks the previous radio button in the group. |
| `ArrowLeft` | Moves focus and checks the previous radio button in the group. |

Previous[←Progress](https://kobalte.dev/docs/core/components/progress)Next[Rating Group→](https://kobalte.dev/docs/core/components/rating-group)