Radio / RadioGroup
Mutually-exclusive choice. Radio must live inside a RadioGroup, which manages the single-selection state.
Component behavior
RadioGroup displays mutually exclusive options. Each Radio can include a label and description.
- A small set of mutually exclusive options that remain visible.
- Options with explanatory descriptions.
- Choices that affect other form fields.
Select: the option set is large or does not require descriptions.
SegmentedControl: a toolbar requires compact view or range selection.
CheckboxGroup: multiple options can be selected.
Switch: the control represents one on/off state.
Props
RadioGroup stores a string selection in context. A Radio is selected when its value matches the group value. Use value and onChange for controlled state or defaultValue for internal state. The uncontrolled default is an empty string. Set disabled on individual radios; there is no group-level disabled prop.
RadioGroup
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Controlled selection. Matched against each Radio's value by equality. |
defaultValue | string | — | Initial uncontrolled selection. Defaults to an empty string with no selected option. |
onChange | (value: string) => void | — | Fires with the newly selected value. Re-clicking the selected radio does not fire it. |
inline | boolean | — | Lay radios out in a row instead of stacked. Descriptions still render under their labels, so inline suits short labels. |
children | ReactNode | — | Radio children. Context permits nested wrappers between radios and the group. |
className | string | — | Additional CSS class on the role="radiogroup" container. |
Radio
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | The value this radio represents, and what onChange reports when it is picked. |
children | ReactNode | — | Label text. Selecting the label toggles the visually hidden input. |
description | ReactNode | — | Dim secondary line below the label (an ETA, a fee note). Part of the clickable label. |
disabled | boolean | — | Prevents selection and dims the row. Per-radio only; there is no group-level disabled. |
className | string | — | Additional CSS class on the label element. |
Examples
Stacked group
Rendering Radio outside RadioGroup throws "<Radio> must be rendered inside a <RadioGroup>."
With descriptions
description renders a secondary line inside the label. It is part of the click target and accessible label.
Inline
inline lays the radios out in a row. It suits short labels with no descriptions; a description in an inline group still renders under its label and makes the row taller. For toolbars, use SegmentedControl.
Labelled group, unavailable option
RadioGroup renders role="radiogroup" without its own aria-label prop. Wrap the group in a Fieldset to provide a legend. Set disabled on an individual Radio to prevent selection.
import { Radio, RadioGroup } from "@solarius/onset";
import type { RadioProps, RadioGroupProps } from "@solarius/onset";