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, onValueChangeBase UI RadioGrouparia-invalidbooleandefaultfalsedisabled, readOnly, required, nameBase UIRadioGroupOption label, descriptionReactNodeRadioGroupItem valuestring
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)