Skip to content
Components

ToggleGroup

A named group of toggle buttons for one optional choice or several independent options. Arrow keys move focus without changing selection.

Preview

Props

  • variant
  • size
  • disabled
  • iconOnly
  • type
  • orientation
  • dir
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"

<ToggleGroup type="single" defaultValue="left" aria-label="Text alignment">
  <ToggleGroupItem value="left">Left</ToggleGroupItem>
  <ToggleGroupItem value="center">Center</ToggleGroupItem>
  <ToggleGroupItem value="right">Right</ToggleGroupItem>
</ToggleGroup>

Usage

When to use

  • Pick one or several related toolbar options, such as alignment or text formatting.
  • Keep a compact set of choices together with arrow-key navigation.

When not to use

  • One choice must always remain selected. Use RadioGroup.
  • Switching between content panels. Use Tabs.
  • A single independent option. Use Toggle.

Variants

variant

Transparent when off, or a surface with a neutral border for outline.

  • defaultdefault

  • outline

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

<ToggleGroup type="single" defaultValue="left" aria-label="Text alignment">
  <ToggleGroupItem value="left">Left</ToggleGroupItem>
  <ToggleGroupItem value="center">Center</ToggleGroupItem>
  <ToggleGroupItem value="right">Right</ToggleGroupItem>
</ToggleGroup>
<ToggleGroup variant="outline" type="single" defaultValue="left" aria-label="Text alignment">
  <ToggleGroupItem value="left">Left</ToggleGroupItem>
  <ToggleGroupItem value="center">Center</ToggleGroupItem>
  <ToggleGroupItem value="right">Right</ToggleGroupItem>
</ToggleGroup>

size

Control height, text and icon size, the same steps as Button: sm 28px, md 32px (the default), lg 36px, xl 44px with a mouse; on touch md is 36px, lg 44px and xl 48px. Small controls keep a minimum hit area.

  • sm

  • mddefault

  • lg

  • xl

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

<ToggleGroup size="sm" type="single" defaultValue="left" aria-label="Text alignment">
  <ToggleGroupItem value="left">Left</ToggleGroupItem>
  <ToggleGroupItem value="center">Center</ToggleGroupItem>
  <ToggleGroupItem value="right">Right</ToggleGroupItem>
</ToggleGroup>
<ToggleGroup type="single" defaultValue="left" aria-label="Text alignment">
  <ToggleGroupItem value="left">Left</ToggleGroupItem>
  <ToggleGroupItem value="center">Center</ToggleGroupItem>
  <ToggleGroupItem value="right">Right</ToggleGroupItem>
</ToggleGroup>
<ToggleGroup size="lg" type="single" defaultValue="left" aria-label="Text alignment">
  <ToggleGroupItem value="left">Left</ToggleGroupItem>
  <ToggleGroupItem value="center">Center</ToggleGroupItem>
  <ToggleGroupItem value="right">Right</ToggleGroupItem>
</ToggleGroup>
<ToggleGroup size="xl" type="single" defaultValue="left" aria-label="Text alignment">
  <ToggleGroupItem value="left">Left</ToggleGroupItem>
  <ToggleGroupItem value="center">Center</ToggleGroupItem>
  <ToggleGroupItem value="right">Right</ToggleGroupItem>
</ToggleGroup>

orientation

Controls layout and the arrow keys used for navigation.

  • horizontaldefault

  • vertical

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

<ToggleGroup type="single" defaultValue="left" aria-label="Text alignment">
  <ToggleGroupItem value="left">Left</ToggleGroupItem>
  <ToggleGroupItem value="center">Center</ToggleGroupItem>
  <ToggleGroupItem value="right">Right</ToggleGroupItem>
</ToggleGroup>
<ToggleGroup orientation="vertical" type="single" defaultValue="left" aria-label="Text alignment">
  <ToggleGroupItem value="left">Left</ToggleGroupItem>
  <ToggleGroupItem value="center">Center</ToggleGroupItem>
  <ToggleGroupItem value="right">Right</ToggleGroupItem>
</ToggleGroup>

Examples

Optional alignment

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

<ToggleGroup type="single" aria-label="Text alignment" defaultValue="left">
  <ToggleGroupItem value="left">Left</ToggleGroupItem>
  <ToggleGroupItem value="center">Center</ToggleGroupItem>
  <ToggleGroupItem value="right">Right</ToggleGroupItem>
</ToggleGroup>

Independent formatting

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

<ToggleGroup type="multiple" aria-label="Text formatting" defaultValue={["bold"]}>
  <ToggleGroupItem value="bold">Bold</ToggleGroupItem>
  <ToggleGroupItem value="italic">Italic</ToggleGroupItem>
</ToggleGroup>

Vertical view choices

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

<ToggleGroup type="single" aria-label="View" orientation="vertical" variant="outline">
  <ToggleGroupItem value="grid">Grid</ToggleGroupItem>
  <ToggleGroupItem value="list">List</ToggleGroupItem>
</ToggleGroup>

Do and don't

Do

  • Name the group and keep each item label stable.
  • Use single for an optional view choice and multiple for independent formatting options.

Don't

  • Do not use single when exactly one choice must remain; use RadioGroup.
  • Do not repeat item values within a group.

Props

NameTypeValuesDefaultDescription
variantenumdefault | outlinedefaultTransparent when off, or a surface with a neutral border for outline.
sizeenumsm | md | lg | xlmdControl height, text and icon size, the same steps as Button: sm 28px, md 32px (the default), lg 36px, xl 44px with a mouse; on touch md is 36px, lg 44px and xl 48px. Small controls keep a minimum hit area.
disabledboolean-falsePrevents focus and selection and uses disabled colors.
iconOnlyboolean-falseSet on ToggleGroupItem. Makes the item square. Requires aria-label on an icon-only item.
type requiredenumsingle | multiple-single takes string values and permits deselection. multiple takes string arrays.
valuenode--Controlled selection: a string for single or a string array for multiple. Every item requires its own unique value.
defaultValuenode--Initial selection when uncontrolled: a string for single or a string array for multiple.
onValueChangefunction--Receives a string for single or a string array for multiple. Clearing single selection reports an empty string.
orientationenumhorizontal | verticalhorizontalControls layout and the arrow keys used for navigation.
direnumltr | rtlltrText direction, inherited when omitted. RTL reverses horizontal arrows.
loopboolean-trueWraps arrow navigation at either end when true.

Anatomy

PartDescription
rootThe toggle button, transparent by default or a bordered surface in outline. On uses the soft accent pair.
iconAn optional decorative icon, 16px in sm, md and lg and 20px in xl.
hitAreaA transparent pseudo-element that extends the button target to size-target-min.
wrapperThe named group with token spacing, horizontal by default and vertical when requested.

Accessibility

Role: radiogroup (single), toolbar (multiple)

KeysAction
TabEnters the group at one item, then leaves the group.
ArrowLeft, ArrowRightMoves focus in a horizontal group, skips disabled items, and respects text direction.
ArrowUp, ArrowDownMoves focus in a vertical group and skips disabled items.
Home, EndMoves focus to the first or last enabled item.
Space, EnterToggles the focused item.
  • A group requires aria-label or aria-labelledby.
  • Single items expose role="radio" and aria-checked. Multiple items expose aria-pressed.
  • Pressing a selected single item clears selection. Use RadioGroup when a choice must remain selected.
  • Items require unique non-empty value strings. Icon-only items require aria-label.
  • Group size and variant are item defaults. An item can override either default.
  • Arrow keys move focus; they do not select. loop defaults to true.

Install

npx shadcn add https://werewolf-ui.vercel.app/r/toggle-group.json

This also adds styles/werewolf.css, the tokens every component uses, and any other component it needs. Import that file once in your root CSS, after @import "tailwindcss", with a path relative to that CSS file (from app/globals.css it is @import "../styles/werewolf.css").