Components · Inputs
Radio group
BetaPicks exactly one option, such as the billing cycle.
- Source
components/ui/radio-group.tsx - shadcn/ui Radio group
- Figma: not linked yet (Q13)
When to use
- To pick exactly one of 2 to 5 options that should all be visible: a billing cycle, a session type, a weight unit.
When not to use
- More than about 5 options: use a Select.
- Several options can be on at once: use checkboxes.
- A single on/off choice: use a Switch or checkbox.
Anatomy
- 1. Group label: a fieldset legend
- 2. Radio: a circle, filled when selected
- 3. Option label, with optional description
Variants
- Vertical (default): options with descriptions, or labels longer than a word or two.
- Horizontal: 2 or 3 short options that fit on one line. Wraps on small screens.
States
| State | What changes | Token |
|---|---|---|
| Selected | Filled dot | fill-primary |
| Focus-visible | Ring around the radio | ring-ring/50 |
| Disabled | Half opacity, label too | opacity-(--opacity-disabled) |
| Invalid | Red border | border-destructive |
Disabled is shown in the horizontal example. Try the keyboard behavior below in both directions.
Usage guidelines
- Always preselect the most common or safest option, unless the choice must be deliberate.
- Order options logically: smallest to largest, most to least common.
- Don't use a radio group to trigger navigation or actions.
Content guidelines
- The group label is a noun: "Billing cycle". Options are parallel: "Monthly", "Every 3 months", "Yearly".
- Put prices and savings in the description, so the options stay scannable.
Accessibility
| Key | Does |
|---|---|
| Tab | Moves focus into the group, to the selected radio |
| Arrow keys | Move to and select the next or previous option. In RTL, Right goes to the previous option |
| Space | Selects the focused option |
- Rendered as a
radiogroupofradioelements inside afieldset. Announced as "Billing cycle, Monthly, radio button, checked, 1 of 3". - Arrow keys follow the reading direction because the site provides Radix's
DirectionProvider.
RTL
The radio sits at the start of each option, so it moves to the right, and arrow-key order reverses with the direction.
Tokens used
Read from components/ui/radio-group.tsx at build time, so this list changes when the component does. Opacity modifiers such as /90 are shadcn hover and focus tints on top of the token.
| Token | Utilities | SuperCoach | Coach |
|---|---|---|---|
| --destructive | border-destructive ring-destructive/20 | red-600 | red-600 |
| --input | border-input | neutral-200 | neutral-200 |
| --primary | text-primary fill-primary | brand-600 | orange-500 |
| --ring | border-ring ring-ring/50 | brand-600 | orange-500 |
- Opacity
opacity-(--opacity-disabled) - Radius
rounded-full - Shadow
shadow-xs
Props
<RadioGroup>
Also takes every prop of Radix RadioGroup.Root
No props of its own.
<RadioGroupItem>
Also takes every prop of Radix RadioGroup.Item
No props of its own.
Replaces in coach-admin
From the read-only audit of coach-admin: 33 style values, 43 uses.
Classes and selectors
.el-radio-card__radio-circle5.el-radio-card__description3.plan__radio-circle3input[type='radio']3.radio-label2.smart-automation-card__radio2.el-radio-card__title2&:hover:not(.el-radio-card--disabled)2&.el-radio-card--disabled1.plan__radio-label1.form-radio-m1.el-radio-card1
Files
src/reusableComponents/formComponents/radio-card/radio-card.scss35
The inventory lists the first 12 locations of each value, so file counts are a lower bound.