---
import Bold from "@lucide/astro/icons/bold"
import Italic from "@lucide/astro/icons/italic"
import Underline from "@lucide/astro/icons/underline"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
---
<ToggleGroup variant="outline" multiple>
<ToggleGroupItem value="bold" aria-label="Toggle bold">
<Bold />
</ToggleGroupItem>
<ToggleGroupItem value="italic" aria-label="Toggle italic">
<Italic />
</ToggleGroupItem>
<ToggleGroupItem value="strikethrough" aria-label="Toggle strikethrough">
<Underline />
</ToggleGroupItem>
</ToggleGroup>Installation
npx shadcn@latest add @fulldev/toggle-group
Usage
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
<ToggleGroup defaultValue="a">
<ToggleGroupItem value="a">A</ToggleGroupItem>
<ToggleGroupItem value="b">B</ToggleGroupItem>
<ToggleGroupItem value="c">C</ToggleGroupItem>
</ToggleGroup>
Composition
ToggleGroup
├── ToggleGroupItem
└── ToggleGroupItem
Outline
Use variant="outline" for an outline style.
---
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
---
<ToggleGroup variant="outline" defaultValue={["all"]}>
<ToggleGroupItem value="all" aria-label="Toggle all">
All
</ToggleGroupItem>
<ToggleGroupItem value="missed" aria-label="Toggle missed">
Missed
</ToggleGroupItem>
</ToggleGroup>Size
Use the size prop to change the size of the toggle group.
---
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
---
<div class="flex flex-col gap-4">
<ToggleGroup size="sm" defaultValue={["top"]} variant="outline">
<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 defaultValue={["top"]} variant="outline">
<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 spacing to set the gap between items. The default is 2; use
spacing={0} for connected items.
---
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
---
<ToggleGroup size="sm" defaultValue={["top"]} variant="outline" 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 vertical toggle groups. Arrow keys follow the
orientation.
---
import BoldIcon from "@lucide/astro/icons/bold"
import ItalicIcon from "@lucide/astro/icons/italic"
import UnderlineIcon from "@lucide/astro/icons/underline"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
---
<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 Bold from "@lucide/astro/icons/bold"
import Italic from "@lucide/astro/icons/italic"
import Underline from "@lucide/astro/icons/underline"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
---
<ToggleGroup disabled>
<ToggleGroupItem value="bold" aria-label="Toggle bold">
<Bold />
</ToggleGroupItem>
<ToggleGroupItem value="italic" aria-label="Toggle italic">
<Italic />
</ToggleGroupItem>
<ToggleGroupItem value="strikethrough" aria-label="Toggle strikethrough">
<Underline />
</ToggleGroupItem>
</ToggleGroup>Custom
A custom toggle group that shows the selected value through the
toggle-group:change event.
Use font-normal
to set the font weight.
---
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
const fontWeight = "normal"
---
<Field data-font-weight-selector>
<FieldLabel>Font Weight</FieldLabel>
<ToggleGroup
defaultValue={[fontWeight]}
variant="outline"
spacing={2}
size="lg"
>
<ToggleGroupItem
value="light"
aria-label="Light"
class="flex size-16 flex-col items-center justify-center rounded-xl"
>
<span class="text-2xl leading-none font-light">Aa</span>
<span class="text-xs text-muted-foreground">Light</span>
</ToggleGroupItem>
<ToggleGroupItem
value="normal"
aria-label="Normal"
class="flex size-16 flex-col items-center justify-center rounded-xl"
>
<span class="text-2xl leading-none font-normal">Aa</span>
<span class="text-xs text-muted-foreground">Normal</span>
</ToggleGroupItem>
<ToggleGroupItem
value="medium"
aria-label="Medium"
class="flex size-16 flex-col items-center justify-center rounded-xl"
>
<span class="text-2xl leading-none font-medium">Aa</span>
<span class="text-xs text-muted-foreground">Medium</span>
</ToggleGroupItem>
<ToggleGroupItem
value="bold"
aria-label="Bold"
class="flex size-16 flex-col items-center justify-center rounded-xl"
>
<span class="text-2xl leading-none font-bold">Aa</span>
<span class="text-xs text-muted-foreground">Bold</span>
</ToggleGroupItem>
</ToggleGroup>
<FieldDescription>
Use{" "}
<code
class="rounded-md bg-muted px-1 py-0.5 font-mono"
data-font-weight-class
>
font-{fontWeight}
</code>{" "}
to set the font weight.
</FieldDescription>
</Field>
<script>
const initialize = () => {
for (const root of document.querySelectorAll(
"[data-font-weight-selector]"
)) {
if (root.hasAttribute("data-bound")) continue
root.setAttribute("data-bound", "")
const output = root.querySelector("[data-font-weight-class]")
root
.querySelector('[data-slot="toggle-group"]')
?.addEventListener("toggle-group:change", (event) => {
const { value } = (event as CustomEvent<{ value: string[] }>).detail
if (output) output.textContent = `font-${value[0] ?? ""}`
})
}
}
initialize()
document.addEventListener("astro:page-load", initialize)
</script>RTL
Set dir="rtl" on the group or a parent element.
---
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
const 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: "כרטיסים",
},
},
} as const
const { dir, values: t } = translations.ar
---
<ToggleGroup variant="outline" 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>API Reference
Source: src/components/ui/toggle-group
ToggleGroup
| Prop | Type | Default | Description |
|---|---|---|---|
defaultValue | string | string[] | [] | Initial selected value or values. |
multiple | boolean | false | Allows multiple selected items. |
orientation | "horizontal" | "vertical" | "horizontal" | Sets arrow-key navigation direction. |
loop | boolean | true | Wraps keyboard focus at either end. |
disabled | boolean | false | Blocks interaction for the whole group. |
variant | "default" | "outline" | item default | Applies a visual variant to every item. |
size | "sm" | "default" | "lg" | item default | Applies a size to every item. |
spacing | number | 2 | Gap between items in Tailwind spacing units. |
ToggleGroupItem
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | required | Unique value for the item. |
disabled | boolean | false | Disables the item. |
variant | "default" | "outline" | "default" | Item variant when the group does not set one. |
size | "sm" | "default" | "lg" | "default" | Item size when the group does not set one. |
The root emits toggle-group:change with { value: string[] }. Dispatch
toggle-group:set with { value: string | string[] } to update it from client
code. See the data-slot docs
for controller methods and full keyboard behavior.