Radio group
A short list of options where exactly one is picked, each a round button beside its words.
ui.radio-group
components/ui/radio-group.tsxUse case
Use it for one answer among a few that a person should compare before choosing: billing monthly or yearly, delivery or pickup on an order, how a quote is paid (a deposit, in full, in instalments). Every option stays visible with its detail (a price, a delay) under its name, which a select would hide behind a click.
Use it when
- Exactly one answer among a few options
- Each option needs its detail visible to compare
- A choice inside a form saved later
Use something else when
- Many options, or a tight form row (a province, a status): Select
- Switching a view or a period at once, above a chart or a list: Segmented control
- Several answers allowed: Checkbox group
- A single yes or no: Checkbox
Examples
Code
Import
import { Label } from "@/components/ui/label"
import { Radio, RadioGroup } from "@/components/ui/radio-group"Usage
const PLANS = [
{ value: "monthly", name: "Monthly", hint: "$49 a month" },
{ value: "yearly", name: "Yearly", hint: "$490 a year, two months free" },
]
<RadioGroup name="billing" defaultValue="monthly" aria-label="Billing" className="grid gap-3">
{PLANS.map((p) => (
<Label key={p.value} className="flex cursor-pointer items-start gap-3 font-normal">
<Radio value={p.value} className="mt-0.5" />
<span className="grid gap-0.5">
<span className="text-[14px] font-medium text-foreground">{p.name}</span>
<span className="text-[12.5px] text-ink-4">{p.hint}</span>
</span>
</Label>
))}
</RadioGroup>Rules
- Every `Radio` has a `value`; give the group a `defaultValue` (or `value` with `onValueChange`) so the starting answer is clear.
- Name the group with `aria-label` (or `aria-labelledby`), and wrap each radio with its words in a `Label`.
- Option names are sentence case; a detail sits under the name in `text-ink-4`.
- Inside a form, pass `name` on the group so the picked value is submitted.