For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to any URL or sending an Accept: text/markdown header. An agent skill is available at /.well-known/agent-skills/site-skill.md.
Home

Toggle Group

A set of toggle buttons with shared variant and size, supporting single or multiple selection.

import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon, BoldIcon, ItalicIcon, StretchHorizontalIcon, UnderlineIcon } from "lucide-react";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";

export const ToggleGroupDemo = () => (
    <div className="flex flex-col gap-6">
      {/* Single selection — text alignment */}
      <ToggleGroup type="single" defaultValue="left">
        <ToggleGroupItem value="left" aria-label="Align left"><AlignLeftIcon /></ToggleGroupItem>
        <ToggleGroupItem value="center" aria-label="Align center"><AlignCenterIcon /></ToggleGroupItem>
        <ToggleGroupItem value="right" aria-label="Align right"><AlignRightIcon /></ToggleGroupItem>
        <ToggleGroupItem value="justify" aria-label="Justify"><AlignJustifyIcon /></ToggleGroupItem>
      </ToggleGroup>
      {/* Multiple selection — text formatting */}
      <ToggleGroup type="multiple" defaultValue={["bold"]}>
        <ToggleGroupItem value="bold" aria-label="Bold"><BoldIcon /></ToggleGroupItem>
        <ToggleGroupItem value="italic" aria-label="Italic"><ItalicIcon /></ToggleGroupItem>
        <ToggleGroupItem value="underline" aria-label="Underline"><UnderlineIcon /></ToggleGroupItem>
      </ToggleGroup>
      {/* Outline variant */}
      <ToggleGroup type="single" variant="outline" defaultValue="md">
        <ToggleGroupItem value="sm">S</ToggleGroupItem>
        <ToggleGroupItem value="md">M</ToggleGroupItem>
        <ToggleGroupItem value="lg">L</ToggleGroupItem>
        <ToggleGroupItem value="xl">XL</ToggleGroupItem>
      </ToggleGroup>
      {/* Small size */}
      <ToggleGroup type="single" size="sm" defaultValue="horizontal">
        <ToggleGroupItem value="horizontal" aria-label="Horizontal">
          <StretchHorizontalIcon />
          Horizontal
        </ToggleGroupItem>
        <ToggleGroupItem value="vertical" aria-label="Vertical">
          <StretchHorizontalIcon className="rotate-90" />
          Vertical
        </ToggleGroupItem>
      </ToggleGroup>
      {/* Disabled */}
      <ToggleGroup type="single" defaultValue="a" disabled>
        <ToggleGroupItem value="a">Option A</ToggleGroupItem>
        <ToggleGroupItem value="b">Option B</ToggleGroupItem>
        <ToggleGroupItem value="c">Option C</ToggleGroupItem>
      </ToggleGroup>
    </div>
  );

Single vs multiple

type="single" allows at most one item pressed at a time. type="multiple" allows any combination.

<ToggleGroup type="single" defaultValue="center">…</ToggleGroup>
<ToggleGroup type="multiple" defaultValue={["bold", "italic"]}>…</ToggleGroup>

Variants

Set variant on ToggleGroup — all items inherit it via context. Override per-item if needed.

<ToggleGroup type="single" variant="outline">
  <ToggleGroupItem value="a">A</ToggleGroupItem>
  <ToggleGroupItem value="b">B</ToggleGroupItem>
</ToggleGroup>

Available variants: default · outline · ghost · secondary

Sizes

<ToggleGroup type="single" size="sm">…</ToggleGroup>
<ToggleGroup type="single" size="lg">…</ToggleGroup>

Available sizes: sm · default · lg · icon · icon-sm

Controlled

const [value, setValue] = useState("left");
 
<ToggleGroup type="single" value={value} onValueChange={setValue}>
  <ToggleGroupItem value="left"><AlignLeftIcon /></ToggleGroupItem>
  <ToggleGroupItem value="right"><AlignRightIcon /></ToggleGroupItem>
</ToggleGroup>

Props

ToggleGroup

PropTypeDefaultDescription
type"single" | "multiple"—Selection mode (required)
valuestring | string[]—Controlled pressed value(s)
defaultValuestring | string[]—Uncontrolled initial value(s)
onValueChange(value) => void—Callback on change
variant"default" | "outline" | "ghost" | "secondary""default"Passed to all items via context
size"sm" | "default" | "lg" | "icon" | "icon-sm""default"Passed to all items via context
disabledbooleanfalseDisables all items

ToggleGroupItem

PropTypeDefaultDescription
valuestring—Item identifier (required)
variantVariantProps—Per-item override of group variant
sizeVariantProps—Per-item override of group size
disabledbooleanfalseDisables this item only

Usage

import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
 
<ToggleGroup type="single" defaultValue="left">
  <ToggleGroupItem value="left" aria-label="Align left">
    <AlignLeftIcon />
  </ToggleGroupItem>
  <ToggleGroupItem value="center" aria-label="Align center">
    <AlignCenterIcon />
  </ToggleGroupItem>
  <ToggleGroupItem value="right" aria-label="Align right">
    <AlignRightIcon />
  </ToggleGroupItem>
</ToggleGroup>

Specs

# Mint — Toggle Group Specs
 
## Component
- name: toggle-group
- file: registry/mint/toggle-group.tsx
- installs to: components/ui/toggle-group.tsx
- dependencies: radix-ui, class-variance-authority
- registryDependencies: toggle
 
## What is it
A compound component that renders a Radix ToggleGroup root with one or more
toggle items sharing the same variant and size. Use it for mutually-exclusive
or multi-select toolbar controls such as alignment, formatting, or view mode.
Prefer ToggleGroup over a set of independent Toggles when items belong to a
single logical choice set.
 
## Visual identity
Items sit flush in a horizontal flex row with a 4px gap. Each item inherits
Mint's rounded-md radius and the Toggle's soft, low-chrome look — transparent
by default, tinted mint-green only when pressed.
 
## Design tokens
--muted: oklch(0.96 0.02 155) / oklch(0.2 0.03 155)               — hover background (default variant)
--muted-foreground: oklch(0.52 0.06 155) / oklch(0.6 0.06 155)   — hover text (default variant)
--accent: oklch(0.92 0.05 155) / oklch(0.26 0.05 155)               — pressed background
--accent-foreground: oklch(0.32 0.1 155) / oklch(0.88 0.06 155)   — pressed text
--secondary: oklch(0.95 0.04 155) / oklch(0.22 0.04 155)            — secondary variant fill
--secondary-foreground: oklch(0.32 0.1 155) / oklch(0.88 0.06 155)
--input: oklch(0.88 0.04 155 / 60%) / oklch(0.32 0.05 155 / 40%)             — outline variant border
--ring: oklch(0.5 0.14 155) / oklch(0.62 0.15 155)                — focus ring
--destructive: oklch(0.55 0.25 15) / oklch(0.704 0.191 22.216) — aria-invalid ring
 
## Sub-components
- ToggleGroup     → Radix ToggleGroup.Root; renders flex items-center gap-1; publishes ToggleGroupContext with { variant, size }
- ToggleGroupItem → Radix ToggleGroup.Item; consumes context; applies toggleVariants(); per-item variant/size overrides context values
 
## Variants
- default   → transparent background; accent fill when pressed. Primary toolbar button style.
- outline   → transparent with border-input border and shadow-xs; accent on hover/press. Structured, form-adjacent toggles.
- ghost     → no border; accent/50 on hover (dark); accent/80 when pressed. Minimal, unobtrusive toolbar items.
- secondary → secondary fill at rest; secondary/80 on hover; secondary/60 when pressed. Softer prominence than default.
 
## States
- hover:             bg-muted + text-muted-foreground (default/outline); bg-accent + text-accent-foreground (ghost/outline hover)
- data-[state=on]:   bg-accent + text-accent-foreground; ghost uses bg-accent/80
- focus-visible:     border-ring + ring-[3px] ring-ring/50
- disabled:          opacity-50 + pointer-events-none; set on ToggleGroup to disable all items, or on ToggleGroupItem for a single item
- aria-invalid:      border-destructive + ring-destructive/20 (ring-destructive/40 dark)
 
## Conventions
- Set variant and size on ToggleGroup once — all items inherit via context; override per-item only when intentional
- Icon-only items require aria-label on each ToggleGroupItem for accessibility
- Use type="single" for mutually exclusive selections (alignment, view mode); type="multiple" for independent toggles (bold + italic)
- Items render with min-w-0 to allow text truncation in constrained layouts
- Sub-components expose data-slot="toggle-group" and data-slot="toggle-group-item" for CSS targeting
- sounds / haptic: ToggleGroup itself does not call useFeedback; sound feedback is handled by the underlying Toggle component (toggleOn / toggleOff) when Toggle is used standalone — ToggleGroupItem does not fire sounds

Installation

GIN Design Plugin
$ npx shadcn add https://gin-design.vercel.app/toggle-group