A two-state button that can be either on or off.

import { BookmarkIcon } from "@/components/icons"
import { Toggle } from "@/components/ui/toggle"

export function ToggleDemo() {
  return (
    <Toggle aria-label="Toggle bookmark" size="sm" variant="outline">
      <BookmarkIcon class="group-aria-pressed/toggle:fill-foreground" />
      Bookmark
    </Toggle>
  )
}

Installation

pnpm dlx shadcnui-hono-jsx@latest add toggle

Usage

import { Toggle } from "@/components/ui/toggle"
<Toggle>Toggle</Toggle>

Outline

Use variant="outline" for an outline style.

import { BoldIcon, ItalicIcon } from "@/components/icons"
import { Toggle } from "@/components/ui/toggle"

export function ToggleOutline() {
  return (
    <div class="flex flex-wrap items-center gap-2">
      <Toggle variant="outline" aria-label="Toggle italic">
        <ItalicIcon />
        Italic
      </Toggle>
      <Toggle variant="outline" aria-label="Toggle bold">
        <BoldIcon />
        Bold
      </Toggle>
    </div>
  )
}

With Text

import { ItalicIcon } from "@/components/icons"
import { Toggle } from "@/components/ui/toggle"

export function ToggleText() {
  return (
    <Toggle aria-label="Toggle italic">
      <ItalicIcon />
      Italic
    </Toggle>
  )
}

Size

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

import { Toggle } from "@/components/ui/toggle"

export function ToggleSizes() {
  return (
    <div class="flex flex-wrap items-center gap-2">
      <Toggle variant="outline" aria-label="Toggle small" size="sm">
        Small
      </Toggle>
      <Toggle variant="outline" aria-label="Toggle default" size="default">
        Default
      </Toggle>
      <Toggle variant="outline" aria-label="Toggle large" size="lg">
        Large
      </Toggle>
    </div>
  )
}

Disabled

import { Toggle } from "@/components/ui/toggle"

export function ToggleDisabled() {
  return (
    <div class="flex flex-wrap items-center gap-2">
      <Toggle aria-label="Toggle disabled" disabled>
        Disabled
      </Toggle>
      <Toggle variant="outline" aria-label="Toggle disabled outline" disabled>
        Disabled
      </Toggle>
    </div>
  )
}

RTL

To enable RTL support in shadcn/ui, see the RTL configuration guide.

// This example sets dir and uses useTranslation because this site is not RTL.

// In an RTL app you won't need them; see the RTL guide.

import { BookmarkIcon } from "@/components/icons"
import {
  type Translations,
  useTranslation,
} from "@/components/language-selector"
import { Toggle } from "@/components/ui/toggle"

const translations: Translations = {
  en: {
    dir: "ltr",
    values: {
      label: "Bookmark",
    },
  },
  ar: {
    dir: "rtl",
    values: {
      label: "إشارة مرجعية",
    },
  },
  he: {
    dir: "rtl",
    values: {
      label: "סימנייה",
    },
  },
}

export function ToggleRtl() {
  const { dir, t } = useTranslation(translations, "ar")

  return (
    <Toggle aria-label="Toggle bookmark" size="sm" variant="outline" dir={dir}>
      <BookmarkIcon class="group-aria-pressed/toggle:fill-foreground" />
      {t.label}
    </Toggle>
  )
}

Notes

  • A label around a visually hidden native checkbox (the pressed state is its checked state): no JavaScript, and name/value are submitted with forms. aria-* goes to the input, so icon-only toggles need aria-label as upstream.
  • Space toggles, Enter does not (a checkbox, not a button); pressed/defaultPressed set the initial state; onPressedChange and render are not supported.
  • Accepts class instead of className.
  • Upstream documentation: shadcn/ui Toggle. See also Differences from shadcn/ui.

API Reference

See the Base UI Toggle documentation.