RadioGroup

RadioGroup provides accessible single-choice selection using Radix primitives with Brandit UI styling.

When to use

  • Let users choose one option from a small, fixed list.
  • Present settings where mutually exclusive choices are required.
  • Prefer radio groups over dropdowns when all options should stay visible.

Behavior notes

  • Use defaultValue for uncontrolled usage or value + onValueChange for controlled state.
  • Pair each RadioGroupItem with a Label and matching id/htmlFor for accessibility.
  • Keep option labels concise and easy to scan.

Example

<RadioGroup defaultValue='email'>
  <div className='flex items-center gap-2'>
    <RadioGroupItem id='notify-email' value='email' />
    <Label htmlFor='notify-email'>Email</Label>
  </div>
  <div className='flex items-center gap-2'>
    <RadioGroupItem id='notify-sms' value='sms' />
    <Label htmlFor='notify-sms'>SMS</Label>
  </div>
</RadioGroup>

Preview

Usage

import { Label, RadioGroup, RadioGroupItem } from '@branditdev/ui';

export function RadioGroupDemo() {
  return (
    <div className='w-full max-w-sm space-y-3'>
      <RadioGroup defaultValue='starter' aria-label='Billing plan'>
        <div className='flex items-center gap-2'>
          <RadioGroupItem id='plan-starter' value='starter' />
          <Label htmlFor='plan-starter'>Starter</Label>
        </div>
        <div className='flex items-center gap-2'>
          <RadioGroupItem id='plan-pro' value='pro' />
          <Label htmlFor='plan-pro'>Pro</Label>
        </div>
        <div className='flex items-center gap-2'>
          <RadioGroupItem id='plan-enterprise' value='enterprise' />
          <Label htmlFor='plan-enterprise'>Enterprise</Label>
        </div>
      </RadioGroup>
    </div>
  );
}

API

RadioGroup(props): Element

Defined in: components/radio-group/radio-group.tsx:14

RadioGroup UI component.

Parameters

NameTypeOptionalDefaultDescription
propsRadioGroupProps & RefAttributes<HTMLDivElement>no-Component properties.

Returns

Element

Rendered component.

Source

import { CircleIcon } from 'lucide-react';
import { RadioGroup as RadioGroupPrimitive } from 'radix-ui';

import { cn } from '@branditdev/ui';


export function RadioGroup({
  className,
  ...props
}: React.ComponentProps<typeof RadioGroupPrimitive.Root>) {
  return (
    <RadioGroupPrimitive.Root
      data-slot='radio-group'
      className={cn('grid gap-3', className)}
      {...props}
    />
  );
}

export function RadioGroupItem({
  className,
  ...props
}: React.ComponentProps<typeof RadioGroupPrimitive.Item>) {
  return (
    <RadioGroupPrimitive.Item
      data-slot='radio-group-item'
      className={cn(
        'aspect-square size-4 shrink-0 rounded-full border border-input text-primary shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:bg-input/30 dark:aria-invalid:ring-destructive/40',
        className
      )}
      {...props}
    >
      <RadioGroupPrimitive.Indicator
        data-slot='radio-group-indicator'
        className='relative flex items-center justify-center'
      >
        <CircleIcon className='absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 fill-primary' />
      </RadioGroupPrimitive.Indicator>
    </RadioGroupPrimitive.Item>
  );
}