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 @herocn/toggle-group

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

Ghost

Use variant="ghost" for a ghost style.

import { BoldIcon, ItalicIcon, UnderlineIcon } from "lucide-react";
import {	ToggleGroup,	ToggleGroupItem,} from "@/components/ui/toggle-group";
export function ToggleGroupVariants() {	return (		<ToggleGroup spacing={1} variant="ghost" defaultValue={["bold"]}>			<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>	);}

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