Skip to main content

Installation

npx shadcn@latest add toggle

Usage

import { Toggle } from "@/components/ui/toggle"
<Toggle aria-label="Toggle italic">
  <Italic className="h-4 w-4" />
</Toggle>

Examples

Basic

A simple toggle button with an icon.
import { Italic } from "lucide-react"
import { Toggle } from "@/components/ui/toggle"

export default function ToggleDemo() {
  return (
    <Toggle aria-label="Toggle italic">
      <Italic className="h-4 w-4" />
    </Toggle>
  )
}

With Text

Toggle button with both icon and text.
import { BookmarkIcon } from "lucide-react"
import { Toggle } from "@/components/ui/toggle"

export default function ToggleWithText() {
  return (
    <Toggle aria-label="Toggle bookmark">
      <BookmarkIcon className="h-4 w-4" />
      Bookmark
    </Toggle>
  )
}

Variants

    Sizes

    import { Italic } from "lucide-react"
    import { Toggle } from "@/components/ui/toggle"
    
    export default function ToggleSizes() {
      return (
        <div className="flex items-center gap-2">
          <Toggle size="sm" aria-label="Toggle italic">
            <Italic className="h-3 w-3" />
          </Toggle>
          <Toggle size="default" aria-label="Toggle italic">
            <Italic className="h-4 w-4" />
          </Toggle>
          <Toggle size="lg" aria-label="Toggle italic">
            <Italic className="h-5 w-5" />
          </Toggle>
        </div>
      )
    }
    

    Disabled

    import { Italic } from "lucide-react"
    import { Toggle } from "@/components/ui/toggle"
    
    export default function ToggleDisabled() {
      return (
        <Toggle disabled aria-label="Toggle italic">
          <Italic className="h-4 w-4" />
        </Toggle>
      )
    }
    

    Controlled

    import { useState } from "react"
    import { Italic } from "lucide-react"
    import { Toggle } from "@/components/ui/toggle"
    
    export default function ToggleControlled() {
      const [pressed, setPressed] = useState(false)
    
      return (
        <div className="flex flex-col gap-2">
          <Toggle
            pressed={pressed}
            onPressedChange={setPressed}
            aria-label="Toggle italic"
          >
            <Italic className="h-4 w-4" />
          </Toggle>
          <p className="text-sm text-muted-foreground">
            State: {pressed ? "On" : "Off"}
          </p>
        </div>
      )
    }
    

    Component Code

    "use client"
    
    import * as React from "react"
    import { cva, type VariantProps } from "class-variance-authority"
    import { Toggle as TogglePrimitive } from "radix-ui"
    
    import { cn } from "@/lib/utils"
    
    const toggleVariants = cva(
      "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
      {
        variants: {
          variant: {
            default: "bg-transparent",
            outline:
              "border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground",
          },
          size: {
            default: "h-9 min-w-9 px-2",
            sm: "h-8 min-w-8 px-1.5",
            lg: "h-10 min-w-10 px-2.5",
          },
        },
        defaultVariants: {
          variant: "default",
          size: "default",
        },
      }
    )
    
    function Toggle({
      className,
      variant,
      size,
      ...props
    }: React.ComponentProps<typeof TogglePrimitive.Root> &
      VariantProps<typeof toggleVariants>) {
      return (
        <TogglePrimitive.Root
          data-slot="toggle"
          className={cn(toggleVariants({ variant, size, className }))}
          {...props}
        />
      )
    }
    
    export { Toggle, toggleVariants }
    

    Props

    Toggle

    PropTypeDefaultDescription
    variant"default" | "outline""default"Visual style variant
    size"sm" | "default" | "lg""default"Size of the toggle
    pressedboolean-Controlled pressed state
    defaultPressedbooleanfalseDefault pressed state (uncontrolled)
    onPressedChange(pressed: boolean) => void-Callback when pressed state changes
    disabledbooleanfalseDisables the toggle
    classNamestring-Additional CSS classes
    aria-labelstring-Accessible label for the toggle

    Accessibility

    • Uses the button role with aria-pressed attribute
    • Keyboard accessible (Space/Enter to toggle)
    • Always include an aria-label for icon-only toggles
    • Disabled state prevents interaction and is announced to screen readers

    API Reference

    Built on top of Radix UI Toggle. See the official API documentation for more details.

    Build docs developers (and LLMs) love