Components · Actions
Toggle group
BetaA set of toggles where one or several can be on, such as kg and lb.
- Source
components/ui/toggle-group.tsx - shadcn/ui Toggle group
- Figma: not linked yet (Q13)
When to use
- To switch between 2 to 4 short options that change what's on screen right away: kg or lb, list or cards, week or month.
- To pick several options from a short, fixed set shown as a row: training days.
When not to use
- For a choice inside a form that is saved later, especially with descriptions: use a Radio group or checkboxes.
- To switch between panels of content: use Tabs.
- To run actions ("Edit", "Duplicate"): use a Button group.
- For more than about 5 options, or long labels: use a Select.
Anatomy
- 1. Group: radiogroup (single) or toolbar (multiple), joined into one control
- 2. Item, selected: accent fill
- 3. Item, not selected
Variants
Multiple, outline: training days
Single, default, with spacing: client view
| Prop | Options | Use for |
|---|---|---|
type | "single" | One option at a time: units, views. Behaves like a radio group. |
"multiple" | Any number on: training days, which charts to show. | |
variant | default | Inside a toolbar or card header that already has a border. |
outline | On its own, where the items need an edge. Joined items share borders. | |
spacing | 0 (default) | Items joined into one segmented control. |
1 and up | Items separated by that many 4px steps, each with its own corners. |
In single mode, pressing the selected item clears the value. When there must always be a value (a weight unit), control it and ignore the empty value, as in the first example: onValueChange={(v) => v && setUnit(v)}.
States
One item disabled
Whole group disabled
| State | What changes | Token |
|---|---|---|
Selected (data-state="on") | Accent fill and text | bg-accent, text-accent-foreground |
| Hover | Light fill | hover:bg-muted (default), hover:bg-accent (outline) |
| Focus-visible | Ring on the item, raised above its neighbors | ring-ring/50, z-(--z-raised) |
| Disabled item or group | Half opacity, skipped by arrow keys | opacity-(--opacity-disabled) |
The selected fill is very close to the background (about 1.1:1), so selection is carried mostly by the text color. See Toggle.
Sizes
Set size on the group, not on each item: sm (32px), default (36px), lg (40px). Items read it from the group.
Usage guidelines
- Give the group a visible label or an
aria-label. The items alone ("kg", "lb") don't say what they set. - Keep items in a logical order: smallest to largest, days in week order (Sunday first for Gulf clients).
- Don't mix icon-only and text items in one group.
Content guidelines
- One word or a unit per item: "kg", "List", "Monthly". Sentence case.
- If you abbreviate ("Sun", "أحد"), set
aria-labelto the full word and keep the visible text inside it, so voice control still matches. - Units in Arabic use the Arabic abbreviation ("كغ") with Western digits around them (Q22).
Accessibility
| Key | Does |
|---|---|
| Tab | Moves into the group, to the selected item (or the first one); Tab again leaves the group |
| Arrow keys | Move focus between items, wrapping at the ends. In RTL, Right goes to the previous item |
| Home / End | First or last item |
| Space or Enter | Selects or clears the focused item |
type="single"rendersrole="radiogroup"with items asrole="radio"andaria-checked. Announced as "Weight unit, radio group, kg, radio button, checked, 1 of 2".type="multiple"rendersrole="toolbar"with items as toggle buttons witharia-pressed. Announced as "Training days, toolbar, Sun, toggle button, pressed". The visible abbreviation is the name (label in name, WCAG 2.5.3);<abbr title>gives the full day on hover.- Unlike a radio group, arrow keys only move focus; Space selects. This avoids changing a view while someone is just moving through it.
- Arrow keys follow the reading direction because the site provides Radix's
DirectionProvider.
RTL
- Items run right to left, so the first option (kg, Sunday) is at the right.
- The outer corners and the shared borders use logical classes (
rounded-s-md,rounded-e-md,border-s). Upstream shadcn used physicalleft/rightclasses, which put the rounded corners on the wrong side in RTL; that is fixed here (Q6). - Arrow-key order reverses with the direction.
Tokens used
Read from components/ui/toggle-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 |
|---|
- Layer
z-(--z-raised) - Radius
rounded-md rounded-s-md rounded-e-md - Radius
rounded-none - Shadow
shadow-xs
Props
<ToggleGroup>
Also takes every prop of Radix ToggleGroup.Root
| Prop | Type | Default |
|---|---|---|
| spacing? | number | 0 |
<ToggleGroupItem>
Also takes every prop of Radix ToggleGroup.Item
No props of its own.
Replaces in coach-admin
From the read-only audit of coach-admin: 7 style values, 7 uses.
The SC Pay payouts page draws its own segmented control (.scpay-segment, with an --active modifier). Unit and view switches elsewhere are built from buttons or tabs and are found under Button and Tabs.
Classes and selectors
.scpay-segment4.scpay-segment__option2.scpay-segment__option--active1
SCSS variables in these styles
$scpay-neutral-bg→--muted$scpay-control-heightnot a color: spacing, size or layout$scpay-overlay-shadownot a color: spacing, size or layout