Skip to content

Radio

Choose exactly one option from a group. Radio and Radio Group, primary and neutral, with every state.

Version 0.4.1 ·

Radio group

Installation

bunx --bun shadcn@latest add @dga/radio

Installs Field too.

Usage

page.tsx
tsx
import { Field, FieldItem, FieldLabel, FieldLegend, FieldSet } from "@/components/ui/field";
import { Radio, RadioGroup } from "@/components/ui/radio";

export function ContactField() {
  return (
    <Field name="contact">
      <FieldSet render={<RadioGroup defaultValue="sms" />}>
        <FieldLegend>Preferred contact method</FieldLegend>
        <FieldItem>
          <FieldLabel>
            <Radio value="sms" />
            Text message
          </FieldLabel>
        </FieldItem>
        <FieldItem>
          <FieldLabel>
            <Radio value="email" />
            Email
          </FieldLabel>
        </FieldItem>
      </FieldSet>
    </Field>
  );
}

Use Radio when people must choose one of two to five options and seeing them all helps. Start with the most common choice selected only when it is a safe default. For more options use Select; for several choices use Checkbox.

Anatomy

  • RadioGroup: the group; one value at a time.
  • Legend (FieldLegend): the name of the group.
  • Radio: the round control with a dot when chosen.
  • Label and helper text for each option, from FieldItem.

Examples

Radio group

Wrap the group in a Field, then a FieldSet that renders the RadioGroup, so the legend names the group and each FieldItem labels its radio.

Radio group

States

Unselected and selected, in the primary and neutral tones, read-only and disabled.

States

RTL

The radio is on the right (start) of its label. Use ArrowDown and ArrowUp in a vertical group: they work the same in both directions. ArrowRight moves to the next option and ArrowLeft to the previous one in both directions too (Base UI does not mirror them).

LTR (English)
RTL (Arabic)

Accessibility

KeyAction
TabMoves focus into the group (to the chosen radio, or the first) and out of it.
ArrowDown / ArrowRightMoves to the next option and chooses it.
ArrowUp / ArrowLeftMoves to the previous option and chooses it.
SpaceChooses the focused radio.
  • The radiogroup role on the group and radio with aria-checked on each option. A FieldSet and its legend name the group.
  • Only one radio is in the Tab order, so the group is one stop.
  • The unchecked ring and the chosen ring and dot are 3:1 or better on every surface (WCAG 1.4.11).
  • Focus is a 2px outline 2px outside the circle. Disabled and read-only radios keep their label legible.

API Reference

Radio

One round option of a RadioGroup. Give every Radio a `value`.

Radio props
PropTypeDefault
"primary" | "neutral"

`primary` (green) or `neutral` (black in light mode).

"primary"
string

The unique identifying value of the radio in a group.

No default
boolean

Whether the component should ignore user interaction.

No default

Also accepts every prop of the Base UI Radio (opens in a new tab).

RadioGroup

A group of radios where only one can be chosen. Arrow keys move and choose, Tab enters and leaves the group. Wrap it in a Field with a FieldSet to give it a legend.

RadioGroup props
PropTypeDefault
string

The controlled value of the radio item that should be currently selected. To render an uncontrolled radio group, use the `defaultValue` prop instead.

No default
string

The uncontrolled value of the radio button that should be initially selected. To render a controlled radio group, use the `value` prop instead.

No default
boolean

Whether the component should ignore user interaction.

No default
string

Identifies the field when a form is submitted.

No default
(value: string, details) => void

Callback fired when the value changes.

No default
boolean

Whether the user should be unable to select a different radio button in the group.

No default
boolean

Whether the user must choose a value before submitting a form.

No default

Also accepts every prop of the Base UI Radio (opens in a new tab).

Deviations from DGA

  • Same dark-mode hover and press fill as Checkbox: the dot stays green-600.
  • Read-only has a 3:1 ring (Figma: 1.5:1).

None. This component matches the DGA Figma file.

Contrast

72 pairs checked · all pass WCAG 2.1 AAShow 14 states
Variant / stateLightDark
unchecked border4.57:1 3:13.80:1 3:1
unchecked border, hovered7.04:1 3:112.04:1 3:1
border, error4.62:1 3:14.65:1 3:1
border, read-only4.57:1 3:13.80:1 3:1
focus ring17.31:1 3:117.49:1 3:1
primary / checked (dot and border)4.54:1 3:13.68:1 3:1
primary / hovered (dot and border)8.18:1 3:13.68:1 3:1
primary / pressed (dot and border)10.34:1 3:13.68:1 3:1
neutral / checked (dot and border)17.93:1 3:19.38:1 3:1
neutral / hovered (dot and border)7.04:1 3:112.04:1 3:1
neutral / pressed (dot and border)4.57:1 3:16.32:1 3:1
read-only mark4.77:1 3:19.38:1 3:1
label14.53:1 AAA15.87:1 AAA
helper text4.77:1 AA6.32:1 AA

Text needs 4.5:1, icons and focus rings 3:1. Disabled states are exempt. Full contrast report