> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/shadcn-ui/ui/llms.txt
> Use this file to discover all available pages before exploring further.

# Toggle

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

## Installation

<CodeGroup>
  ```bash npm theme={null}
  npx shadcn@latest add toggle
  ```

  ```bash yarn theme={null}
  yarn dlx shadcn@latest add toggle
  ```

  ```bash pnpm theme={null}
  pnpm dlx shadcn@latest add toggle
  ```

  ```bash bun theme={null}
  bunx shadcn@latest add toggle
  ```
</CodeGroup>

## Usage

```tsx theme={null}
import { Toggle } from "@/components/ui/toggle"
```

```tsx theme={null}
<Toggle aria-label="Toggle italic">
  <Italic className="h-4 w-4" />
</Toggle>
```

## Examples

### Basic

A simple toggle button with an icon.

```tsx theme={null}
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.

```tsx theme={null}
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

<Tabs defaultValue="default">
  <TabsList>
    <TabsTrigger value="default">Default</TabsTrigger>
    <TabsTrigger value="outline">Outline</TabsTrigger>
  </TabsList>

  <TabsContent value="default">
    ```tsx theme={null}
    import { Italic } from "lucide-react"
    import { Toggle } from "@/components/ui/toggle"

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

  <TabsContent value="outline">
    ```tsx theme={null}
    import { Italic } from "lucide-react"
    import { Toggle } from "@/components/ui/toggle"

    export default function ToggleOutline() {
      return (
        <Toggle variant="outline" aria-label="Toggle italic">
          <Italic className="h-4 w-4" />
        </Toggle>
      )
    }
    ```
  </TabsContent>
</Tabs>

### Sizes

```tsx theme={null}
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

```tsx theme={null}
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

```tsx theme={null}
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

```tsx theme={null}
"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

| Prop              | Type                         | Default     | Description                          |
| ----------------- | ---------------------------- | ----------- | ------------------------------------ |
| `variant`         | `"default" \| "outline"`     | `"default"` | Visual style variant                 |
| `size`            | `"sm" \| "default" \| "lg"`  | `"default"` | Size of the toggle                   |
| `pressed`         | `boolean`                    | -           | Controlled pressed state             |
| `defaultPressed`  | `boolean`                    | `false`     | Default pressed state (uncontrolled) |
| `onPressedChange` | `(pressed: boolean) => void` | -           | Callback when pressed state changes  |
| `disabled`        | `boolean`                    | `false`     | Disables the toggle                  |
| `className`       | `string`                     | -           | Additional CSS classes               |
| `aria-label`      | `string`                     | -           | 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](https://base-ui.com/react/components/toggle). See the [official API documentation](https://base-ui.com/react/components/toggle#api-reference) for more details.
