# Toggle

A two-state button.

Source: [toggle.tsx](https://github.com/jakejarvis/jarvis-ui/blob/main/src/components/ui/toggle.tsx)

```tsx
import { BellIcon, StarIcon } from "lucide-react";

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

export default function ToggleWithText() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <Toggle defaultPressed>
        <StarIcon />
        Star
      </Toggle>
      <Toggle>
        <BellIcon />
        Watch
      </Toggle>
    </div>
  );
}
```

## Installation

Add the registry, once per project:

```bash
npx shadcn@latest registry add @jarvis=https://ui.jarv.is/r/{name}.json
```

Then add the component:

```bash
npx shadcn@latest add @jarvis/toggle
```

## Usage

```tsx
import { StarIcon } from "lucide-react";

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

export function StarToggle() {
  return (
    <Toggle aria-label="Star">
      <StarIcon />
    </Toggle>
  );
}
```

Use a toggle for one on/off setting, such as muting a call. Keep its label the same in both
states; screen readers already announce whether it's pressed.

For a set of related toggles, use a [Toggle Group](https://ui.jarv.is/components/toggle-group.md). Inside a
[Toolbar](https://ui.jarv.is/components/toolbar.md), use `ToolbarToggle`.

## Examples

### Sizes

Give an icon-only toggle an `aria-label`.

```tsx
import { BookmarkIcon } from "lucide-react";

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

export default function ToggleSizes() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <Toggle size="sm" aria-label="Bookmark">
        <BookmarkIcon />
      </Toggle>
      <Toggle aria-label="Bookmark" defaultPressed>
        <BookmarkIcon />
      </Toggle>
      <Toggle size="lg" aria-label="Bookmark">
        <BookmarkIcon />
      </Toggle>
    </div>
  );
}
```

### Controlled

Use `defaultPressed`, or `pressed` with `onPressedChange` to control it.

```tsx
import { MicIcon, MicOffIcon } from "lucide-react";
import * as React from "react";

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

export default function ToggleControlled() {
  const [muted, setMuted] = React.useState(false);
  return (
    <div className="flex items-center gap-3">
      <Toggle size="lg" pressed={muted} onPressedChange={setMuted} aria-label="Mute">
        {muted ? <MicOffIcon /> : <MicIcon />}
      </Toggle>
      <p className="text-sm text-muted-foreground">
        {muted ? "Your microphone is muted" : "Your microphone is on"}
      </p>
    </div>
  );
}
```

### Disabled

```tsx
import { PinIcon } from "lucide-react";

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

export default function ToggleDisabled() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <Toggle disabled>
        <PinIcon />
        Pin
      </Toggle>
      <Toggle disabled defaultPressed>
        <PinIcon />
        Pin
      </Toggle>
    </div>
  );
}
```

## Props

| Part | Extends |
| --- | --- |
| `Toggle` | [`Toggle`](https://base-ui.com/react/components/toggle#api-reference) |

The tables leave out `className`, `style` and `render`. Parts built on Base UI take them as its [styling](https://base-ui.com/react/handbook/styling) and [composition](https://base-ui.com/react/handbook/composition) guides describe.

### Toggle

| Prop               | Type                                                                    | Description                                                                                                                                                                                       |
| ------------------ | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pressed?`         | `boolean`                                                               | Whether the toggle button is currently pressed. This is the controlled counterpart of `defaultPressed`.                                                                                           |
| `defaultPressed?`  | `boolean`                                                               | Whether the toggle button is currently pressed. This is the uncontrolled counterpart of `pressed`. Default: `false`                                                                               |
| `disabled?`        | `boolean`                                                               | Whether the component should ignore user interaction. Default: `false`                                                                                                                            |
| `onPressedChange?` | `((pressed: boolean, eventDetails: Toggle.ChangeEventDetails) => void)` | Callback fired when the pressed state is changed.                                                                                                                                                 |
| `value?`           | `string`                                                                | A unique string that identifies the toggle when used inside a toggle group.                                                                                                                       |
| `nativeButton?`    | `boolean`                                                               | Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`). Default: `true` |
| `size?`            | `"default" \| "lg" \| "sm"`                                             | Default: `"default"`                                                                                                                                                                              |
