Component
Stablev1.0.0Form

Radio Group

Radio buttons allow users to select exactly one option from a set of mutually exclusive choices. Unlike Checkbox (multi-select) or Toggle (binary instant action), Radio Group is used when only one value can be selected and the options should all be visible at once.

When to Use

Use Radio when
  • User must choose exactly one option from 2–6 visible choices
  • All options need to be visible simultaneously for comparison
  • Selection changes on form submit (not instant)
  • Options are mutually exclusive
Don't use Radio when
  • More than 6 options — use Select instead
  • Multiple selections allowed — use Checkbox
  • Instant toggle needed — use Toggle/Switch

Anatomy

1
Fieldset wrapper
Semantic <fieldset> + <legend> groups all options. Legend serves as the group label for screen readers.
2
Radio input
Native input[type=radio]. accent-color:#6366F1. width/height:16px. Same name attribute on all inputs in the group.
3
Option label
13px fw-500. Wrapped in <label> for full-row click area.
4
Option sub-label (optional)
11px #94A3B8. Describes the option in more detail.

Variants

Vertical (default)
With sub-labels

States

Unselected
Empty circle
Selected
Filled with accent-color:#6366F1
Disabled
opacity:.5, cursor:not-allowed

Properties

PropertyTypeRequiredDefaultDescription
namestringrequiredAll radio inputs in a group share the same name. This makes them mutually exclusive.
valuestringrequiredEach option has a unique value submitted on form select.
defaultValuestringoptionalundefinedPre-selected option value.
disabledbooleanoptionalfalsePer-option or group-level disable.
legendstringrequiredGroup label in <legend> element. Can be visually hidden but must exist.

Behavior

TriggerBehavior
Click optionSelects that option. Deselects all others in same name group. Fires onChange with new value.
Arrow keysWhen focused, arrow keys cycle through options in the group. Native browser behavior.
TabMoves focus into/out of the radio group. Inside the group, arrow keys navigate.

Accessibility

RequirementImplementation
Group semanticsWrap all options in <fieldset> with <legend>. Legend can be visually hidden but must exist in DOM.
Native inputAlways use input[type=radio]. Never divs or spans that simulate radio buttons.
KeyboardTab enters group. Arrow keys cycle options. Space selects focused option.
Label associationWrap each input+label in <label> or use for/id pairing.

Composition

Allowed
Inside form-group with form-label as legend
2–6 options maximum
Inside modal forms
Forbidden
More than 6 options — use Select
Without fieldset + legend wrapper
Mixed with Checkbox in same group

Best Practices

Do
Sub-labels help users understand the difference between options.
Don't
More than 6 options — use Select instead.

Content Rules

Monthly / Annual / Lifetime
Short, noun-based, parallel structure.
I want to be billed monthly
First person, sentence-length. Options should be nouns.

AI Implementation Guide

For AI coding assistants: Always use native input[type=radio] elements. All options in a group MUST share the same name attribute — this is what makes them mutually exclusive. Wrap the entire group in <fieldset> + <legend>. Each option is a <label> wrapping input + text. accent-color:#6366F1 for brand color. Max 6 options — beyond that, switch to Select component.

Design Decisions

Why limit to 6 options maximum?
Radio groups work because users can scan all options at once for comparison. Beyond 6 options, scanning becomes tedious and a Select dropdown (which hides options until needed) is more efficient. The threshold of 6 is a widely-accepted UX heuristic.

Changelog

v1.0.0July 2026Added
  • Initial release — vertical layout, with/without sub-labels, disabled state
  • Native input[type=radio] with accent-color:#6366F1
  • fieldset + legend for accessibility