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.