Skip to content

Toggle Group

Stable

A set of toggle buttons for choosing one option — or several — from a small, visible set.

Anatomy

  1. 1GroupOne control and one tab stop: arrow keys move between items, Tab moves on. It sets the variant, size and spacing for every item.
  2. 2Pressed itemSelected options take the pressed fill and report aria-pressed. A group can require one choice or allow several.
  3. 3ItemA toggle button. Icon-only items need an aria-label, like any icon button.

Installation

$ pnpm dlx shadcn@latest add https://www.prfct.dev/r/toggle-group.json

Usage

import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
<ToggleGroup defaultValue={["left"]} aria-label="Text alignment">
  <ToggleGroupItem value="left" aria-label="Align left">
    <AlignLeftIcon />
  </ToggleGroupItem>
  <ToggleGroupItem value="center" aria-label="Align center">
    <AlignCenterIcon />
  </ToggleGroupItem>
</ToggleGroup>

The value is always an array of the pressed items' values — ["left"] for a single choice, ["bold", "italic"] for several.

Examples

Multiple

Add multiple to let any number of items be pressed at once, as in a formatting toolbar.

Segmented

spacing={0} with the outline variant fuses the items into one control with shared borders — a segmented control for switching between a few views of the same content.

View switcher

In a single-choice group, pressing the active item again unpresses it and leaves nothing selected. When one option must always be active, control the value and ignore empty updates.

Projects
  • Atlas
  • Beacon
  • Cinder
  • Delta
const [view, setView] = React.useState("grid")

<ToggleGroup
  value={[view]}
  onValueChange={(value) => value.length > 0 && setView(value[0])}
  aria-label="View"
>

</ToggleGroup>

Vertical

orientation="vertical" stacks the items and switches keyboard navigation to the up and down arrows — the layout of a tool palette.

Sizes

size applies to every item: sm 32, default 36, lg 40.

Guidelines

When to use

  • To switch between two to five views or modes of the same content: Day · Week · Month, grid or list.
  • For toolbars with related options, single-choice (alignment) or multiple-choice (text style).

When not to use

  • For choices inside a form that is submitted later — use a Radio Group, which reads as a form field and supports descriptions.
  • For more than five or six options, or long labels — use a Select.
  • For unrelated actions — use a Button Group. A toggle group implies a shared state.
  • For switching between views that each have their own panel — use Tabs. For navigating between pages, use links.

Keep labels short and parallel

Segments should be the same kind of thing and roughly the same length, so the control reads as a set. Icons work well in toolbars; words work better for modes.

Do.Short, parallel options of the same kind.
Don’t.Mixed lengths and an action among options — it no longer reads as one choice.

Accessibility

  • The group renders role="group"; name it with aria-label or aria-labelledby pointing at a visible label.
  • Each item is a toggle button with aria-pressed. Icon-only items need an aria-label.
  • The group is a single tab stop with roving focus: Tab enters it, arrow keys move between items, and focus wraps around at the ends (loopFocus).
KeyBehavior
Tab
Moves focus into the group; press again to leave it.
Moves focus to the next item (down in vertical groups).
Moves focus to the previous item (up in vertical groups).
SpaceEnter
Presses or unpresses the focused item.

API reference

ToggleGroup

Renders a <div> with role="group". Accepts every prop of Base UI's Toggle Group.

PropTypeDefault
value

The pressed items' values. The controlled counterpart of defaultValue.

string[]No default
defaultValue

The initially pressed items when uncontrolled.

string[]No default
onValueChange

Called when the pressed items change.

(value: string[], eventDetails) => voidNo default
multiple

Allows more than one item to be pressed.

booleanfalse
variant

Applied to every item.

"default" | "outline"No default
size

Applied to every item.

"sm" | "default" | "lg"No default
spacing

Gap between items in spacing units. 0 fuses the items into one control.

number1
orientation

Layout direction and arrow-key axis.

"horizontal" | "vertical""horizontal"
loopFocus

Wraps keyboard focus from the last item to the first.

booleantrue
disabled

Disables every item.

booleanfalse

ToggleGroupItem

A Toggle that reports its value to the group. Renders a <button>.

PropTypeDefault
valuerequired

Identifies the item in the group's value array.

stringNo default
disabled

Disables this item only.

booleanfalse
variant

Used when the group doesn't set one.

"default" | "outline""default"
size

Used when the group doesn't set one.

"sm" | "default" | "lg""default"