Skip to content
garn

Radio Group

Choose exactly one option from a small set of visible choices.

Stablev0.4.2added in v0.1.0@garn/ui/radio-group
On this page

Default

Three labeled options, one preselected.

Sizing

Radio dot size (fixed --garn-box-* geometry, identity); set on the root, propagated to items.

States

Interactive states, toggled live.

Installation

garn is copy-in — the garn CLI writes this component's source into your project, so you own and can edit it. It resolves any base files and installs the npm dependencies below for you.

terminal
npx garn-ui add radio-group
First time? Set up garn in your project
Registry
radio-group
Deps
@radix-ui/react-radio-groupclass-variance-authoritylucide-react
Registry deps
utils

Import

import { RadioGroup, RadioGroupItem } from "@garn/ui/radio-group";

Anatomy

The parts this component is built from — compose them to assemble it.

RadioGroupRequired[data-slot="radio-group"]

Root — owns the selected value and the size (propagated to items).

RadioGroupItemRequired[data-slot="radio-group-item"]

One option; needs a unique value. Pair each with a Label.

Props

The component's public props and their types.

size
Description
No description.
Type
"lg" | "md" | "sm"
Default
md

Plus 288 inherited native HTML attributes.

Styling

Target these data-slots and states, and remap these tokens, to restyle without forking the component.

[data-slot="radio-group"]

States

SelectorState
[data-state=checked]checked
:focus-visiblefocus-visible
[disabled]disabled
PropertyTokenTier
size--garn-box-mdsemantic · identity
fill--garn-brand-solidbrandablesemantic
ring--garn-ringbrandablesemantic

When to use

Pick one option from a few (≈2–5) mutually exclusive choices, all visible at once.

Reach for something else when

  • A long list (use select)
  • independent on/off items (use checkbox)
  • a single instant setting (use switch).

Overview

RadioGroup lets a person pick exactly one option from a few mutually-exclusive choices that are all worth showing at once (≈2–5). RadioGroup owns the selected value and propagates size to each RadioGroupItem. Once the list grows past a handful or the options stop fitting on screen, switch to Select; for a binary on/off setting, a Switch or single Checkbox reads better than two radios.

Guidelines

Always show one option as selected. A radio group should have a sensible default rather than starting empty — an all-blank group makes "no choice" look like a valid state when it usually isn't. Give each RadioGroupItem a unique value and its own Label.

Keep options parallel and exhaustive. Phrase choices in the same grammatical form and at the same level of specificity, and cover the full space (add an "Other"/"None" when the set isn't complete). Order them logically — by magnitude, frequency, or convention — not at random.

Don't use radios for multi-select or instant actions. Several selectable items → Checkboxes; a setting that takes effect immediately → Switch. Arrow keys move selection within the group (roving focus), so don't nest interactive controls inside an item.

Best practices

Do
  • Give every RadioGroupItem a unique value and a clickable Label.
  • Pre-select a sensible default with defaultValue when one exists.
Don't
  • Don't use radios for many options — switch to a select past ~5.
  • Don't use radios for multi-select — that's checkboxes.

Content guidelines

  • Write parallel option labels in sentence case (“Standard”, “Express”, “Overnight”).
  • Order options logically (by speed, price, or frequency) and lead with the most common.
  • Add a short helper line to an option only when the trade-off isn't obvious from the label.

Troubleshooting

Selecting an option does nothing.

Cause. Passing value without onValueChange makes the group controlled and frozen.

Fix. Use defaultValue for uncontrolled, or pass value + onValueChange.

Accessibility

Role
radiogroup
ARIA APG
radio group
Focus
Roving tabindex; arrow keys move + select within the group.

Accessibility requirements

warn

Label the group and each option (a Label per item, plus a group label).

when the group has no accessible name (aria-labelledby / aria-label) and items have no labels

Keyboard

TabMove focus into the group (lands on the selected, or first, radio).
ArrowUpArrowDownArrowLeftArrowRightMove to and select the next/previous option.
A1.3.1Info and RelationshipsA2.1.1KeyboardA4.1.2Name, Role, Value
  • role=radiogroup wraps role=radio items; label the group (aria-labelledby / a Label).