RadioGroup
- Component overview: Radio button group for single selection among mutually exclusive options.
- Interaction: The current spec covers the unchecked, checked, disabled, and hover main matrix.
- Implementation note:
RadioGroupretains the mutually exclusive selection structure; the design layer owns the border, fill, and inner circle visuals. - Figma spec
Basic Usage
Pass label to make the entire row (control + text) clickable.
Result
Loading...
Live Editor
render( <RadioGroup defaultValue="option1" aria-label="Favorite fruit"> <RadioGroupItem value="option1" label="Apple" /> <RadioGroupItem value="option2" label="Banana" /> <RadioGroupItem value="option3" label="Cherry" /> </RadioGroup>, )
Disabled State
Result
Loading...
Live Editor
render( <RadioGroup defaultValue="option1" disabled aria-label="Disabled group"> <RadioGroupItem value="option1" label="Selected (disabled)" /> <RadioGroupItem value="option2" label="Unselected (disabled)" /> </RadioGroup>, )
Hover and Main Matrix
Result
Loading...
Live Editor
render( <div style={{ display: 'flex', flexWrap: 'wrap', gap: 24, alignItems: 'center' }}> <div style={{ display: 'flex', flexDirection: 'column', gap: 8, alignItems: 'center' }}> <RadioGroup aria-label="Unchecked default"> <RadioGroupItem value="default-unchecked" aria-label="Unchecked default" /> </RadioGroup> <span style={{ fontSize: 12, color: '#999' }}>Unchecked Default</span> </div> <div style={{ display: 'flex', flexDirection: 'column', gap: 8, alignItems: 'center' }}> <RadioGroup aria-label="Unchecked hover"> <RadioGroupItem value="hover-unchecked" className="border-[var(--Labels-Primary)]" aria-label="Unchecked hover" /> </RadioGroup> <span style={{ fontSize: 12, color: '#999' }}>Unchecked Hover</span> </div> <div style={{ display: 'flex', flexDirection: 'column', gap: 8, alignItems: 'center' }}> <RadioGroup defaultValue="default-checked" aria-label="Checked default"> <RadioGroupItem value="default-checked" aria-label="Checked default" /> </RadioGroup> <span style={{ fontSize: 12, color: '#999' }}>Checked Default</span> </div> <div style={{ display: 'flex', flexDirection: 'column', gap: 8, alignItems: 'center' }}> <RadioGroup defaultValue="disabled-checked" disabled aria-label="Checked disabled"> <RadioGroupItem value="disabled-checked" aria-label="Checked disabled" /> </RadioGroup> <span style={{ fontSize: 12, color: '#999' }}>Checked Disabled</span> </div> </div>, )
Namespace Usage
Result
Loading...
Live Editor
render( <Controls.RadioGroup defaultValue="a" aria-label="Namespace radio"> <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}> <Controls.RadioGroupItem value="a" aria-label="A" /> <span style={{ fontSize: 14 }}>Controls.RadioGroupItem</span> </div> </Controls.RadioGroup>, )
RadioGroup Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Controlled selected value |
defaultValue | string | — | Default selected value (uncontrolled) |
disabled | boolean | false | Disables the entire group |
onValueChange | (value: string) => void | — | Selected value change callback |
orientation | 'horizontal' | 'vertical' | 'vertical' | Layout direction |
className | string | — | Custom style class |
aria-label | string | — | Accessibility label |
RadioGroupItem Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Option value (required) |
label | string | — | Label text; when set, the entire row (control + text) is clickable |
disabled | boolean | false | Disables this item |
labelClassName | string | — | Custom style class for the label row |
className | string | — | Custom style class |
aria-label | string | — | Accessibility label |