RadioGroup
A set of options where exactly one is chosen. Base UI owns the roving tab index and the arrow keys; this owns the surface they wear.
import { Radio, RadioGroup } from 'neba';
<RadioGroup label="Plan" defaultValue="team">
<Radio value="starter" label="Starter" />
<Radio value="team" label="Team" />
</RadioGroup>;Props
RadioGroup
| Prop | Type | Default | Description |
|---|---|---|---|
| sizeshared | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Height and type scale |
| colorshared | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info' | 'primary' | Semantic colour role. Set on the group, inherited by every Radio |
| orientationshared | 'horizontal' | 'vertical' | 'vertical' | Which way the options stack. Vertical by default — a row breaks the moment one label is long |
| label | ReactNode | — | The label, wired to the control by Base UI's Field |
| description | ReactNode | — | Helper text |
| error | ReactNode | — | Error message. Its presence turns the control invalid and re-points the colour family at danger |
| invalid | boolean | !!error | Forces the invalid state without a message, for when a form library owns validity |
| value | Value | — | The chosen value. Use with onValueChange for a controlled group |
| defaultValue | Value | — | The initial value, for an uncontrolled group |
| onValueChange | (value: Value, details) => void | — | Called when the chosen option changes |
| name | string | — | Identifies the field when a form is submitted |
| required | boolean | false | One option must be chosen before the form submits |
| readOnly | boolean | false | Shown but not changeable. Keeps its colour and edge, drains the saturation |
| disabled | boolean | false | Unavailable. Drops the colour family for neutral grey |
| children | ReactNode | — | The Radio options |
Radio
| Prop | Type | Default | Description |
|---|---|---|---|
| value * | Value | — | Identifies this option. Speaks the same language as the group’s value |
| label | ReactNode | — | The text beside the dot |
| description | ReactNode | — | Helper text under the label |
| readOnly | boolean | false | Shown but not changeable. Keeps its colour and edge, drains the saturation |
| disabled | boolean | false | Unavailable. Drops the colour family for neutral grey |
A Radio has no size and no color of its own. Both come from the group, which is the only place they can be set once and mean the same thing for every option in the set — a radio button is meaningless alone, it only says anything relative to its siblings.
Examples
Descriptions
An option that needs a sentence gets one. The dot stays centred on the first line of the label whatever the description does under it.
Orientation
Vertical by default. A row of options is fine right up until one label is longer than expected, and then it silently stops being readable.
States
disabled and readOnly can be set on the group or on one option. On the group, readOnly reaches every member.
Why this one is round
Roundness is what tells a reader "one of these" rather than "any of these", and it is the one convention old enough that breaking it would cost more than it bought. Everything else about the dot — the acrylic, the hairline, the fill on selection — is the same as a Checkbox.
Accessibility
- The set takes one tab stop; the arrow keys move within it. That is the whole reason this is a component rather than a
<div>full of inputs. - The group's
labelbecomes its accessible name. - Each
Radiois wired to its label by Base UI's Field, so clicking the text selects it.