RadioGroup
A controlled single-choice field that stacks labelled options as divider-separated selection rows.
Implementation previewEvery example. In one place.
Explore every named example, including states, compositions, and theme variants.
Example source
packages/design-system/src/components/forms/RadioGroup/RadioGroup.stories.tsxExport PlaygroundImplementation preview Local Storybook build 0.2.0-preview.1. Source specification status does not approve this runtime.
Stories + source JSON ↗Local specification source status: preview. Implementation preview pending sign-off.
A controlled single-choice field that stacks labelled options as divider-separated selection rows.
Implementation API 1 entry point · source-derived preview
Read the actual callable API and preserve its composition constraints. Each union branch is a complete alternative; props marked forbidden cannot be supplied.
import { RadioGroup } from '@cloakedinc/design-system';RadioGroupRadioGroupProps
packages/design-system/src/components/forms/RadioGroup/RadioGroup.tsx:45
| Prop | Type | Presence | Notes |
|---|---|---|---|
value | string | Required | Value of the selected option; a value matching no option leaves the group unselected. |
options | RadioOption[] | Required | Options in display order. Dividers sit between rows, not after the last one. |
onChange | ((value: string) => void) | undefined | Optional | Called with the next value. Pressing the already-selected option does not call it. |
disabled | boolean | undefined | Optional | Prevents interaction with every option when true. |
required | boolean | undefined | Optional | Marks the group as required for assistive technology. |
ariaLabel | string | undefined | Optional | Accessible name when no visible label is associated with the group. |
haptic | HapticFeedback | undefined | Optional | Haptic feedback for value changes. Defaults to `true` (`selection`).Source default: true |
className | string | undefined | Optional | |
testId | string | undefined | Optional | Test id for the group; each row derives `${testId}-${option.value}`. |
id | string | undefined | Optional | DOM id the control renders, which the Field's label points at. |
invalid | boolean | undefined | Optional | Paints the invalid treatment and announces the control as invalid. A Field supplies this from its own `error`; set it directly only for a control with no Field around it. |
ariaDescribedBy | string | undefined | Optional | Ids of the helper or error copy describing the control, supplied by a parent Field. |
ariaLabelledBy | string | undefined | Optional | Id of the visible label naming the control, supplied by a parent Field. |
Only explicit destructured parameter initializers are extracted. Other runtime defaults remain in implementation source.
Overview
Manages a set of radios as one mutually-exclusive field — one value, labelled options, and
group semantics (role="radiogroup"). This is the control you reach for, not the bare Radio.
Options render as divider-separated List.Item.Selection rows with the control at the trailing
edge, so a group reads as part of the surface it sits on. Rows are 80px with a description and
64px without.
When to use
Use RadioGroup for a single choice where every option should stay visible so seeing them all
aids the decision — best at 2–5 options. Pair it with Field for the label; only pass the
standalone aria props when used outside Field. Choosing between the neighbours:
- The list is long or space is tight? Use
Select— don't stack a dozen radios. - You need a compact inline 2–4 option switch (view/filter) rather than a labelled form field?
Use
SegmentedControl. - The user may pick more than one option? Use
Checkbox.
Component specification
$schema
../../../specs/component-spec.schema.jsonParts
- Id
- group
- Label
- Group
- Description
- Owns the accessible radio-group name, validation, and required state.
- Id
- option
- Label
- Option row
- Description
- Pressable full-width row carrying one option's copy and its selection control.
- Id
- label
- Label
- Option label
- Description
- Names the option and provides the row's accessible name.
- Id
- description
- Label
- Option description
- Description
- Optional supporting copy beneath the option label.
- Id
- indicator
- Label
- Selection indicator
- Description
- Trailing control showing unselected or selected-dot state without duplicating semantics.
- Id
- divider
- Label
- Row divider
- Description
- Hairline separating adjacent options; absent after the last option.
Allowed Design Choices
- Variants
- Row
- Label
- Row
- Description
- Each option is one full-width selection row on the list surface.
- Sizes
Variants
- Id
- row
- Label
- Row
- Description
- Divider-separated single-choice rows with a trailing selection control.
- Platforms
- ios
- android
- web
Sizes
None specifiedMeasurements
- Id
- row-min-height
- Label
- Option row height
- Kind
- at-least
- Token
- --cds-size-80
- Value
- 80
- Unit
- px
- Applies To
- option
- description
- Id
- compact-row-min-height
- Label
- Option row height without description
- Kind
- at-least
- Token
- --cds-size-64
- Value
- 64
- Unit
- px
- Applies To
- option
- Id
- row-inset
- Label
- Option row inset
- Kind
- exact
- Token
- --cds-space-20
- Value
- 20
- Unit
- px
- Applies To
- option
- Id
- copy-to-control-gap
- Label
- Copy-to-control gap
- Kind
- exact
- Token
- --cds-space-24
- Value
- 24
- Unit
- px
- Applies To
- option
- indicator
- Id
- indicator-diameter
- Label
- Selection indicator diameter
- Kind
- exact
- Token
- --cds-size-32
- Value
- 32
- Unit
- px
- Applies To
- indicator
Layout
- Alignment
- Copy fills the leading column and the selection control pins to the trailing edge, both vertically centered.
- Flow
- Options stack full-width with a hairline between adjacent rows and none after the last.
- Notes
- Keep option rows flush to the surface; do not wrap them in per-option cards or radii.
- Use Select when the choice list is too long to keep visible.
Typography And Color
- Typography
- Label
- Option label
- Description
- Use body text for the option name.
- Token
- --cds-type-body-size
- Label
- Option description
- Description
- Use body-small secondary text for supporting copy.
- Token
- --cds-type-body-small-size
- Colors
- Label
- Row surface
- Description
- Use the list row surface for every option, selected or not.
- Token
- --cds-bg-surface
- Label
- Row divider
- Description
- Use the shared divider hairline between adjacent options.
- Token
- --cds-divider
- Label
- Selected indicator
- Description
- Use the theme-aware bold fill for the chosen option's control.
- Token
- --cds-bg-bold
- Label
- Option copy
- Description
- Use primary and secondary text emphasis by copy hierarchy.
- Token
- --cds-text-primary
States
- Id
- unselected
- Label
- Unselected
- Description
- Shows the neutral empty indicator with no row treatment change.
- Id
- selected
- Label
- Selected
- Description
- Fills the trailing indicator and shows the dot; the row itself is unchanged.
- Id
- option-disabled
- Label
- Option disabled
- Description
- Dims one row and blocks its press while leaving the rest selectable.
- Id
- group-disabled
- Label
- Group disabled
- Description
- Dims and blocks every option in the group.
- Id
- invalid
- Label
- Invalid
- Description
- Exposes group-level invalid and described-by relationships supplied by Field.
Behavior
- Label
- Single selection
- Description
- Emit a new option value only when it differs from the controlled value.
- Label
- Disabled options
- Description
- Never emit changes for a disabled option or disabled group.
- Label
- Row press target
- Description
- Treat the whole row as the press target, not just the selection control.
Accessibility
- Label
- Group name
- Description
- Associate a visible Field label or provide an accessible group name.
- Label
- Option semantics
- Description
- Expose each option as a radio whose accessible name is its label and whose description is announced when present.
- Label
- Validation
- Description
- Expose required, invalid, and described-by state on the group without duplicating it on decorative indicators.
Content Adaptation
- Label
- Option count
- Description
- Keep groups to a short visible set; use Select for long lists.
- Label
- Descriptions
- Description
- Use concise descriptions to clarify consequences, not repeat option labels; omitting them tightens the row.
Motion Haptics
- Motion
- Label
- Selection state
- Description
- Change only the indicator fill and dot; option content must not move.
- Haptics
- Label
- Selection feedback
- Description
- Request the selection haptic after a new enabled value is chosen, and none when the current value is re-pressed.
Platform Differences
- Platforms
- web
- Description
- Web renders each option as a button with radio semantics rather than a native radio input; native platforms map the same option content to their radio accessibility controls.
- Rationale
- The row is the press target on every platform, and the shared row treatment matters more here than native input chrome the design hides anyway.