Skip to content
Browse documentation
DocsComponents

Radio

Choose exactly one option from a related set.

Installation

Terminal
pnpm dlx shadcn@latest add https://react-toolbox.io/r/radio.json

New 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

PropertyTypeDefault
labelReact.ReactNode—
rippleboolean—
classNamesRadioButtonTheme

Classes for the component's rendered parts. Applied after legacy theme overrides.

—
themeDeprecated aliasRadioButtonTheme

Use classNames for style slots; use ThemeProvider for design tokens.

—
refReact.Ref<RadioButtonHandle>—
valuestring—

Callbacks

PropertyTypeDefault
onMouseEnterReact.MouseEventHandler<HTMLLabelElement>—
onMouseLeaveReact.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:

  • disabled
  • field
  • input
  • radio
  • radioChecked
  • ripple
  • text

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

PropertyTypeDefault
disabledbooleanfalse
namestring—
valuestring—
classNamesRadioButtonTheme

Classes for the component's rendered parts. Applied after legacy theme overrides.

—
themeDeprecated aliasRadioButtonTheme

Use classNames for style slots; use ThemeProvider for design tokens.

—
refReact.Ref<HTMLDivElement>—

Callbacks

PropertyTypeDefault
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:

  • disabled
  • field
  • input
  • radio
  • radioChecked
  • ripple
  • text

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
tsx
type RadioButtonTheme = RadioTheme;
RadioButtonHandle
tsx
interface RadioButtonHandle {
  focus(): void;
  blur(): void;
  readonly inputElement: HTMLInputElement | null;
}
RadioButtonProps
tsx
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
tsx
type RadioButtonClassNames = RadioButtonTheme;
RadioGroupProps
tsx
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.

Material Design 1: Selection controls