Radio

One selected value from a related set — mutually exclusive. Group radios by a shared name; exactly one is chosen. For independent on/off choices use a checkbox instead.

States

Real DOM drivers set every state; demo classes force hover and focus here. One size — size.icon.md. Unselected hover previews the primary dot on the unfilled ring; selection reverses it onto the primary fill, which remains filled as it steps to its hover color.

ExampleStateDriverRolesUsage
Rest, unselectedborder.strongsurface.pageAn option in a set, not chosen
Hover:hoversurface.pageaction.primary.bgThe primary dot previews selection on the unfilled ring
Selected:checkedaction.primary.bg.textThe dot marks the one chosen value
Selected + hover:checked:hoveraction.primary.hover.textThe fill responds without disguising the selected value
Focus:focus-visiblefocus.ringKeyboard focus — the shared ring
Invalid[aria-invalid]status.error.borderFlag the group, then reference the message
Disabled:disabledaction.disabled.bgborder.defaultVisible but not selectable
Radio · Group
Plan
Choose one available plan to continue.
The disabled option remains visible for context.

Radios share a name and one native fieldset legend. The group-level invalid state colors the boundary and legend, owns its wrapping error, and clears all three when an enabled option is chosen.

Usage notes

Radios are one-of-many — the set shares a name and a single answer.

VerdictRule
DoGroup radios with a shared name in fieldset.ds-choice-group under a real legend; pre-select a sensible default when one exists.
DoGive every option a label — visible via its row, or aria-label when the context is the label.
DoValidate the group, not the option: set aria-invalid and reference the message via aria-describedby.
Don’tStretch a radio set past what fits visibly — longer lists collapse into a Select.
Don’tUse radios for independent on/off choices — that is Checkbox — or a horizontal one-of-few — that is SegmentedControl.