Components
- Accordion
- Alert
- Alert Dialog
- Aspect Ratio
- Attachment
- Avatar
- Badge
- Breadcrumb
- Bubble
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Collapsible
- Combobox
- Command
- Context Menu
- Date Picker
- Dialog
- Drawer
- Dropdown Menu
- Empty
- Field
- Hover Card
- Input
- Input OTP
- Input Group
- Item
- Kbd
- Label
- Marker
- Menubar
- Message
- Message Scroller
- Native Select
- Navigation Menu
- Pagination
- Popover
- Progress
- Radio Group
- Resizable
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Spinner
- Switch
- Table
- Tabs
- Textarea
- Toggle
- Toggle Group
- Tooltip
- New Component
Elements
Charts
Icons
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
| Prop | Type | Default | Description |
|---|---|---|---|
type | "single" | "multiple" | — | Selection mode (required) |
value | string | string[] | — | Controlled pressed value(s) |
defaultValue | string | 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 |
disabled | boolean | false | Disables all items |
ToggleGroupItem
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Item identifier (required) |
variant | VariantProps | — | Per-item override of group variant |
size | VariantProps | — | Per-item override of group size |
disabled | boolean | false | Disables 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 soundsInstallation
$ npx shadcn add \https://gin-design.vercel.app/toggle-group