Skip to content
garn

Toggle Group

A group of toggle buttons acting as one single- or multi-select control.

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

Default

Multi-select formatting toolbar.

Appearance

Fill treatment, shared with the items via context; `outline` gives each item a bordered surface.

Ghost

Outline

Sizing

Item height rung (--garn-control-h-*), applied to every item via context.

Spacing

The same control rendered across garn's density modes — compact, default, and spacious.

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 toggle-group
First time? Set up garn in your project
Registry
toggle-group
Deps
@radix-ui/react-toggle-groupclass-variance-authority
Registry deps
toggleutils

Import

import { ToggleGroup, ToggleGroupItem } from "@garn/ui/toggle-group";

Anatomy

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

ToggleGroupRequired[data-slot="toggle-group"]

Root — sets type (single | multiple), owns value, and shares appearance/size to items via context.

ToggleGroupItemRequired[data-slot="toggle-group-item"]

One toggle in the group; needs a unique value. Inherits appearance/size from the group.

Props

The component's public props and their types.

appearance
Description
No description.
Type
"ghost" | "outline"
Default
ghost
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="toggle-group"]

States

SelectorState
[data-state=on]on
[data-state=off]off
[disabled]disabled
PropertyTokenTier
itemHeight--garn-control-h-mdsemantic · air
ring--garn-ringbrandablesemantic

When to use

Group related toggles into one control — a segmented single-choice selector or a multi-select toolbar (alignment, formatting marks).

Reach for something else when

  • One independent on/off (use toggle)
  • a single instant setting (use switch)
  • a long list (use select)
  • a few exclusive choices in a form (use radio-group)
  • switching between views (use tabs).

Overview

ToggleGroup binds related toggles into one control — a segmented single-choice selector or a multi-select toolbar (text alignment, formatting marks). ToggleGroup sets type (single for a segmented pick-one, multiple for independent toggles), owns the value, and shares appearance/size to each ToggleGroupItem. Use it for a compact set of visual, button-style options; for a labelled form choice use RadioGroup (one) or Checkboxes (several), and for a single toggle use Toggle.

Guidelines

Pick single vs multiple to match the choice. single is a segmented control (exactly one active — alignment); multiple is independent toggles (bold + italic together). Choosing the wrong type confuses what selection means.

Keep it small, labelled, and even. It works for a handful of peer options shown at once; a long list belongs in a Select. Give each item an accessible name (icon-only items especially) and a consistent size/appearance across the group.

Use it for visual options, not form fields. When the choice is a labelled field in a form, RadioGroup/Checkbox communicate intent better. Preserve the roving-focus keyboard model and make the active state clear beyond color alone.

Best practices

Do
  • Set type="single" for one-of-N, type="multiple" for many-of-N.
  • Set appearance/size on the group — items inherit them via context.
  • Label the group, and give each item (often icon-only) an aria-label and a unique value.
Don't
  • Don't mix unrelated actions into one group.
  • Don't leave the group or its icon-only items unlabeled.
  • Don't use it to navigate between pages (use tabs/links).

Content guidelines

  • Use short, parallel item labels, or clear icons with aria-labels (“Left / Center / Right”).
  • Keep the set small and related; a long list of choices belongs in a select.
  • Name the group with an aria-label that says what the toggles control.

Troubleshooting

TypeScript error or nothing selects.

Cause. type is required on the group, and each ToggleGroupItem needs a unique value.

Fix. Set type="single" or type="multiple", and give every item a unique value.

An item's appearance/size doesn't match the group.

Cause. appearance/size are set on the group and shared via context; per-item values are overridden by the group's.

Fix. Set appearance/size on the ToggleGroup, not on individual items.

Accessibility

Role
group

Accessibility requirements

warn

Label the group and each icon-only item (aria-label on the group and on each item).

when the group has no accessible name (aria-label / aria-labelledby) and its items are icon-only

Keyboard

TabMove focus into the group (roving tabindex).
ArrowLeftArrowRightArrowUpArrowDownMove between items in the group.
EnterSpaceToggle the focused item.
A1.3.1Info and RelationshipsA2.1.1KeyboardA4.1.2Name, Role, Value
  • The group is a single tab stop with roving focus across items.
  • Label the group (aria-label / aria-labelledby) and give each icon-only item its own aria-label.
  • `type="single"` behaves like a radio set; `type="multiple"` like a set of independent toggles.