The RadioGroup component allows users to select a single option from a set of mutually exclusive choices.
Installation
npx shadcn@latest add @eo-n/radio-group
Install dependencies
Install the required packages:npm install @base-ui/react
Copy component code
Copy and paste the radio-group component code into your project at components/ui/radio-group.tsx.
Update imports
Update the import paths to match your project setup.
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Label } from "@/components/ui/label";
export default function Example() {
return (
<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>
);
}
Examples
Default
<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>
Controlled
import { useState } from "react";
function ControlledRadioGroup() {
const [value, setValue] = useState("option1");
return (
<div className="space-y-4">
<RadioGroup value={value} onValueChange={setValue}>
<div className="flex items-center space-x-2">
<RadioGroupItem value="option1" id="opt1" />
<Label htmlFor="opt1">Option 1</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="option2" id="opt2" />
<Label htmlFor="opt2">Option 2</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="option3" id="opt3" />
<Label htmlFor="opt3">Option 3</Label>
</div>
</RadioGroup>
<p className="text-sm">Selected: {value}</p>
</div>
);
}
Disabled Item
<RadioGroup defaultValue="option1">
<div className="flex items-center space-x-2">
<RadioGroupItem value="option1" id="d1" />
<Label htmlFor="d1">Option 1</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="option2" id="d2" disabled />
<Label htmlFor="d2">Option 2 (Disabled)</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="option3" id="d3" />
<Label htmlFor="d3">Option 3</Label>
</div>
</RadioGroup>
Disabled Group
<RadioGroup defaultValue="option1" disabled>
<div className="flex items-center space-x-2">
<RadioGroupItem value="option1" id="g1" />
<Label htmlFor="g1">Option 1</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="option2" id="g2" />
<Label htmlFor="g2">Option 2</Label>
</div>
</RadioGroup>
In a Form
function FormExample() {
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
const formData = new FormData(e.target as HTMLFormElement);
console.log(formData.get('notification'));
};
return (
<form onSubmit={handleSubmit}>
<RadioGroup defaultValue="all" name="notification">
<div className="flex items-center space-x-2">
<RadioGroupItem value="all" id="all" />
<Label htmlFor="all">All notifications</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="mentions" id="mentions" />
<Label htmlFor="mentions">Mentions only</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="none" id="none" />
<Label htmlFor="none">None</Label>
</div>
</RadioGroup>
<button type="submit">Submit</button>
</form>
);
}
API Reference
RadioGroup
Extends all props from @base-ui/react RadioGroup component.
The controlled selected value.
The default selected value when uncontrolled.
Callback fired when the selected value changes.
Whether all radio items in the group are disabled.
The name attribute for form submission.
Whether the radio group is required in a form.
Additional CSS classes to apply.
RadioGroupItem
Extends all props from @base-ui/react Radio.Root component.
The value of the radio item.
Whether this specific radio item is disabled.
The id for associating with a label.
Additional CSS classes to apply.
TypeScript
import { RadioGroup as RadioGroupPrimitive, Radio as RadioPrimitive } from "@base-ui/react";
type RadioGroupProps = React.ComponentProps<typeof RadioGroupPrimitive>;
type RadioGroupItemProps = React.ComponentProps<typeof RadioPrimitive.Root>;
Accessibility
- Fully keyboard accessible (Arrow keys to navigate, Space to select)
- Proper ARIA attributes
- Focus visible indicator
- Works with form labels
- Roving tab index for keyboard navigation
Related