Radio Group
One choice from a visible, labeled set of options.
Preview
Use Radio Group when exactly one option can be selected. Keep all options visible and give the group a shared name. Try the labels or arrow keys.
Installation
pnpm dlx shadcn@latest add http://127.0.0.1:3017/r/radio-group.jsonInstalls Radio Group and its Radix primitive, preserving your theme. Field, Label, and Button are separate optional items. The dot is drawn with CSS, so no icon library is required. See the registry guide for local endpoints and updates.
Usage
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { Field, FieldLabel, FieldSet, FieldLegend } from '@/components/ui/field';
<FieldSet>
<FieldLegend id="digest-label">Digest frequency</FieldLegend>
<RadioGroup name="digest" defaultValue="weekly" aria-labelledby="digest-label">
<Field orientation="horizontal" className="gap-2">
<RadioGroupItem id="daily" value="daily" />
<FieldLabel htmlFor="daily">Daily</FieldLabel>
</Field>
<Field orientation="horizontal" className="gap-2">
<RadioGroupItem id="weekly" value="weekly" />
<FieldLabel htmlFor="weekly">Weekly</FieldLabel>
</Field>
</RadioGroup>
</FieldSet>Each item needs a unique value within the group and a labeled ID. Use FieldContent to stack a label and caption-sized description. The group has a 12px option gap; horizontal control-to-label spacing is 8px. Marks are 16px circles with an 8px selected dot. There is no shadow.
Use the group's value and onValueChange for controlled selection; do not control individual items with checked. Selection cannot be cleared by clicking the selected radio again. Offer an explicit “None” option when that is a valid choice.
Composition
Use a fieldset to describe the choice, a RadioGroup to own selection, and a labeled Field for each option:
FieldSet
├── FieldLegend
└── RadioGroup
└── Field (repeat for each option)
├── RadioGroupItem
└── FieldLabelConnect RadioGroup's aria-labelledby to the legend's id. Match each FieldLabel's htmlFor to its RadioGroupItem's id; each item also needs a unique value. When an option has supporting text, wrap FieldLabel and FieldDescription in FieldContent, as in the preview. Put shared selection and form props on RadioGroup.
Interaction states
Each specimen below is an independent one-item group for comparing appearance. Use a complete set of options in actual forms. Hover and focus are pinned; disabled items are skipped during navigation.
The selected border and dot use the focus-indicator color, falling back to primary when that token is absent. This keeps the small selection mark bright in dark mode. Invalid item borders and focus outlines use destructive; labels stay neutral.
Required group and form values
Submit without a selection, choose an option, then submit again. Reset clears the controlled selection. This demo validates locally and saves nothing.
Set required and name on RadioGroup. A selected enabled item contributes the group's name and its value inside a form. An unselected or disabled item contributes no value. For custom validation, mark the group and affected items with aria-invalid, associate an error with the group, and focus its first enabled item when no selection exists.
Keyboard and accessibility
- Tab enters the group at the selected item, or the first enabled item when no value is selected. Tab again leaves the group.
- Arrow keys move focus and select an enabled option. Navigation wraps by default (
loop). Space selects a focused item. - Label the group with
aria-labelledbypointing to its visible legend, and label each item separately. - Use
orientation="horizontal"for a horizontal layout and passdir="rtl"for a right-to-left group when appropriate. disabledon RadioGroup disables all items; an individual item can also be disabled. Keep corresponding labels in the same disabled visual state.- Keep label targets generous for touch and preserve the distinct dot so color is not the only selection cue.
<RadioGroup orientation="horizontal" className="flex flex-wrap gap-4"
aria-label="Alignment" defaultValue="start">
{/* Labeled RadioGroupItem controls */}
</RadioGroup>API
| Part / prop | Default | Purpose |
|---|---|---|
Group value / defaultValue | Unselected | Controlled or initial selected value |
Group onValueChange | — | Receives the selected value string |
Group name, required, disabled | Unset / false | Form name and group constraints |
Group orientation, dir, loop | Radix defaults; loop true | Keyboard navigation configuration |
Item value | Required | Unique value within the group |
Item disabled, aria-invalid | Unset | Availability and invalid state |
| Radix Root / Item props | — | Includes refs and accessibility attributes |
Use Checkbox for multiple independent selections and Switch for an immediate on/off setting.