

<Preview name="ToggleDefaultExample" />

## Overview [#overview]

The **Toggle** component provides a pressable button that switches between active and inactive states, commonly used for toolbar actions, formatting options, or feature toggles. Built on Base UI primitives, it features customizable variants, sizes, and smooth transitions.

## Usage [#usage]

```tsx
import { Toggle } from "@tilt-legal/cubitt-components/primitives";
```

```tsx
<Toggle aria-label="Toggle bold">
  <TextBold />
</Toggle>
```

<Accordions type="single">
  <Accordion title="URL State Management">
    Using Cubitt's URL-state hooks, you can sync the toggle state with the URL by providing a `paramName`:

    ```tsx
    // Toggle state synced with ?bold=true
    <Toggle paramName="bold" defaultPressed={false} aria-label="Toggle bold">
      <TextBold />
      Bold
    </Toggle>

    // Advanced options:
    <Toggle
      paramName="feature"
      defaultPressed={false}
      paramClearOnDefault={true}    // Remove param when value equals default
      paramDebounce={100}           // Debounce URL updates
      onUrlValueChange={(pressed) => console.log('Toggle state:', pressed)}
      aria-label="Toggle feature"
    >
      Feature
    </Toggle>
    ```
  </Accordion>
</Accordions>

***

## Examples [#examples]

### Default [#default]

Basic toggle button with default styling.

<Tabs items="[&#x22;Preview&#x22;, &#x22;Code&#x22;]">
  <Tab value="Preview">
    <Preview name="ToggleDefaultExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Toggle } from "@tilt-legal/cubitt-components/primitives";
    import {
      TextBold } from "@tilt-legal/cubitt-icons/ui/outline";

    export default function Example() {
      return (
        <Toggle aria-label="Toggle bold">
          <TextBold />
        </Toggle>
      );
    }
    ```
  </Tab>
</Tabs>

### Outline Variant [#outline-variant]

Toggle with outlined styling.

<Tabs
  items="[&#x22;Preview&#x22;,
    &#x22;Code&#x22;]"
>
  <Tab value="Preview">
    <Preview name="ToggleOutlineExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Toggle } from "@tilt-legal/cubitt-components/primitives";
    import {
      TextItalic } from "@tilt-legal/cubitt-icons/ui/outline";

    export default function Example() {
      return (
        <Toggle variant="outline" aria-label="Toggle italic">
          <TextItalic />
        </Toggle>
      );
    }
    ```
  </Tab>
</Tabs>

### With Text [#with-text]

Toggle buttons can include both icons and text labels.

<Tabs
  items="[&#x22;Preview&#x22;,
    &#x22;Code&#x22;]"
>
  <Tab value="Preview">
    <Preview name="ToggleWithTextExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Toggle } from "@tilt-legal/cubitt-components/primitives";
    import {
      TextBold,
      TextItalic } from "@tilt-legal/cubitt-icons/ui/outline";

    export default function Example() {
      return (
        <div className="flex items-center gap-2">
          <Toggle aria-label="Toggle bold">
            <TextBold />
            Bold
          </Toggle>
          <Toggle variant="outline" aria-label="Toggle italic">
            <TextItalic />
            Italic
          </Toggle>
        </div>
      );
    }
    ```
  </Tab>
</Tabs>

### Sizes [#sizes]

Toggles in different sizes.

<Tabs
  items="[&#x22;Preview&#x22;,
    &#x22;Code&#x22;]"
>
  <Tab value="Preview">
    <Preview name="ToggleSizesExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Toggle } from "@tilt-legal/cubitt-components/primitives";
    import {
      TextBold,
      TextItalic,
      TextUnderline } from "@tilt-legal/cubitt-icons/ui/outline";

    export default function Example() {
      return (
        <div className="flex items-center gap-4">
          <Toggle size="sm" aria-label="Toggle bold" variant="outline">
            <TextBold />
          </Toggle>
          <Toggle size="md" aria-label="Toggle italic" variant="outline">
            <TextItalic />
          </Toggle>
          <Toggle size="lg" aria-label="Toggle underline" variant="outline">
            <TextUnderline />
          </Toggle>
        </div>
      );
    }
    ```
  </Tab>
</Tabs>

### URL State [#url-state]

Sync toggle state with the URL. Try toggling and refreshing the page.

<Tabs
  items="[&#x22;Preview&#x22;,
    &#x22;Code&#x22;]"
>
  <Tab value="Preview">
    <Preview name="ToggleURLStateExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Toggle } from "@tilt-legal/cubitt-components/primitives";
    import { TextBold } from "@tilt-legal/cubitt-icons/ui/outline";

    export default function Example() {
      return (
        <Toggle
          paramName="demo-bold"
          defaultPressed={false}
          paramClearOnDefault={true}
          aria-label="Toggle bold"
        >
          <TextBold />
          Bold
        </Toggle>
      );
    }
    ```
  </Tab>
</Tabs>

***

## API Reference [#api-reference]

### Toggle [#toggle]

A pressable button that maintains pressed/unpressed state.

| Prop              | Type                         | Default     | Description                                               |
| ----------------- | ---------------------------- | ----------- | --------------------------------------------------------- |
| `pressed`         | `boolean`                    | —           | The controlled pressed state of the toggle.               |
| `defaultPressed`  | `boolean`                    | `false`     | The default pressed state when uncontrolled.              |
| `onPressedChange` | `(pressed: boolean) => void` | —           | Callback fired when the pressed state changes.            |
| `disabled`        | `boolean`                    | `false`     | Whether the toggle is disabled.                           |
| `variant`         | `"default" \| "outline"`     | `"default"` | Visual style variant of the toggle.                       |
| `size`            | `"sm" \| "md" \| "lg"`       | `"md"`      | Size of the toggle button.                                |
| `className`       | `string`                     | —           | Additional CSS classes for the toggle.                    |
| `aria-label`      | `string`                     | —           | Accessible label for the toggle (required for icon-only). |

#### URL State Props [#url-state-props]

When provided with a `paramName`, the toggle will sync its state with URL parameters via TanStack Router search params.

| Prop                  | Type                         | Default | Description                                                                  |
| --------------------- | ---------------------------- | ------- | ---------------------------------------------------------------------------- |
| `paramName`           | `string`                     | —       | URL parameter name for syncing state with URL. Enables URL state management. |
| `paramValue`          | `boolean`                    | —       | Controlled value for the URL parameter.                                      |
| `onUrlValueChange`    | `(pressed: boolean) => void` | —       | Callback when URL parameter value changes.                                   |
| `paramClearOnDefault` | `boolean`                    | `true`  | Remove URL param when value equals default.                                  |
| `paramThrottle`       | `number`                     | —       | Throttle URL updates in milliseconds.                                        |
| `paramDebounce`       | `number`                     | —       | Debounce URL updates in milliseconds.                                        |

### Notes [#notes]

* **Accessibility**: Always provide `aria-label` for icon-only toggles to ensure screen reader users understand the button's purpose
* **State management**: Use `pressed` and `onPressedChange` for controlled mode, or `defaultPressed` for uncontrolled mode
* **Multiple toggles**: For related toggle buttons, consider using the `ToggleGroup` component which provides better keyboard navigation and state management
* The component uses Base UI primitives with smooth transitions for state changes
