# RadioGroup

## Overview

A set of mutually exclusive options where selecting one automatically deselects all others. Built on Radix UI with full keyboard navigation (arrow keys cycle through options). Use when only one choice from a defined set is valid.

---

## When to Use

- Mutually exclusive configuration options (2–6 items)
- Plan selection (Basic / Pro / Enterprise)
- Response type selection in forms
- Gender, salutation, or category selectors when options are few and fixed

## When NOT to Use

- More than 6 options — use `<Select>` instead.
- Multiple simultaneous selections — use `<Checkbox>` instead.

---

## Anatomy

```
<RadioGroup>
  <div className="flex items-center space-x-2">
    <RadioGroupItem value="option-a" id="option-a" />
    <Label htmlFor="option-a">Option A</Label>
  </div>
</RadioGroup>
```

---

## Props

### RadioGroup

| Prop            | Type                         | Default      | Description                |
| --------------- | ---------------------------- | ------------ | -------------------------- |
| `value`         | `string`                     | —            | Controlled selected value  |
| `defaultValue`  | `string`                     | —            | Uncontrolled initial value |
| `onValueChange` | `(value: string) => void`    | —            | Change handler             |
| `disabled`      | `boolean`                    | `false`      | Disables all items         |
| `orientation`   | `'horizontal' \| 'vertical'` | `'vertical'` | Layout direction           |

### RadioGroupItem

| Prop       | Type                   | Required | Default | Description                                           |
| ---------- | ---------------------- | -------- | ------- | ----------------------------------------------------- |
| `value`    | `string`               | **Yes**  | —       | The option value                                      |
| `id`       | `string`               | **Yes**  | —       | Associates with `<Label htmlFor="...">`               |
| `size`     | `'sm' \| 'md' \| 'lg'` | No       | `'md'`  | Size variant controlling the radio circle dimensions. |
| `disabled` | `boolean`              | No       | `false` | Disables this specific item                           |

---

## Examples

### Vertical List

```tsx
import { RadioGroup, RadioGroupItem, Label } from 'xertica-ui/ui';

<RadioGroup defaultValue="editor">
  <div className="flex items-center space-x-2">
    <RadioGroupItem value="admin" id="admin" />
    <Label htmlFor="admin">Administrator</Label>
  </div>
  <div className="flex items-center space-x-2">
    <RadioGroupItem value="editor" id="editor" />
    <Label htmlFor="editor">Editor</Label>
  </div>
  <div className="flex items-center space-x-2">
    <RadioGroupItem value="viewer" id="viewer" />
    <Label htmlFor="viewer">Viewer</Label>
  </div>
</RadioGroup>;
```

### Inside react-hook-form

```tsx
<FormField
  control={form.control}
  name="role"
  render={({ field }) => (
    <FormItem>
      <FormLabel>Role</FormLabel>
      <FormControl>
        <RadioGroup
          onValueChange={field.onChange}
          defaultValue={field.value}
          className="flex flex-col space-y-1"
        >
          <FormItem className="flex items-center space-x-2 space-y-0">
            <FormControl>
              <RadioGroupItem value="admin" />
            </FormControl>
            <FormLabel>Administrator</FormLabel>
          </FormItem>
          <FormItem className="flex items-center space-x-2 space-y-0">
            <FormControl>
              <RadioGroupItem value="editor" />
            </FormControl>
            <FormLabel>Editor</FormLabel>
          </FormItem>
        </RadioGroup>
      </FormControl>
      <FormMessage />
    </FormItem>
  )}
/>
```

---

## AI Rules

- Each `RadioGroupItem` requires both `value` and `id`.
- **Sizing** — `RadioGroupItem` supports `sm`, `md`, and `lg`. Ensure the size matches the associated `Label` size.
- The `Label` `htmlFor` must match the `RadioGroupItem` `id`.
- In forms, use `onValueChange={field.onChange}` and `defaultValue={field.value}` — **not** `{...field}`.
- For more than 6 options, switch to `<Select>` instead.

---

## Related Components

- [`Checkbox`](./checkbox.md) — For multi-select lists
- [`Select`](./select.md) — For large option sets
- [`Form`](./form.md)
