Radio
Choose exactly one option from a related set.
Installation
pnpm dlx shadcn@latest add https://react-toolbox.io/r/radio.jsonNew here? Set up your project first. Styles, fonts, and required components are included.
Usage
Give each RadioButton a distinct value and visible label. RadioGroup keeps a single selected value and shares the input name across the group.
Use the Code tab above for a complete example. The import follows your configured UI alias. See Theming to customize colors, spacing, and style slots.
State and callbacks
RadioGroup is controlled: pass value and update it from onChange. Each RadioButton supplies its own value; the group computes checked state and shares the name and disabled state.
A standalone RadioButton uses checked and onChange directly. There is no uncontrolled group selection API.
API reference
Generated from the installed TypeScript source. Defaults are the values declared by each function; a dash means no parameter default is declared. Forwarded props can use the receiving component’s default. Callback types show the exact arguments passed to your handler.
RadioButton
| Property | Type | Default |
|---|---|---|
label | React.ReactNode | — |
ripple | boolean | — |
classNames | RadioButtonThemeClasses for the component's rendered parts. Applied after legacy theme overrides. | — |
themeDeprecated alias | RadioButtonThemeUse classNames for style slots; use ThemeProvider for design tokens. | — |
ref | React.Ref<RadioButtonHandle> | — |
value | string | — |
Callbacks
| Property | Type | Default |
|---|---|---|
onMouseEnter | React.MouseEventHandler<HTMLLabelElement> | — |
onMouseLeave | React.MouseEventHandler<HTMLLabelElement> | — |
onChange | (event: React.MouseEvent<HTMLInputElement>, handle: RadioButtonHandle) => void | — |
Also inherits Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'type' | 'size' | 'onMouseEnter' | 'onMouseLeave'>, except the omissions and overrides in its exported props type below. Use the supported native aria-*, data-*, event, and element attributes as appropriate.
Additional defaults on inherited props: checked = false; className = ''; disabled = false.
Style slots
Pass a map of Tailwind classes to classNames. Available keys:
disabledfieldinputradioradioCheckedrippletext
theme is the deprecated compatibility alias. When both are provided, classNames wins conflicting utilities within each slot. See Theming for tokens and override rules.
RadioGroup
| Property | Type | Default |
|---|---|---|
disabled | boolean | false |
name | string | — |
value | string | — |
classNames | RadioButtonThemeClasses for the component's rendered parts. Applied after legacy theme overrides. | — |
themeDeprecated alias | RadioButtonThemeUse classNames for style slots; use ThemeProvider for design tokens. | — |
ref | React.Ref<HTMLDivElement> | — |
Callbacks
| Property | Type | Default |
|---|---|---|
onChange | (value: string | undefined, event: React.MouseEvent<HTMLInputElement>) => void | — |
Also inherits Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'>, except the omissions and overrides in its exported props type below. Use the supported native aria-*, data-*, event, and element attributes as appropriate.
Additional defaults on inherited props: className = ''.
Style slots
Pass a map of Tailwind classes to classNames. Available keys:
disabledfieldinputradioradioCheckedrippletext
theme is the deprecated compatibility alias. When both are provided, classNames wins conflicting utilities within each slot. See Theming for tokens and override rules.
Exported TypeScript types
Expand a type to inspect its full declaration, including generic constraints, union branches, callback arguments, ref handles, and inherited props. Import these types from @/components/ui/material/radio.
RadioButtonTheme
type RadioButtonTheme = RadioTheme;RadioButtonHandle
interface RadioButtonHandle {
focus(): void;
blur(): void;
readonly inputElement: HTMLInputElement | null;
}RadioButtonProps
interface RadioButtonProps
extends Omit<
React.InputHTMLAttributes<HTMLInputElement>,
'onChange' | 'type' | 'size' | 'onMouseEnter' | 'onMouseLeave'
> {
label?: React.ReactNode;
onMouseEnter?: React.MouseEventHandler<HTMLLabelElement>;
onMouseLeave?: React.MouseEventHandler<HTMLLabelElement>;
ripple?: boolean;
/** Classes for the component's rendered parts. Applied after legacy theme overrides. */
classNames?: RadioButtonTheme;
/** @deprecated Use classNames for style slots; use ThemeProvider for design tokens. */
theme?: RadioButtonTheme;
ref?: React.Ref<RadioButtonHandle>;
value?: string;
onChange?: (event: React.MouseEvent<HTMLInputElement>, handle: RadioButtonHandle) => void;
}RadioButtonClassNames
type RadioButtonClassNames = RadioButtonTheme;RadioGroupProps
interface RadioGroupProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {
disabled?: boolean;
name?: string;
value?: string;
/** Classes for the component's rendered parts. Applied after legacy theme overrides. */
classNames?: RadioButtonTheme;
/** @deprecated Use classNames for style slots; use ThemeProvider for design tokens. */
theme?: RadioButtonTheme;
onChange?: (value: string | undefined, event: React.MouseEvent<HTMLInputElement>) => void;
ref?: React.Ref<HTMLDivElement>;
}Material guidelines
- Use a radio group for one choice among mutually exclusive options. Show alternatives together when comparing them helps the decision.
- Label both the group and its options. Use a dropdown when the available space or number of choices makes an inline group impractical.