Skip to main content

Radio

MD3 radio button, built on a native <input type="radio">. Wrap radios in a RadioGroup to share a name, manage the selected value, and expose a role="radiogroup".

RadioGroup​

RadioGroup hands a shared name to every Radio inside it (at any depth) and tracks the selection. Use defaultValue for an uncontrolled group.

<RadioGroup aria-label="Notification frequency" defaultValue="daily">
<label>
<Radio value="realtime" /> Real time
</label>
<label>
<Radio value="daily" /> Daily digest
</label>
</RadioGroup>

Controlled​

Pass value and onChange. onChange receives the native event and the newly selected value (MUI-style (event, value)).

Selected: medium

const [value, setValue] = useState('medium')

<RadioGroup aria-label="Size" value={value} onChange={(event, next) => setValue(next)}>
<label><Radio value="small" /> Small</label>
<label><Radio value="medium" /> Medium</label>
<label><Radio value="large" /> Large</label>
</RadioGroup>

Standalone radios​

Without a group, radios that share a name behave like native radios: the browser keeps them mutually exclusive. A Radio's own onChange fires with (event, value) when that radio becomes selected.

<Radio name="plan" value="a" defaultChecked aria-label="Option A" />
<Radio name="plan" value="b" aria-label="Option B" />

Disabled​

Disable a single radio, or every radio at once with <RadioGroup disabled>.

<RadioGroup aria-label="Plan" defaultValue="free" disabled>
…
</RadioGroup>

Accessibility​

  • Each radio is a native <input type="radio">: Tab moves into the group (to the selected radio), arrow keys move the selection within it, and Space selects — all native behavior.
  • Give every radio an accessible name: wrap it in a <label> with visible text, or pass aria-label.
  • Name the group with aria-label or aria-labelledby on RadioGroup.
  • The touch target is 48dp. ref points at the root element; inputRef reaches the native input.

Props​

Radio​

PropTypeDefaultDescription
checkedboolean—Controlled checked state.
defaultCheckedboolean—Uncontrolled initial checked state (native input behavior — the browser manages group exclusivity for radios sharing a `name`).
inputRefRef<HTMLInputElement>—Ref to the native `<input>` element (the forwarded `ref` points at the root).
onChange((event: ChangeEvent<HTMLInputElement, Element>, value: string) => void)—Fires with the native event and this radio's `value` (as a string — the same value a wrapping `RadioGroup` reports) when the radio is selected.

RadioGroup​

PropTypeDefaultDescription
childrenReactNode—`Radio` elements (any depth).
defaultValuestring—Uncontrolled initial selected value.
disabledbooleanfalseDisable every radio in the group.
namestring—Shared input name for the group. Auto-generated when omitted.
onChange((event: ChangeEvent<HTMLInputElement, Element>, value: string) => void)—Fires with the native event and the newly selected value.
valuestring—Controlled selected value.