What is Radio group?
Radio group: A radio group is a set of options where selecting one deselects the rest, used when a form needs exactly one choice from a short, visible list.
A radio group presents every option at once and allows exactly one to be selected. Picking a different option moves the selection; there is no way to unselect everything once a choice is made. It is the right control for a short list of mutually exclusive answers: a plan, a shipping speed, a visibility setting, a payment method. The name comes from the station buttons on old car radios, where pressing one popped the others out.
When to use it
- Two to about seven options that all deserve to be visible, so people can compare them without opening anything.
- Options with descriptions, such as plans with prices or shipping methods with dates. A select cannot show that detail.
- More than seven options usually belong in a select or combobox, which hide the list until needed.
- Instant switching between views is a segmented control, which is a radio group in a compact skin.
Should one be preselected
Preselect an option when there is a safe, common default, such as standard shipping, and the form must have a value. Leave the group empty when the choice is a real decision the user should make, such as a paid plan, and validate on submit. Never preselect the option that costs the most or shares the most data.
Accessibility
Native radio inputs with the same name inside a fieldset with a legend are the most robust option and need no ARIA. A custom group uses role="radiogroup" on the container, named by aria-labelledby, and role="radio" with aria-checked on each option. Keyboard behavior is the same in both: Tab reaches the group once, landing on the checked option (or the first when none is checked), and Arrow keys move the selection among the options with a roving tabindex. Each option needs a visible label that can be clicked, and an error on the group is shown once, below the legend, with aria-describedby on the group pointing at it.
How to build one in React
MiniDev's RadioGroup and RadioGroupItem wrap the Base UI primitives. Pair each item with a Label so the text is clickable:
import { Label } from "@/components/ui/label"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
export function ShippingMethod() {
return (
<fieldset>
<legend className="text-sm font-medium">Shipping</legend>
<RadioGroup name="shipping" defaultValue="standard" className="mt-3">
<div className="flex items-center gap-2">
<RadioGroupItem value="standard" id="ship-standard" />
<Label htmlFor="ship-standard">Standard, 3 to 5 days</Label>
</div>
<div className="flex items-center gap-2">
<RadioGroupItem value="express" id="ship-express" />
<Label htmlFor="ship-express">Express, next day</Label>
</div>
</RadioGroup>
</fieldset>
)
}
Pass value and onValueChange instead of defaultValue when another part of the form depends on the choice, which makes it a controlled component. For options with a price, an icon and a description, ChoiceCard renders each option as a selectable card. Browse the forms category for the rest of the input set.