Radio
A grouped single-choice control — a RadioGroup that owns the selected value, wrapping one Radio
per option.
Installation
npm install @sipe-team/radio
import '@sipe-team/radio/styles.css';
Usage
RadioGroup renders a <fieldset> and shares a name, size, and the selected value through
context, so every Radio inside it is wired into one group automatically — picking one clears the
rest. Clicking a Radio's label selects it.
Examples
Uncontrolled
Give RadioGroup a defaultValue and let it track the selection itself — the common case for forms
that read the value on submit. RadioGroup generates a name when you do not pass one, so the
options are still submitted as a single field.
Controlled
Own the state yourself with value and onChangeValue when another part of the UI has to react to
the selection. onChangeValue receives the next value string.
Sizes
medium (default) fits most forms; small for dense rows, large for touch targets. Set size on
RadioGroup to scale every option, and the dot, font, and spacing all scale together.
Disabled
disabled on RadioGroup disables every option via the native <fieldset disabled>; disabled on
a single Radio disables just that one. Both dim the affected labels.
Anatomy
import { Radio, RadioGroup } from '@sipe-team/radio';
export default () => (
<RadioGroup labelText="Label" defaultValue="a">
<Radio value="a">Option A</Radio>
<Radio value="b">Option B</Radio>
</RadioGroup>
);
RadioGroup renders a <fieldset> (with a <legend> when labelText is set) and provides context;
each Radio reads from it and renders a <label> wrapping an <input type="radio">. The selected
value, name, size, and disabled live on RadioGroup — a Radio should be rendered inside one
so the options share a group.
API Reference
Neither part forwards a ref.
RadioGroup
Renders a <fieldset>. Provides the selection, name, size, and disabled to its Radio
children through context.
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Required. The Radio options. |
value | string | — | Controlled selected value. Pair with onChangeValue. |
defaultValue | string | — | Initial selected value when uncontrolled. |
onChangeValue | (value: string) => void | — | Called with the next value when a Radio is chosen. |
labelText | string | '' | Rendered as the fieldset's <legend>. Omitted when empty. |
name | string | auto | Shared name for the inputs. Generated via useId when not provided. |
size | 'small' | 'medium' | 'large' | 'medium' | Scales the dot, font size, and spacing of every option. |
disabled | boolean | false | Disables the whole group via <fieldset disabled>. |
className | string | — | Appended to the fieldset class. |
Extra props are not spread onto the <fieldset>; only those above are used.
Radio
Renders a <label> wrapping an <input type="radio">, plus a <span> for the label text when
children are given. Reads the selected value, name, size, and group disabled from
RadioGroup.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Required. This option's value, compared against the group's value. |
children | ReactNode | — | Label text. When omitted, no <span> is rendered. |
size | 'small' | 'medium' | 'large' | group / 'medium' | Overrides the group size for this option. |
disabled | boolean | false | Disables just this option. The group disabled also forces it on. |
defaultChecked | boolean | — | Marks this option checked when uncontrolled. Usually prefer RadioGroup's defaultValue. |
className | string | — | Appended to the <label> (container) class. |
Also accepts the rest of ComponentProps<'input'> except size (onChange, required, id, …),
spread onto the underlying <input>. name and checked are supplied by RadioGroup.
Accessibility
RadioGrouprenders a native<fieldset>;labelTextbecomes its<legend>, labelling the group for screen readers.- Each
Radiois a native<input type="radio">sharing the group'sname, so the browser provides roving focus and arrow-key navigation between options for free. - Every
Radiowraps its<input>in a<label>with a matching generatedid, so clicking the label selects the option. disabledsets the nativedisabledattribute (on the<fieldset>for the group, or the<input>for a single option).
Known limitations
- Radio uses hardcoded light-surface colors (
constants/colors.ts) rather than theme-driven tokens, so it does not adapt to this dark-only docs site. The demos above are shown on a light card so the control renders as intended; on a dark background its text would be illegible. RadioGroupalways stacks its options vertically (flex-direction: column); there is noorientationprop for a horizontal layout.