Radio Group
StableLets people choose exactly one option from a small set, with every option visible at once.
Installation
$ pnpm dlx shadcn@latest add https://www.prfct.dev/r/radio-group.jsonUsage
import { Field, FieldLabel } from "@/components/ui/field"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"<RadioGroup defaultValue="daily">
<Field orientation="horizontal">
<RadioGroupItem value="daily" id="daily" />
<FieldLabel htmlFor="daily">Daily summary</FieldLabel>
</Field>
<Field orientation="horizontal">
<RadioGroupItem value="weekly" id="weekly" />
<FieldLabel htmlFor="weekly">Weekly summary</FieldLabel>
</Field>
</RadioGroup>The selected radio fills with the brand color and its dot springs into place.
Examples
With descriptions
When options need explaining, pair each label with a description in FieldContent. People compare options by reading the descriptions side by side — one of the main reasons to prefer radios over a select.
Only invited members can see and join this project.
Anyone in your organization can find and view it.
Anyone on the internet can view it. Only members can edit.
Choice cards
Wrap each field in a FieldLabel to make the whole card clickable. Cards suit decisions with a price, a limit or a feature list — plans, shipping speeds, deployment targets.
Horizontal
Lay short options out in a row when they read as a scale or a set of peers. Use FieldSet and FieldLegend to name the group; a row of radios without a question is ambiguous.
States
Disable a group when the choice doesn't apply yet, and explain why nearby. For validation, set required, mark the items aria-invalid and show a FieldError under the group.
Guidelines
When to use
- To choose exactly one option from two to about seven.
- When people benefit from seeing and comparing every option at once.
When not to use
- To select several options — use Checkboxes.
- For a single on/off setting — use a Switch or a checkbox.
- For more than about seven options, or when space is tight — use a Select.
- For compact segmented choices in toolbars (view modes, alignment) — use a Toggle Group.
Defaults
Preselect the most common or safest option — a radio group can't be returned to "nothing selected" once people choose, so an empty group only makes sense when the choice must be deliberate. In that case, validate it.
Standard — free
Express — $12
Subscribe to the newsletter
Order
Order options logically — by magnitude, time, or likelihood — and keep the list vertical unless the options are very short. Align radios on the left so the labels form a clean, scannable column.
Accessibility
RadioGroup renders role="radiogroup" and each item role="radio" with aria-checked. The group behaves as a single tab stop with roving focus, following the ARIA radio group pattern.
| Key | Behavior |
|---|---|
Tab | Moves focus into the group — to the checked radio, or the first one if none is checked — and out of it. |
↓→ | Moves to and checks the next radio, wrapping at the end. |
↑← | Moves to and checks the previous radio, wrapping at the start. |
Space | Checks the focused radio if it isn't checked yet. |
- Name the group. Use
FieldSet+FieldLegend, oraria-label/aria-labelledbyonRadioGroup, so the question is announced along with each option. - Label every radio with a
FieldLabelthat points at itsid. Base UI links the label to the visible radio, so clicking the text selects it. - Boundaries and targets. Radios use the
inputtoken for their border (3:1, WCAG 1.4.11) and a 24×24px hit area around the 16px circle.
API reference
RadioGroup
Renders a <div role="radiogroup">. Accepts every prop of Base UI's RadioGroup.
RadioGroupItem
Renders a <span role="radio"> with a hidden input. Accepts every prop of Base UI's Radio.Root.