8.0k New

Toggle Group

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

Docs API Reference

Epicenter

Local-first, open source apps

Special Sponsor
<script lang="ts">
  import BoldIcon from "@lucide/svelte/icons/bold";
  import ItalicIcon from "@lucide/svelte/icons/italic";
  import UnderlineIcon from "@lucide/svelte/icons/underline";
  import * as ToggleGroup from "$lib/components/ui/toggle-group/index.js";
</script>
 
<ToggleGroup.Root variant="outline" type="multiple">
  <ToggleGroup.Item value="bold" aria-label="Toggle bold">
    <BoldIcon />
  </ToggleGroup.Item>
  <ToggleGroup.Item value="italic" aria-label="Toggle italic">
    <ItalicIcon />
  </ToggleGroup.Item>
  <ToggleGroup.Item value="strikethrough" aria-label="Toggle strikethrough">
    <UnderlineIcon />
  </ToggleGroup.Item>
</ToggleGroup.Root>

Installation

pnpm dlx shadcn-svelte@latest add toggle-group

Usage

<script lang="ts">
  import * as ToggleGroup from "$lib/components/ui/toggle-group/index.js";
</script>
<ToggleGroup.Root type="single">
  <ToggleGroup.Item value="a">A</ToggleGroup.Item>
  <ToggleGroup.Item value="b">B</ToggleGroup.Item>
  <ToggleGroup.Item value="c">C</ToggleGroup.Item>
</ToggleGroup.Root>

Outline

Use variant="outline" for an outline style.

<script lang="ts">
  import * as ToggleGroup from "$lib/components/ui/toggle-group/index.js";
</script>
 
<ToggleGroup.Root variant="outline" type="single" value="all">
  <ToggleGroup.Item value="all" aria-label="Toggle all">All</ToggleGroup.Item>
  <ToggleGroup.Item value="missed" aria-label="Toggle missed"
    >Missed</ToggleGroup.Item
  >
</ToggleGroup.Root>

Size

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

<script lang="ts">
  import * as ToggleGroup from "$lib/components/ui/toggle-group/index.js";
 
  const sides = ["top", "bottom", "left", "right"] as const;
</script>
 
<div class="flex flex-col gap-4">
  <ToggleGroup.Root type="single" size="sm" value="top" variant="outline">
    {#each sides as side (side)}
      <ToggleGroup.Item
        value={side}
        aria-label="Toggle {side}"
        class="capitalize"
      >
        {side}
      </ToggleGroup.Item>
    {/each}
  </ToggleGroup.Root>
  <ToggleGroup.Root type="single" value="top" variant="outline">
    {#each sides as side (side)}
      <ToggleGroup.Item
        value={side}
        aria-label="Toggle {side}"
        class="capitalize"
      >
        {side}
      </ToggleGroup.Item>
    {/each}
  </ToggleGroup.Root>
</div>

Spacing

Use spacing to add spacing between toggle group items.

<script lang="ts">
  import * as ToggleGroup from "$lib/components/ui/toggle-group/index.js";
 
  const sides = ["top", "bottom", "left", "right"] as const;
</script>
 
<ToggleGroup.Root
  type="single"
  size="sm"
  value="top"
  variant="outline"
  spacing={2}
>
  {#each sides as side (side)}
    <ToggleGroup.Item
      value={side}
      aria-label="Toggle {side}"
      class="capitalize"
    >
      {side}
    </ToggleGroup.Item>
  {/each}
</ToggleGroup.Root>

Vertical

Use orientation="vertical" for vertical toggle groups.

<script lang="ts">
  import BoldIcon from "@lucide/svelte/icons/bold";
  import ItalicIcon from "@lucide/svelte/icons/italic";
  import UnderlineIcon from "@lucide/svelte/icons/underline";
  import * as ToggleGroup from "$lib/components/ui/toggle-group/index.js";
</script>
 
<ToggleGroup.Root
  type="multiple"
  orientation="vertical"
  spacing={1}
  value={["bold", "italic"]}
>
  <ToggleGroup.Item value="bold" aria-label="Toggle bold">
    <BoldIcon />
  </ToggleGroup.Item>
  <ToggleGroup.Item value="italic" aria-label="Toggle italic">
    <ItalicIcon />
  </ToggleGroup.Item>
  <ToggleGroup.Item value="underline" aria-label="Toggle underline">
    <UnderlineIcon />
  </ToggleGroup.Item>
</ToggleGroup.Root>

Disabled

<script lang="ts">
  import BoldIcon from "@lucide/svelte/icons/bold";
  import ItalicIcon from "@lucide/svelte/icons/italic";
  import UnderlineIcon from "@lucide/svelte/icons/underline";
  import * as ToggleGroup from "$lib/components/ui/toggle-group/index.js";
</script>
 
<ToggleGroup.Root disabled type="single">
  <ToggleGroup.Item value="bold" aria-label="Toggle bold">
    <BoldIcon />
  </ToggleGroup.Item>
  <ToggleGroup.Item value="italic" aria-label="Toggle italic">
    <ItalicIcon />
  </ToggleGroup.Item>
  <ToggleGroup.Item value="strikethrough" aria-label="Toggle strikethrough">
    <UnderlineIcon />
  </ToggleGroup.Item>
</ToggleGroup.Root>

Custom

A custom toggle group example.

Use font-normal to set the font weight.

<script lang="ts">
  import * as Field from "$lib/components/ui/field/index.js";
  import * as ToggleGroup from "$lib/components/ui/toggle-group/index.js";
 
  const weights = [
    { value: "light", label: "Light", class: "font-light" },
    { value: "normal", label: "Normal", class: "font-normal" },
    { value: "medium", label: "Medium", class: "font-medium" },
    { value: "bold", label: "Bold", class: "font-bold" }
  ];
 
  let fontWeight = $state("normal");
</script>
 
<Field.Field>
  <Field.Label>Font Weight</Field.Label>
  <ToggleGroup.Root
    type="single"
    bind:value={fontWeight}
    variant="outline"
    spacing={2}
    size="lg"
  >
    {#each weights as weight (weight.value)}
      <ToggleGroup.Item
        value={weight.value}
        aria-label={weight.label}
        class="flex size-16 flex-col items-center justify-center rounded-xl"
      >
        <span class="text-2xl leading-none {weight.class}">Aa</span>
        <span class="text-xs text-muted-foreground">{weight.label}</span>
      </ToggleGroup.Item>
    {/each}
  </ToggleGroup.Root>
  <Field.Description>
    Use <code class="rounded-md bg-muted px-1 py-0.5 font-mono"
      >font-{fontWeight}</code
    > to set the font weight.
  </Field.Description>
</Field.Field>