Home

Radio group

A short list of options where exactly one is picked, each a round button beside its words.

ui.radio-groupcomponents/ui/radio-group.tsx

Use case

For the AI

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

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.