Radio group

Picks one of a few choices.

Checked

  • falsedefault

  • true

States

  • rest

  • hover

  • held

  • focus-visible

  • chosen

  • invalid

  • disabled

Usage

When to use it
Use
Exactly one of two to six choices, each needing a line about its consequence.
Use
A form setting saved with the form, where the person should compare before choosing.
Not for
Two to five views of the same thing, switched at once. Use Segmented control.
Not for
Any number can be on. Use Checkbox.
Not for
More than six choices. Use Select.

Rules

6 rules
Must
Use RadioGroupOption for each choice so its label and description share one target and are read together. Because a loose RadioGroupItem with text beside it has no name, and only the 16px square takes the press.
Must
Name the group with a FieldLegend in a FieldSet, or aria-label. Because arrowing into an unnamed group, a screen reader announces the options with no question.
Must
Give the group a value or defaultValue unless choosing nothing is a real answer. Because a radio cannot be cleared once chosen, so an empty start the person must fix looks like a missing default.
Never
Round the radio or its dot to tell it from a checkbox. Because every corner in Sodium is square; the radio tells itself apart by its square dot and by the group it sits in.
Must
Write label in sentence case and description as a sentence; the label role sets the capitals. Because a screen reader reads the source, and typed capitals are spelled out.
Should
Say why a disabled option is out of reach in its description.

State order

7 states, highest first
1
disabled
2
invalid
3
chosen
4
held
5
focus-visible
6
hover
7
rest

Accessibility

4 checks
role="radiogroup" with one tab stop; each radio is named by its label and described by its consequence.
The open edge is --line-control, 3.5:1 on its body; the chosen one is yellow with an ink square dot, 12.8:1, in light, the yellow tint with a yellow dot, 9.0:1, in dark.
Each radio is 16px with a 28px hit area, and the whole option row is the target.
Focus is the 2px --focus ring on the radio.

Keyboard

3 keys
Arrow keys
Move to the next or previous option and choose it, wrapping at the ends.
Space
Chooses the focused option.
Tab
Enters on the chosen option and leaves the group.

Edge cases

5 edge cases
Long description
Wraps under the label; the radio stays on the first line.
Nothing chosen
Tab lands on the first enabled option.
Disabled option
Arrow keys skip it; its text turns the disabled colour.
Right to left
The radio moves to the start with the label, and the arrows follow the reading order.
Forced colors
The chosen radio takes Highlight with a HighlightText dot and no light.

API

5 props
value, defaultValue, onValueChange
Base UI RadioGroup
aria-invalid
boolean default false
disabled, readOnly, required, name
Base UI
RadioGroupOption label, description
ReactNode
RadioGroupItem value
string

Tokens

19 tokens
--check-off
var(--secondary-bg)
--check-off-hover
#ffffff
--well
#f4f3ee
--line-control
#8a8478
--line
#e2dfd5
--text-1
#161512
--text-2
#55524a
--fail
#b3261e
--check-bg
#ffd400
--check-edge
#d9b400
--check-mark
#161512
--primary-light
rgb(255 255 255 / 0.55)
--primary-light-hover
rgb(255 255 255 / 0.85)
--type-label
400 13px/16px var(--font-mono)
--type-caption
400 13px/18px var(--font-sans)
--focus
#7a5d00
--dur-light
240ms
--dur-glow
320ms
--ease-soft
cubic-bezier(0.22, 0.8, 0.24, 1)

Install

For your coding agent

GitHub

Please star me pookie

198

A new design system every week

Leave your email before you copy the prompt.