<!-- Protocore Design System — RadioGroup -->
# RadioGroup

- **Category:** Inputs (`inputs`)
- **Slug:** `inputs/radio-group`
- **Status:** stable
- **Platforms:** web
- **Import:** `import { RadioGroup, RadioGroupItem } from "@protocore/pds";`
- **Docs:** https://pds.protocore.io/components/inputs/radio-group

> One-of-many selection with sharp square markers; the active option carries the accent fill.

## When to use it

Use a **RadioGroup** for a single choice among a **small, fixed set** (roughly 2–6 options) where seeing every option at once aids the decision. When options exceed what fits comfortably, switch to **Select**. For 2–4 short, equal-weight options that read like a toggle (a view mode, a time range), **SegmentedControl** is more compact. When any number of options may be selected, use **Checkbox** instead.

## Props

### RadioGroup

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `asChild` | `boolean` | no | — | — |
| `className` | `string` | no | — | — |
| `style` | `CSSProperties` | no | — | — |

### RadioGroupItem

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `asChild` | `boolean` | no | — | — |
| `className` | `string` | no | — | — |
| `label` | `ReactNode` | no | — | Text rendered beside the marker (sans 14). |
| `style` | `CSSProperties` | no | — | — |

## Examples

### Basics

Wrap `RadioGroup.Item`s in a `RadioGroup`. Each item takes a `value` and a `label`; the group is controllable via `value` / `defaultValue`.

```tsx
import { RadioGroup } from "@protocore/pds";

export default function Demo() {
  return (
    <RadioGroup.Root defaultValue="standard" aria-label="Replication tier">
      <RadioGroup.Item value="standard" label="Standard — 3 replicas" />
      <RadioGroup.Item value="ha" label="High availability — 5 replicas" />
      <RadioGroup.Item value="single" label="Single node — no replication" />
    </RadioGroup.Root>
  );
}
```

### Disabled option

Disable an individual `RadioGroup.Item` to show an option that exists but isn't available on the current plan.

```tsx
import { RadioGroup } from "@protocore/pds";

export default function Demo() {
  return (
    <RadioGroup.Root defaultValue="team" aria-label="Plan">
      <RadioGroup.Item value="hobby" label="Hobby" />
      <RadioGroup.Item value="team" label="Team" />
      <RadioGroup.Item value="enterprise" label="Enterprise — contact sales" disabled />
    </RadioGroup.Root>
  );
}
```

## Do & don't

**Do**

- Give the group an accessible name via a wrapping `Field` label or `aria-label`.
- Provide a sensible `defaultValue` so the group is never in an empty state.
- Keep option labels parallel in structure and length.
- Order options logically — by magnitude, frequency, or recommended-first.

**Don't**

- Don't use a radio group for more than a handful of options — use Select.
- Don't use it for independent on/off toggles — use Checkbox.
- Don't leave every option unselected on first render unless 'none' is a real value.
- Don't nest interactive controls inside a radio label.

## Accessibility

**Keyboard**

| Keys | Action |
| --- | --- |
| `Tab` | Move focus into the group, landing on the selected item (or the first item). |
| `Arrow Down / Right` | Move to and select the next enabled option. |
| `Arrow Up / Left` | Move to and select the previous enabled option. |
| `Space` | Select the focused option. |

**Notes**

- Built on Radix RadioGroup with roving tabindex — the group is a single Tab stop.
- Exposes `role="radiogroup"`; each item is a `role="radio"` with `aria-checked`.
- Disabled items are skipped during arrow navigation.

## Related

`checkbox`, `select`, `segmented-control`, `field`

---

© Protocore. All rights reserved. Use of the Protocore Design System requires prior written authorization from Protocore (contact@protocore.io). These machine-readable materials must not be ingested into ML-training datasets or derivative design systems. See https://pds.protocore.io/legal/
