RadioGroup
A group of radio buttons where only one option can be selected at a time. Built on the @base-ui/react RadioGroup primitive with circular indicators, expanded click targets, and managed selection state.
Anatomy
A <RadioGroup> container with a grid layout holds multiple <RadioGroupItem> elements. Each item renders as a circle with a centered indicator dot when selected. The group manages single-selection state automatically.
Examples
Vertical (default)
With disabled option
Design Guidelines
Do
- Use for mutually exclusive options. When the user must pick exactly one option from a set.
- Always pre-select a default. Radio groups should always have one option selected.
- Keep options to 2-7 items. Longer lists should use a Select or Combobox instead.
- Stack vertically. Vertical layout is easier to scan than horizontal.
Don't
- Don't use for multiple selections. Use Checkbox for selecting multiple items.
- Don't use for binary on/off. Use Switch for settings that take immediate effect.
- Don't show without labels. Each radio needs descriptive text for accessibility.
- Don't start without a selection. An empty radio group creates confusion.
Developer Reference
Accessibility
- Uses Base UI RadioGroup — manages
aria-checkedand roving tabindex. - Arrow keys navigate between items; Space/Enter selects.
- The indicator dot (size-2, white) appears centered on checked state.
- After pseudo-element expands click target for WCAG touch target compliance.
aria-invalidtriggers destructive ring on all items.
Usage
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
import { Label } from "@/components/ui/label"
<RadioGroup defaultValue="comfortable">
<div className="flex items-center gap-2">
<RadioGroupItem value="default" id="r1" />
<Label htmlFor="r1">Default</Label>
</div>
<div className="flex items-center gap-2">
<RadioGroupItem value="comfortable" id="r2" />
<Label htmlFor="r2">Comfortable</Label>
</div>
<div className="flex items-center gap-2">
<RadioGroupItem value="compact" id="r3" />
<Label htmlFor="r3">Compact</Label>
</div>
</RadioGroup>
// Controlled
const [value, setValue] = useState("comfortable")
<RadioGroup value={value} onValueChange={setValue}>
...
</RadioGroup>