Github

Toggle Group

A set of two-state buttons that can be toggled on or off.

import { BoldIcon, ItalicIcon, UnderlineIcon } from "lucide-react";

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

export function ToggleGroupDemo() {
	return (
		<ToggleGroup multiple>
			<ToggleGroupItem value="bold" aria-label="Toggle bold">
				<BoldIcon />
			</ToggleGroupItem>
			<ToggleGroupItem value="italic" aria-label="Toggle italic">
				<ItalicIcon />
			</ToggleGroupItem>
			<ToggleGroupItem value="underline" aria-label="Toggle underline">
				<UnderlineIcon />
			</ToggleGroupItem>
		</ToggleGroup>
	);
}

Installation

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

Usage

import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
<ToggleGroup>
  <ToggleGroupItem value="a">A</ToggleGroupItem>
  <ToggleGroupItem value="b">B</ToggleGroupItem>
  <ToggleGroupItem value="c">C</ToggleGroupItem>
</ToggleGroup>

Composition

Use the following composition to build a ToggleGroup:

ToggleGroup
├── ToggleGroupItem
└── ToggleGroupItem

Examples

Sizes

Use the size prop to change the size of the toggle group items.

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

export function ToggleGroupSizes() {
	return (
		<div className="flex flex-col items-start gap-4">
			<ToggleGroup size="sm" defaultValue={["top"]}>
				<ToggleGroupItem value="top" aria-label="Toggle top">
					Top
				</ToggleGroupItem>
				<ToggleGroupItem value="bottom" aria-label="Toggle bottom">
					Bottom
				</ToggleGroupItem>
				<ToggleGroupItem value="left" aria-label="Toggle left">
					Left
				</ToggleGroupItem>
				<ToggleGroupItem value="right" aria-label="Toggle right">
					Right
				</ToggleGroupItem>
			</ToggleGroup>
			<ToggleGroup size="default" defaultValue={["top"]}>
				<ToggleGroupItem value="top" aria-label="Toggle top">
					Top
				</ToggleGroupItem>
				<ToggleGroupItem value="bottom" aria-label="Toggle bottom">
					Bottom
				</ToggleGroupItem>
				<ToggleGroupItem value="left" aria-label="Toggle left">
					Left
				</ToggleGroupItem>
				<ToggleGroupItem value="right" aria-label="Toggle right">
					Right
				</ToggleGroupItem>
			</ToggleGroup>
			<ToggleGroup size="lg" defaultValue={["top"]}>
				<ToggleGroupItem value="top" aria-label="Toggle top">
					Top
				</ToggleGroupItem>
				<ToggleGroupItem value="bottom" aria-label="Toggle bottom">
					Bottom
				</ToggleGroupItem>
				<ToggleGroupItem value="left" aria-label="Toggle left">
					Left
				</ToggleGroupItem>
				<ToggleGroupItem value="right" aria-label="Toggle right">
					Right
				</ToggleGroupItem>
			</ToggleGroup>
		</div>
	);
}

Spacing

Use the spacing prop to add gaps between toggle group items.

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

export function ToggleGroupSpacing() {
	return (
		<ToggleGroup defaultValue={["top"]} spacing={2}>
			<ToggleGroupItem value="top" aria-label="Toggle top">
				Top
			</ToggleGroupItem>
			<ToggleGroupItem value="bottom" aria-label="Toggle bottom">
				Bottom
			</ToggleGroupItem>
			<ToggleGroupItem value="left" aria-label="Toggle left">
				Left
			</ToggleGroupItem>
			<ToggleGroupItem value="right" aria-label="Toggle right">
				Right
			</ToggleGroupItem>
		</ToggleGroup>
	);
}

Vertical

Use orientation="vertical" for a vertically stacked toggle group.

import { BoldIcon, ItalicIcon, UnderlineIcon } from "lucide-react";

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

export function ToggleGroupVertical() {
	return (
		<ToggleGroup
			multiple
			orientation="vertical"
			spacing={1}
			defaultValue={["bold", "italic"]}
		>
			<ToggleGroupItem value="bold" aria-label="Toggle bold">
				<BoldIcon />
			</ToggleGroupItem>
			<ToggleGroupItem value="italic" aria-label="Toggle italic">
				<ItalicIcon />
			</ToggleGroupItem>
			<ToggleGroupItem value="underline" aria-label="Toggle underline">
				<UnderlineIcon />
			</ToggleGroupItem>
		</ToggleGroup>
	);
}

Disabled

import { BoldIcon, ItalicIcon, UnderlineIcon } from "lucide-react";

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

export function ToggleGroupDisabled() {
	return (
		<ToggleGroup multiple disabled>
			<ToggleGroupItem value="bold" aria-label="Toggle bold">
				<BoldIcon />
			</ToggleGroupItem>
			<ToggleGroupItem value="italic" aria-label="Toggle italic">
				<ItalicIcon />
			</ToggleGroupItem>
			<ToggleGroupItem value="underline" aria-label="Toggle underline">
				<UnderlineIcon />
			</ToggleGroupItem>
		</ToggleGroup>
	);
}

Custom

Use font-normal to set the font weight.

"use client";

import * as React from "react";

import {
	Field,
	FieldDescription,
	FieldLabel,
} from "@/components/ui/field";
import {
	ToggleGroup,
	ToggleGroupItem,
} from "@/components/ui/toggle-group";

export function ToggleGroupCustom() {
	const [fontWeight, setFontWeight] = React.useState("normal");

	return (
		<Field>
			<FieldLabel>Font Weight</FieldLabel>
			<ToggleGroup
				value={[fontWeight]}
				onValueChange={(value) => setFontWeight(value[0])}
				spacing={2}
				size="lg"
			>
				<ToggleGroupItem
					value="light"
					aria-label="Light"
					className="flex size-16 flex-col items-center justify-center rounded-xl"
				>
					<span className="font-light text-2xl leading-none">Aa</span>
					<span className="text-muted-foreground text-xs">Light</span>
				</ToggleGroupItem>
				<ToggleGroupItem
					value="normal"
					aria-label="Normal"
					className="flex size-16 flex-col items-center justify-center rounded-xl"
				>
					<span className="font-normal text-2xl leading-none">Aa</span>
					<span className="text-muted-foreground text-xs">Normal</span>
				</ToggleGroupItem>
				<ToggleGroupItem
					value="medium"
					aria-label="Medium"
					className="flex size-16 flex-col items-center justify-center rounded-xl"
				>
					<span className="font-medium text-2xl leading-none">Aa</span>
					<span className="text-muted-foreground text-xs">Medium</span>
				</ToggleGroupItem>
				<ToggleGroupItem
					value="bold"
					aria-label="Bold"
					className="flex size-16 flex-col items-center justify-center rounded-xl"
				>
					<span className="font-bold text-2xl leading-none">Aa</span>
					<span className="text-muted-foreground text-xs">Bold</span>
				</ToggleGroupItem>
			</ToggleGroup>
			<FieldDescription>
				Use{" "}
				<code className="rounded-md bg-muted px-1 py-0.5 font-mono">
					font-{fontWeight}
				</code>{" "}
				to set the font weight.
			</FieldDescription>
		</Field>
	);
}

RTL

"use client";

import {
	type Translations,
	useTranslation,
} from "@/components/language-selector";
import {
	ToggleGroup,
	ToggleGroupItem,
} from "@/components/ui/toggle-group";

const translations: Translations = {
	en: {
		dir: "ltr",
		values: {
			list: "List",
			grid: "Grid",
			cards: "Cards",
		},
	},
	ar: {
		dir: "rtl",
		values: {
			list: "قائمة",
			grid: "شبكة",
			cards: "بطاقات",
		},
	},
	he: {
		dir: "rtl",
		values: {
			list: "רשימה",
			grid: "רשת",
			cards: "כרטיסים",
		},
	},
};

export function ToggleGroupRtl() {
	const { dir, language, t } = useTranslation(translations, "ar");

	return (
		<div lang={language} dir={dir}>
			<ToggleGroup defaultValue={["list"]} dir={dir}>
				<ToggleGroupItem value="list" aria-label={t.list}>
					{t.list}
				</ToggleGroupItem>
				<ToggleGroupItem value="grid" aria-label={t.grid}>
					{t.grid}
				</ToggleGroupItem>
				<ToggleGroupItem value="cards" aria-label={t.cards}>
					{t.cards}
				</ToggleGroupItem>
			</ToggleGroup>
		</div>
	);
}

API Reference

ToggleGroup

PropTypeDefault

ToggleGroupItem

PropTypeDefault