Radio Group
Forms
Selection
Single selection radio button groups for mutually exclusive choices, built on Radix UI primitives. Supports controlled and uncontrolled modes.
Preview
Basic radio group
Controlled State
Manage radio group state in your component
Selected plan: pro
With Descriptions
Add context with descriptions
Receive notifications via email
Get text messages for important updates
Receive push notifications on your devices
Card Style
Radio groups with card layouts
Perfect for individuals - $9/month
For growing teams - $29/month
For large organizations - Custom pricing
Disabled State
Disabled group and individual items
Disabled Group
Disabled Individual Items
Props
RadioGroup component API reference
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Controlled value |
defaultValue | string | — | Default value (uncontrolled) |
onValueChange | (value: string) => void | — | Callback when value changes |
disabled | boolean | false | Disable the entire group |
required | boolean | false | Mark as required in forms |
className | string | — | Additional CSS classes |
RadioGroupItem Props
| Prop | Type | Default | Description |
|---|---|---|---|
value* | string | — | Unique value for this option |
id | string | — | ID for label association |
disabled | boolean | false | Disable this item |
className | string | — | Additional CSS classes |
Usage
Import and implementation example
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'
import { Label } from '@/components/ui/label'
export default function Example() {
const [value, setValue] = useState('option1')
return (
<>
{/* Basic radio group */}
<RadioGroup defaultValue="option1">
<div className="flex items-center space-x-2">
<RadioGroupItem value="option1" id="option1" />
<Label htmlFor="option1">Option 1</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="option2" id="option2" />
<Label htmlFor="option2">Option 2</Label>
</div>
</RadioGroup>
{/* Controlled */}
<RadioGroup value={value} onValueChange={setValue}>
<div className="flex items-center space-x-2">
<RadioGroupItem value="yes" id="yes" />
<Label htmlFor="yes">Yes</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="no" id="no" />
<Label htmlFor="no">No</Label>
</div>
</RadioGroup>
{/* With descriptions */}
<RadioGroup defaultValue="email">
<div className="flex items-start space-x-3">
<RadioGroupItem value="email" id="email" className="mt-1" />
<div>
<Label htmlFor="email">Email</Label>
<p className="text-sm text-slate-500">Receive via email</p>
</div>
</div>
</RadioGroup>
</>
)
}Features
Built-in functionality
- Single selection: Only one option can be selected
- Keyboard navigation: Arrow keys to move between options
- Controlled & uncontrolled: Flexible state management
- Radix UI primitives: Built on accessible components
- Smooth transitions: 200ms color transitions
- Circular design: Full border radius radio buttons
- Card layouts: Support for card-style options
- Dark mode: Full dark mode support
Accessibility
Accessibility considerations
ARIA Attributes
Uses native radio semantics via Radixrole="radiogroup" on containeraria-checked indicates selection stateKeyboard Navigation
| Key | Action |
|---|---|
| Tab | Focus the radio group |
| Arrow Up/Down | Navigate between options |
| Arrow Left/Right | Navigate between options |
| Space | Select focused option |
Notes
- Always pair RadioGroupItem with Label
- Disabled items are visually indicated
- Focus ring visible on keyboard navigation
- Selected state shown with filled circle