Join our Discord Community

Radio Group

A set of checkable buttons where only one can be selected at a time. Built for React applications with Next.js integration and TypeScript support.

You know those round buttons where you can only pick one option? Like choosing a shipping method or selecting a plan? That's radio groups - they make sure users can only pick one thing from a set of choices.

Select your preference

Classic radio group for single-choice selection:

Loading component...

Built on Radix UI RadioGroup with proper keyboard navigation and ARIA support. This free open source React component handles all the focus management and accessibility while looking exactly how you want it.

npx shadcn@latest add radio-group

When to use radio buttons

Radio buttons aren't just checkboxes that hate each other. They're for when you need exactly one choice:

  • Mutually exclusive options - Only one can be true
  • Always visible choices - All options shown upfront
  • Small sets of options - Usually 2-7 choices max
  • Important decisions - Users need to see all options
  • Default selections - One option can be pre-selected
  • Keyboard navigation - Arrow keys move between options

Useful radio group patterns

Settings and preferences

Common pattern for app settings:

Loading component...

Form with validation

Integrated with react-hook-form and validation:

Loading component...

Cards layout

Sometimes radio buttons work better as cards:

Loading component...

These patterns show up everywhere because they solve real problems. Settings that need one choice, form fields that need validation, survey questions that need a single answer.

Perfect for forms and settings

Works great anywhere users need to make a single choice from a visible set - checkout flows, settings panels, surveys, configuration wizards. The kind of decisions where seeing all options matters.

Drops right into Next.js projects. Full TypeScript support. Styled with Tailwind CSS to match the shadcn design system.

Built with Radix UI

Under the hood it's Radix UI RadioGroup, which handles the tricky stuff:

  • Roving tabindex - One tab stop, then arrow keys
  • Automatic IDs - Labels and inputs connected properly
  • Group management - Only one selected at a time
  • Orientation support - Vertical or horizontal layouts
  • Loop navigation - Arrow keys wrap around
  • Form integration - Works with native form submission

API Reference

RadioGroup

The root container that manages radio state.

PropTypeDefaultDescription
classNamestring-Additional CSS classes
defaultValuestring-Default selected value for uncontrolled
valuestring-Controlled selected value
onValueChange(value: string) => void-Called when selection changes
disabledbooleanfalseDisable all radio items
namestring-Name for form submission
requiredbooleanfalseWhether selection is required
orientation"horizontal" | "vertical""vertical"Layout direction
loopbooleantrueWhether keyboard nav loops

Data attributes:

  • [data-disabled]: Present when disabled

RadioGroupItem

Individual radio button in the group.

PropTypeDefaultDescription
classNamestring-Additional CSS classes
valuestringrequiredValue for this option
idstring-ID for label association
disabledbooleanfalseDisable this specific item

Data attributes:

  • [data-state]: "checked" | "unchecked"
  • [data-disabled]: Present when disabled

Keyboard Navigation

KeyAction
TabFocus the radio group
SpaceSelect focused item
Arrow DownMove focus to next item
Arrow RightMove focus to next item
Arrow UpMove focus to previous item
Arrow LeftMove focus to previous item
HomeFocus first item
EndFocus last item

Form Integration

Works with react-hook-form and other form libraries:

<FormField
  control={form.control}
  name="option"
  render={({ field }) => (
    <RadioGroup
      onValueChange={field.onChange}
      defaultValue={field.value}
    >
      <RadioGroupItem value="option1" />
      <RadioGroupItem value="option2" />
    </RadioGroup>
  )}
/>

Common Patterns

PatternUse CaseImplementation
Inline labelsCompact formsLabel next to radio
Stacked labelsMobile-friendlyLabel below radio
Card selectionVisual optionsRadio inside card component
Icon optionsVisual choicesIcon + label + radio
Description textComplex optionsTitle + description per item

Make radio groups that work

Few things to keep in mind:

  • Always have a default - Don't make users think about the obvious choice
  • Keep groups small - More than 7 options? Maybe use a select instead
  • Labels that click - Make the whole label clickable, not just the circle
  • Group related options - Visual spacing helps scanning
  • Clear option names - "Yes/No" beats "Enable/Disable"
  • Consider the layout - Vertical for most things, horizontal for short lists
  • Show the selection - Make it super obvious what's selected
  • Test keyboard navigation - Should feel natural with arrow keys