Redpanda UIRedpanda UI

Radio Group

A set of checkable buttons—known as radio buttons—where no more than one of the buttons can be checked at a time.

Made by imskyleen

Installation

Loading component...

Horizontal

Loading component...

Disabled items

Loading component...

When to use

Radio groups provide mutually exclusive options where users must select exactly one choice. Use this decision tree to determine when radio groups are appropriate:

Usage

Basic Usage

import { RadioGroup, RadioGroupItem } from "@/components/redpanda-ui/radio-group"
import { Label } from "@/components/redpanda-ui/label"

<RadioGroup defaultValue="option1">
  <div className="flex items-center space-x-2">
    <RadioGroupItem value="option1" id="r1" />
    <Label htmlFor="r1">Option 1</Label>
  </div>
  <div className="flex items-center space-x-2">
    <RadioGroupItem value="option2" id="r2" />
    <Label htmlFor="r2">Option 2</Label>
  </div>
  <div className="flex items-center space-x-2">
    <RadioGroupItem value="option3" id="r3" />
    <Label htmlFor="r3">Option 3</Label>
  </div>
</RadioGroup>

Controlled Usage

import { useState } from "react"

function ControlledRadioGroup() {
  const [value, setValue] = useState("option1")

  return (
    <RadioGroup value={value} onValueChange={setValue}>
      <div className="flex items-center space-x-2">
        <RadioGroupItem value="option1" id="r1" />
        <Label htmlFor="r1">Option 1</Label>
      </div>
      <div className="flex items-center space-x-2">
        <RadioGroupItem value="option2" id="r2" />
        <Label htmlFor="r2">Option 2</Label>
      </div>
    </RadioGroup>
  )
}

With Custom Animation

<RadioGroup defaultValue="fast">
  <div className="flex items-center space-x-2">
    <RadioGroupItem 
      value="fast" 
      id="fast"
      transition={{ type: 'spring', stiffness: 300, damping: 20 }}
    />
    <Label htmlFor="fast">Fast Animation</Label>
  </div>
  <div className="flex items-center space-x-2">
    <RadioGroupItem 
      value="slow" 
      id="slow"
      transition={{ type: 'spring', stiffness: 100, damping: 30 }}
    />
    <Label htmlFor="slow">Slow Animation</Label>
  </div>
</RadioGroup>

Anatomy

The Radio Group component is built with Base UI primitives and enhanced with Motion animations:

RadioGroup (Root Container)
├── RadioGroupItem (Individual Radio Button)
│   ├── Motion wrapper - handles hover/tap animations
│   ├── Border/Visual styling - circular border
│   └── RadioGroupIndicator (Selection Indicator)
│       └── Motion Circle - animated filled circle
└── Layout - grid with gap-2.5 spacing

Animation States:
├── Hover - scale: 1.05
├── Tap - scale: 0.95
└── Selection Indicator
    ├── Initial - opacity: 0, scale: 0
    ├── Selected - opacity: 1, scale: 1
    └── Deselected - opacity: 0, scale: 0

Key Features:

  • Single Selection: Only one option can be selected at a time
  • Keyboard Navigation: Arrow keys move between options, Space/Enter selects
  • Accessibility: Full ARIA support with proper labeling and focus management
  • Animation: Smooth spring animations for selection state and hover/tap feedback
  • Customizable: Configurable transition timing and styling

Props

Animate UI Props

RadioGroupItem

Prop

Type

Examples

Default

Loading component...

Attached

Loading component...

With description

Loading component...

Error state

Loading component...

Card style

Loading component...

Form

Loading component...

Keyboard interactions

KeyAction
Tab into the groupFocus lands on the currently-selected item, or the first item if none is selected.
ArrowUp / ArrowDownMoves between items (vertical).
ArrowLeft / ArrowRightMoves between items (horizontal).
SpaceSelects the focused item.

Accessibility

  • The group container is role="radiogroup" and each item role="radio" with aria-checked. Base UI additionally sets the Radix-compat data-state="checked" | "unchecked" attribute.
  • Always label the group: wrap it in a <Label> + visual heading, or use <Field> / <FormLabel> in a form context. Individual items also need associated <Label htmlFor>.
  • Focus is roving — only the currently-selected item is tabbable. Arrow keys both move focus and select the next item (standard radio group semantics).
  • onValueChange is the Radix-style single-argument (value: string) => void via the compat layer.

Credits

Recent changes

  • patchv1.2.0Pin shipped dependency floors to the version we develop against. Registry items now declare ranges like `^5.1.9` (the actual installed version) instead of collapsing to `^5.0.0`, so consumers start on the known-tested b…#133
  • minorv1.1.0Theme docs refresh, readability pass on semantic foregrounds, and consumer-facing Base UI regression fixes.#121
  • minorv1.0.0Post-Base-UI polish. Public API unchanged.#116
  • majorv1.0.0Migrate every Radix-based primitive to `@base-ui/react@^1.4.0` (Base UI).#114
  • patchv0.3.1**Accordion** - `AccordionTrigger` now shows `cursor-pointer` on hover.#112
See full history →
Built by malinskibeniamin. The source code is available on GitHub.

On this page