Radio Group

Radio groups let users select a single option from a set of mutually exclusive choices.

Examples

Basic

Disabled

Entire group disabled
Single item disabled

Custom indicator

Controlled

Selected: comfortable

Overview

RadioGroup provides a set of radio buttons where only one can be selected at a time. Built on Base UI Radio.

tsx
import { RadioGroup, RadioGroupItem } from "@rogo-technologies/ui/radio-group";

<RadioGroup defaultValue="option-one">
  <div className="flex items-center gap-2">
    <RadioGroupItem value="option-one" id="option-one" />
    <label htmlFor="option-one">Option One</label>
  </div>
  <div className="flex items-center gap-2">
    <RadioGroupItem value="option-two" id="option-two" />
    <label htmlFor="option-two">Option Two</label>
  </div>
</RadioGroup>;

Usage

Controlled

tsx
const [value, setValue] = useState("comfortable");

<RadioGroup value={value} onValueChange={setValue}>
  <RadioGroupItem value="default" id="option-default" />
  <RadioGroupItem value="comfortable" id="option-comfortable" />
  <RadioGroupItem value="compact" id="option-compact" />
</RadioGroup>;

Disabled

tsx
<RadioGroup defaultValue="option-a" disabled>
  <RadioGroupItem value="option-a" />
  <RadioGroupItem value="option-b" />
</RadioGroup>

<RadioGroup defaultValue="available">
  <RadioGroupItem value="available" />
  <RadioGroupItem value="unavailable" disabled />
</RadioGroup>

Composable API

Use RadioGroupRoot, RadioItem, and RadioIndicator for custom indicator content.

tsx
import { RadioGroupRoot, RadioItem, RadioIndicator } from "@rogo-technologies/ui/radio-group";

<RadioGroupRoot defaultValue="option-a">
  <RadioItem value="option-a">
    <RadioIndicator />
  </RadioItem>
</RadioGroupRoot>

<RadioGroupRoot defaultValue="option-a">
  <RadioItem value="option-a">
    <RadioIndicator>
      <span className="text-brand text-[10px]"></span>
    </RadioIndicator>
  </RadioItem>
</RadioGroupRoot>

With form libraries

tsx
import { useForm, Controller } from "react-hook-form";

const { control, handleSubmit } = useForm({ defaultValues: { plan: "free" } });

<form onSubmit={handleSubmit(onSubmit)}>
  <Controller
    control={control}
    name="plan"
    render={({ field }) => (
      <RadioGroup value={field.value} onValueChange={field.onChange}>
        <RadioGroupItem value="free" id="plan-free" />
        <label htmlFor="plan-free">Free</label>
        <RadioGroupItem value="pro" id="plan-pro" />
        <label htmlFor="plan-pro">Pro</label>
      </RadioGroup>
    )}
  />
</form>;

Accessibility

  • Radio group uses role="radiogroup" with arrow key navigation
  • Each radio is keyboard accessible with Space to select
  • Focus is visible with a ring indicator
  • Associates with labels via id and htmlFor
  • Supports aria-labelledby for group labels
tsx
<RadioGroup aria-labelledby="plan-heading">
  <h3 id="plan-heading">Choose a plan</h3>
  <RadioGroupItem value="free" id="plan-free" />
  <label htmlFor="plan-free">Free</label>
</RadioGroup>

API

RadioGroup

PropTypeDefaultDescription
valuestringControlled selected value.
defaultValuestringInitial value for uncontrolled usage.
onValueChange(value: string) => voidCallback when selection changes.
disabledbooleanfalseDisables all items in the group.
requiredbooleanfalseMarks the group as required.
namestringName attribute for form submission.

RadioGroupItem

PropTypeDefaultDescription
valuestringUnique value identifying this radio.
disabledbooleanfalseDisables this item.

RadioGroupRoot

PropTypeDefaultDescription
valuestringControlled selected value.
defaultValuestringInitial value for uncontrolled usage.
onValueChange(value: string) => voidCallback when selection changes.
disabledbooleanfalseDisables all items.

RadioItem

PropTypeDefaultDescription
valuestringUnique value identifying this radio.
disabledbooleanfalseDisables this item.

RadioIndicator

PropTypeDefaultDescription
childrenReactNodeFilled circleCustom indicator content.
keepMountedbooleanfalseKeep in DOM when unchecked.

Guidelines

Do

  • Always pair radio items with visible labels
  • Use radio groups for mutually exclusive options (only one can be selected)
  • Provide a sensible default selection when possible
  • Group related options together visually

Don't

  • Don't use radio buttons when multiple selections are allowed — use checkboxes instead
  • Don't use radio groups for binary on/off toggles — use a switch instead
  • Don't have more than 7 options in a radio group — consider a select or combobox instead
  • Don't style radio groups as segmented/tab-like controls — use tabs for view switching
  • Don't leave a required radio group without a default — users can't deselect
Made in NYC© 2026 Rogo Technologies Inc.