Skip to content

Radio group

Picks exactly one option from a short list that stays visible.

Library
What’s this?
Notify me about

Installation

pnpm dlx shadcn@latest add @wisty/radio-group

The CLI installs the Radix or Base UI file to match your project.

If your project doesn't have Wisty UI's theme yet, add it once with npx shadcn@latest add @wisty/cosmos. Until then, components keep shadcn's default look. Installation has the details.

When to use

Use it

  • People pick exactly one option from a short list, like how often to get notifications.
  • Every option should stay visible, so people can compare them before they choose.

Don't use it

  • People can pick any number of options. Use Checkbox.
  • The choice turns one thing on or off. Use Checkbox, or Switch when it applies at once.
  • More than about seven options, or space is tight. Use Select, or Combobox for a searchable list. For a row of numbers, like 0 to 10, use Linear scale.
  • The options read as a segmented control in a toolbar, like Day, Week and Month. Use Toggle group.

Usage

Give each RadioGroupItem a value and an id, with a Label after it that points at the id. Name the group.

import { Label } from "@/components/ui/label"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
<RadioGroup defaultValue="phone" aria-label="Preferred contact method">
  <div className="flex items-center gap-2">
    <RadioGroupItem value="phone" id="contact-phone" />
    <Label htmlFor="contact-phone">Phone</Label>
  </div>
  <div className="flex items-center gap-2">
    <RadioGroupItem value="email" id="contact-email" />
    <Label htmlFor="contact-email">Email</Label>
  </div>
</RadioGroup>

In a form, name the group with a visible legend instead: a FieldSet with a FieldLegend variant="label", aria-labelledby on the group pointing at the legend, and each option in a Field orientation="horizontal", as the Email notifications example shows. In Base UI projects, onValueChange also gets event details as a second argument.

Examples

States

Enabled, disabled and invalid groups of two, each with one checked, set with `disabled` and `aria-invalid` on `RadioGroupItem`.

API reference

SLDS mapping

RadioGroup is the control of SLDS's radio group fieldset. RadioGroupItem is slds-radio_faux, the circle of slds-radio, and a disabled item is its :disabled state. Options stack with no gap, as SLDS's block slds-radio lines do. A Label beside an item is regular weight, as SLDS's radio labels are.

Known gaps:

  • SLDS names the group with a visible legend. Wrap the group in a FieldSet with a FieldLegend, or name it with aria-label.

Keyboard interactions

Keys Action
Tab Enters the group as one stop, at the checked option or the first one.
Arrow Down, Arrow Right Moves to the next option and checks it.
Arrow Up, Arrow Left Moves to the previous option and checks it.
Space Checks the focused option.

Accessibility

  • Name the group with a FieldLegend or aria-label, and every item with a visible Label.
  • Pair aria-invalid with an error message the items point to through aria-describedby.
  • A disabled item turns gray but isn't dimmed. Say why it's unavailable in nearby text if that matters.

Responsive behavior

  • The circle keeps its size in a flex row, and its hit area reaches past it on every side. Long labels wrap next to it; align the circle to the first line with items-start on the row.
  • The group fills its container's width and stacks its options. For options in a row, set className="flex gap-4" on the group.

Rules

  • Give each item a unique value.
  • Use aria-invalid for errors. Don't add border or color classes.