Single-choice form control for mutually-exclusive options inside a RadioGroup.
Description
Radio is a single item within a radio group. It is always rendered inside a RadioGroup; the group owns the selected value, the roving tab index, and arrow-key navigation. On its own a Radio cannot toggle, which is by design: a single radio is never the right control.
Reach for it when you have two to six mutually-exclusive options that should all be visible at once: a plan picker, a theme switcher, a sort order. For more than six options use Select; for binary on/off use Switch; for one-of-many that allows multiple use CheckboxGroup.
Don't use Radio for a standalone yes/no answer; a single radio that can't be unselected is a usability dead-end. Use Checkbox instead.
Installation
Usage
Examples
Variants
variant picks the semantic intent of the selected indicator. primary is the default; use danger for a destructive option (e.g. "Delete account") and inverse on dark surfaces.
Sizes
Three sizes line up with the rest of the form-control scale. sm is the default; drop to xs in dense rows, or use md for more spacious layouts.
States
The radio exposes four runtime states (unchecked, checked, disabled, and disabled-checked) through the Radix data-state and data-disabled attributes.
Inside RadioGroup
When variant and size are passed on the group, every child Radio inherits them through RadioContext. Pass styling once on the parent, not on each item.
Accessibility
Radio is built on Radix UI's RadioGroup.Item, so keyboard navigation, focus management, and ARIA wiring are handled for you. Focus management is roving: only the checked (or first) item is in the tab order.
ARIA notes:
- The root renders with
role="radio"and setsaria-checkedto"true"or"false". disabledsetsdata-disabledand skips the item during arrow-key navigation.- The indicator dot is decorative; expose the radio's purpose via
aria-label,aria-labelledby, or a<label htmlFor>association.
Styling
Tailwind override: pass className to merge Tailwind classes with the component's CVA classes:
Data slots and attributes: the component sets these for CSS targeting:
data-slot="radio"on the root element.data-slot="radio-indicator"on the inner indicator wrapper.data-variant="<variant>",data-size="<size>"on the root.data-state="checked" | "unchecked"(managed by Radix) anddata-disabled(only whendisabled).
Target a specific state in CSS:
Related Components
- RadioGroup: the required parent; owns the selected value and arrow-key navigation.
- Checkbox: single binary control when there isn't a mutually-exclusive set.
- Select: use instead of
RadioGroupwhen there are more than six options. - Switch: immediate on/off setting.
API Reference
Radio
A single radio item. Extends React.ComponentProps<typeof Radix.RadioGroup.Item>, so any prop the Radix primitive accepts (value, id, disabled, required, …) is forwarded.