Radio Input
A radio input provides a bare <input type="radio"> element without a wrapping label. It is designed for use in custom radio group layouts where labels are provided separately or by a parent component. The component uses aria-label to ensure each radio button has an accessible name.
This component is useful in custom-designed radio groups, card selection interfaces, segmented controls, and any layout where the radio button and its label need to be independently positioned or styled. For simple radio groups with adjacent labels, consider wrapping this in a <label> element.
Implementation Notes
- Renders a native
<input type="radio">element - Uses
aria-labelfor accessible naming (no visible label element included) - Supports
nameattribute for grouping radio buttons into a mutually exclusive set - Supports
valueattribute for identifying which option is selected - Supports
checkedanddisabledstates - Does not use two-way binding for checked state; consumers can use event handlers or bind directly
- Spreads
restPropsfor consumer customization (e.g.,onchange,id)
Props
label: string (required) -- accessible name viaaria-labelname: string (default:undefined) -- radio group name for mutual exclusionvalue: string (default:undefined) -- the value representing this radio optionchecked: boolean (default:false) -- whether this radio button is currently selecteddisabled: boolean (default:false) -- whether the radio button is disabled...restProps: any additional HTML attributes spread onto the input
Usage
<Fieldset legend="Are you 18 or over?">
<RadioGroup name="age-check">
<RadioInput label="Yes" value="yes" />
<RadioInput label="No" value="no" />
</RadioGroup>
</Fieldset>
<Fieldset legend="How would you like to receive your results?">
<RadioGroup name="results-preference">
<RadioInput label="Email" value="email" hint="We will send results within 24 hours" />
<RadioInput label="Post" value="post" hint="Results will arrive within 7 working days" />
<RadioInput label="I do not want my results" value="none" />
</RadioGroup>
</Fieldset>
Keyboard Interactions
Native radio input keyboard behavior is handled by the browser:
- Tab: Moves focus to the selected radio in the group (or the first if none selected)
- Arrow Up / Arrow Left: Moves selection to the previous radio in the group
- Arrow Down / Arrow Right: Moves selection to the next radio in the group
- Space: Selects the focused radio button (if not already selected)
ARIA
aria-label={label}-- provides an accessible name for the radio button since no visible<label>element is included
When to Use
- Use when users can only select one option from a list of mutually exclusive choices
- Use within a RadioGroup inside a Fieldset with a legend that poses the question
- Use with a "None of these" or "I do not know" option when it is valid for users to decline all options
- Use with Hint on individual radio items when extra context helps users choose
When Not to Use
- Do not use when users need to select more than one option -- use CheckboxInput within a CheckboxGroup instead
- Do not pre-select a radio option -- users may miss the question or submit the wrong answer
- Do not use for toggling a single setting on or off -- use SwitchButton for immediate-effect toggles
- Do not use for long lists of options -- use Select or Combobox when the list exceeds 6-8 items
Headless
The RadioInput headless component provides a native <input type="radio"> with aria-label for accessible naming, and supports name, value, checked, and disabled attributes. The browser handles all radio group keyboard navigation natively. The consumer provides all visual styling.
Styles
The consumer provides all CSS styling. The component renders with a .radio-input class for targeting. No default styles are included — this is a fully headless component.
Testing
- Verify the component renders a
<input>element with classradio-input - Verify aria-label={label}
-- provides an accessible name for the radio button since no visible<label>` element is included - Verify keyboard interactions work correctly
- Verify pass-through attributes are applied
Advice
- Designers: Ensure the clickable area around each radio option is large enough for comfortable touch interaction, even when using custom visual designs.
- Developers: Always set a consistent
nameattribute across grouped RadioInput components to ensure mutual exclusion, and useonchangehandlers to update state.
Related components
radio-group— a group of radio buttons for selecting one optioncheckbox-input— a checkbox input for toggling a boolean value <input type="checkbox">segment-group-item— one selectable segment in a segment group
References
- WAI-ARIA Radio Group Pattern: https://www.w3.org/WAI/ARIA/apg/patterns/radiobutton/
- MDN input type="radio": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio