ToroUI

Radio Group

A set of mutually exclusive radio buttons for selecting a single option from a list.


A radio group built on Base UI's Radio and RadioGroup primitives. It renders styled radio buttons with a filled circle indicator and supports focus-visible ring, disabled state, and validation error styling.

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

export default function RadioGroupDemo() {
  return (
    <RadioGroup defaultValue="option-1">
      <div className="flex items-center gap-2">
        <RadioGroupItem value="option-1" id="option-1" />
        <Label htmlFor="option-1">Option 1</Label>
      </div>
      <div className="flex items-center gap-2">
        <RadioGroupItem value="option-2" id="option-2" />
        <Label htmlFor="option-2">Option 2</Label>
      </div>
      <div className="flex items-center gap-2">
        <RadioGroupItem value="option-3" id="option-3" />
        <Label htmlFor="option-3">Option 3</Label>
      </div>
    </RadioGroup>
  )
}

Anatomy

import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
<RadioGroup defaultValue="option-1">
  <div className="flex items-center gap-2">
    <RadioGroupItem value="option-1" id="option-1" />
    <Label htmlFor="option-1">Option 1</Label>
  </div>
  <div className="flex items-center gap-2">
    <RadioGroupItem value="option-2" id="option-2" />
    <Label htmlFor="option-2">Option 2</Label>
  </div>
</RadioGroup>

Examples

Basic radio group

<RadioGroup defaultValue="comfortable">
  <div className="flex items-center gap-2">
    <RadioGroupItem value="default" id="r1" />
    <Label htmlFor="r1">Default</Label>
  </div>
  <div className="flex items-center gap-2">
    <RadioGroupItem value="comfortable" id="r2" />
    <Label htmlFor="r2">Comfortable</Label>
  </div>
  <div className="flex items-center gap-2">
    <RadioGroupItem value="compact" id="r3" />
    <Label htmlFor="r3">Compact</Label>
  </div>
</RadioGroup>

Disabled item

<RadioGroup defaultValue="option-1">
  <div className="flex items-center gap-2">
    <RadioGroupItem value="option-1" id="d1" />
    <Label htmlFor="d1">Available</Label>
  </div>
  <div className="flex items-center gap-2">
    <RadioGroupItem value="option-2" id="d2" disabled />
    <Label htmlFor="d2">Unavailable</Label>
  </div>
</RadioGroup>

Horizontal layout

Override the default vertical grid layout with a flex row.

<RadioGroup defaultValue="left" className="flex gap-4">
  <div className="flex items-center gap-2">
    <RadioGroupItem value="left" id="h1" />
    <Label htmlFor="h1">Left</Label>
  </div>
  <div className="flex items-center gap-2">
    <RadioGroupItem value="center" id="h2" />
    <Label htmlFor="h2">Center</Label>
  </div>
  <div className="flex items-center gap-2">
    <RadioGroupItem value="right" id="h3" />
    <Label htmlFor="h3">Right</Label>
  </div>
</RadioGroup>

API Reference

RadioGroup

The root container that manages selection state. Renders a grid layout with vertical spacing by default.

PropTypeDefaultDescription
defaultValuestringThe initially selected value (uncontrolled).
valuestringThe selected value (controlled).
onValueChange(value: string) => voidCallback fired when the selected value changes.
disabledbooleanWhen true, disables all radio items in the group.
classNamestring
childrenReactNode

RadioGroupItem

A single radio button. Renders a circular indicator with a filled dot when checked.

PropTypeDefaultDescription
valuestringThe value of this radio item.
idstringUsed to associate with a Label via htmlFor.
disabledbooleanWhen true, prevents interaction and reduces opacity.
classNamestring