Components
RadioGroup
A set of radio buttons for selecting one option from a list.
RadioGroup
The RadioGroup component provides a set of mutually exclusive options where only one can be selected at a time. It's ideal for forms where users must choose exactly one option.
RadioGroup items are automatically grouped. Only one item can be selected at a time.
Features
- Mutually exclusive selection
- Keyboard navigation with arrow keys
- Controlled and uncontrolled modes
- Horizontal and vertical layouts
- Disabled state support
- Loop navigation option
- Form integration with name attribute
Usage
import { RadioGroup, RadioGroupItem } from '@loke/design-system/radio-group';
import { Label } from '@loke/design-system/label';
export default function Example() {
return (
<RadioGroup defaultValue="option-one">
<div className="flex items-center space-x-2">
<RadioGroupItem value="option-one" id="option-one" />
<Label htmlFor="option-one">Option One</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="option-two" id="option-two" />
<Label htmlFor="option-two">Option Two</Label>
</div>
</RadioGroup>
);
}Tips:
- Always pair radio items with labels for accessibility.
- Use
defaultValuefor uncontrolled orvaluewithonValueChangefor controlled. - Consider providing a default selection when appropriate.
Props
RadioGroup
Prop
Type
RadioGroupItem
Prop
Type
Examples
Basic radio group
<RadioGroup defaultValue="comfortable">
<div className="flex items-center space-x-2">
<RadioGroupItem value="default" id="r1" />
<Label htmlFor="r1">Default</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="comfortable" id="r2" />
<Label htmlFor="r2">Comfortable</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="compact" id="r3" />
<Label htmlFor="r3">Compact</Label>
</div>
</RadioGroup>With descriptions
Pay with your credit card.
Pay with your PayPal account.
Pay with Apple Pay for faster checkout.
<RadioGroup defaultValue="card">
<div className="flex items-start space-x-2">
<RadioGroupItem value="card" id="card" />
<div className="grid gap-1.5 leading-none">
<Label htmlFor="card">Card</Label>
<p className="text-sm text-muted-foreground">
Pay with your credit card.
</p>
</div>
</div>
<div className="flex items-start space-x-2">
<RadioGroupItem value="paypal" id="paypal" />
<div className="grid gap-1.5 leading-none">
<Label htmlFor="paypal">PayPal</Label>
<p className="text-sm text-muted-foreground">
Pay with your PayPal account.
</p>
</div>
</div>
</RadioGroup>Horizontal layout
<RadioGroup defaultValue="medium" className="flex flex-row gap-4">
<div className="flex items-center space-x-2">
<RadioGroupItem value="small" id="small" />
<Label htmlFor="small">Small</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="medium" id="medium" />
<Label htmlFor="medium">Medium</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="large" id="large" />
<Label htmlFor="large">Large</Label>
</div>
</RadioGroup>With disabled items
<RadioGroup defaultValue="active">
<div className="flex items-center space-x-2">
<RadioGroupItem value="active" id="active" />
<Label htmlFor="active">Active</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="paused" id="paused" />
<Label htmlFor="paused">Paused</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="disabled" id="disabled" disabled />
<Label htmlFor="disabled" className="opacity-50">Disabled</Label>
</div>
</RadioGroup>Accessibility
- Uses proper
role="radiogroup"withrole="radio"for items. - Arrow keys navigate between options.
- Space/Enter selects the focused option.
- Focus is visible and follows focus-visible pattern.
- Required state is communicated via
aria-required. - Disabled items are skipped in navigation.
Best practices
- Always provide labels for each radio item.
- Use clear, concise option labels.
- Consider providing a default selection.
- Group related options with descriptive group labels.
- Use RadioGroup instead of Checkbox for mutually exclusive options.
- Limit options to 7 or fewer for better usability.
- Consider using Select for more than 7 options.