Radio Group
A set of checkable buttons where only one can be selected at a time.
Installation
$
Usage
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"Examples
Default
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| defaultValueRadioGroup | string | - | The value of the item that is checked initially, for uncontrolled usage. |
| valueRadioGroup, RadioGroupItem | string | - | On <RadioGroup />, the controlled checked value (use with onValueChange). On <RadioGroupItem />, the value this option submits when checked (required). |
| onValueChangeRadioGroup | (value: string) => void | - | Called with the newly checked item's value. |
| nameRadioGroup | string | - | The name submitted with form data. |
| disabledRadioGroup, RadioGroupItem | boolean | false | Disables every item, or a single option on <RadioGroupItem />. |
| requiredRadioGroup | boolean | false | Requires a selection before the owning form can be submitted. |
| orientationRadioGroup | "horizontal" | "vertical" | - | Axis used for arrow-key navigation between items. |
| loopRadioGroup | boolean | true | When true, arrow-key navigation wraps from the last item back to the first. |
"use client"
import * as React from "react"
import { RadioGroup as RadioGroupPrimitive } from "@base-ui/react/radio-group"
import { Radio as RadioPrimitive } from "@base-ui/react/radio"
import { cn } from "@/registry/lib/utils"
function RadioGroup({
className,
...props
}: React.ComponentProps<typeof RadioGroupPrimitive>) {
return (
<RadioGroupPrimitive
data-slot="radio-group"
className={cn("grid gap-3", className)}
{...props}
/>
)
}
function RadioGroupItem({
className,
...props
}: React.ComponentProps<typeof RadioPrimitive.Root>) {
return (
<RadioPrimitive.Root
data-slot="radio-group-item"
className={cn(
"peer tap-target border-border dark:bg-neutral-800 data-[checked]:bg-accent data-[checked]:text-accent-foreground dark:data-[checked]:bg-accent data-[checked]:border-accent focus-visible:border-accent focus-visible:ring-ring-accent aria-invalid:ring-ring-destructive aria-invalid:border-destructive size-4 shrink-0 rounded-full border shadow-xs transition-[transform,color,background-color,border-color,box-shadow] motion-reduce:transition-[color,background-color,border-color,box-shadow] duration-150 ease-out active:scale-[0.98] outline-none focus-visible:ring-1 data-[disabled]:cursor-not-allowed data-[disabled]:opacity-70",
className
)}
{...props}
>
<RadioPrimitive.Indicator
data-slot="radio-group-indicator"
className="grid size-full place-content-center text-current animate-in zoom-in-50 duration-150"
>
<span className="size-1.5 rounded-full bg-current" />
</RadioPrimitive.Indicator>
</RadioPrimitive.Root>
)
}
export { RadioGroup, RadioGroupItem }