

<Preview name="SettingsCardExample" />

## Overview [#overview]

The **Switch** component provides a toggle control for binary choices, offering a more visually distinct alternative to checkboxes for on/off or enable/disable settings. Built on Base UI primitives, it offers full keyboard navigation and accessibility features.

## Usage [#usage]

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

```tsx
<Switch />
```

### With Label [#with-label]

Always associate switches with descriptive labels for better accessibility and user experience:

```tsx
<Label orientation="horizontal">
  <Switch />
  Enable notifications
</Label>
```

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

    ```tsx
    // Boolean state synced with ?notifications=true
    <Switch paramName="notifications" defaultChecked={false} />

    // With label and URL state:
    <Label orientation="horizontal">
      <Switch paramName="darkMode" defaultChecked={false} />
      Enable dark mode
    </Label>

    // Advanced options:
    <Switch
      paramName="setting"
      paramClearOnDefault={true}    // Remove param when value equals default
      paramDebounce={150}           // Debounce URL updates
      onUrlValueChange={(checked) => console.log('Setting enabled:', checked)}
      defaultChecked={false}
    />
    ```
  </Accordion>
</Accordions>

## Examples [#examples]

### Default [#default]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="BasicSwitchExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Switch, Label } from "@tilt-legal/cubitt-components/primitives";

    export default function Component() {
      return (
        <Label orientation="horizontal">
          <Switch />
          Default switch
        </Label>
      );
    }
    ```
  </Tab>
</Tabs>

### Sizes [#sizes]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="SwitchSizesExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Switch, Label } from "@tilt-legal/cubitt-components/primitives";

    export default function Component() {
      return (
        <div className="flex items-center gap-6">
          <Label orientation="horizontal">
            <Switch size="sm" />
            Small
          </Label>
          <Label orientation="horizontal">
            <Switch size="md" />
            Medium
          </Label>
          <Label orientation="horizontal">
            <Switch size="lg" />
            Large
          </Label>
        </div>
      );
    }
    ```
  </Tab>
</Tabs>

### Checked by Default [#checked-by-default]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="CheckedByDefaultExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Switch, Label } from "@tilt-legal/cubitt-components/primitives";

    export default function Component() {
      return (
        <Label orientation="horizontal">
          <Switch defaultChecked />
          Enabled by default
        </Label>
      );
    }
    ```
  </Tab>
</Tabs>

### Disabled [#disabled]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="DisabledSwitchExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Switch, Label } from "@tilt-legal/cubitt-components/primitives";

    export default function Component() {
      return (
        <div className="flex flex-col gap-4">
          <Label orientation="horizontal">
            <Switch disabled />
            Disabled (off)
          </Label>
          <Label orientation="horizontal">
            <Switch disabled defaultChecked />
            Disabled (on)
          </Label>
        </div>
      );
    }
    ```
  </Tab>
</Tabs>

### With Description [#with-description]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="WithDescriptionExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Switch, Label } from "@tilt-legal/cubitt-components/primitives";

    export default function Component() {
      return (
        <Label orientation="horizontal" className="items-start gap-3">
          <Switch />
          <div className="grid gap-1.5">
            <span className="font-medium">Marketing emails</span>
            <p className="text-sm text-muted-foreground">
              Receive emails about new products, features, and more.
            </p>
          </div>
        </Label>
      );
    }
    ```
  </Tab>
</Tabs>

### Settings Card [#settings-card]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="SettingsCardExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Switch, Label } from "@tilt-legal/cubitt-components/primitives";

    export default function Component() {
      return (
        <Label
          orientation="horizontal"
          className="hover:bg-accent/20 items-start gap-3 rounded-xl border p-4 has-[[aria-checked=true]]:border-primary has-[[aria-checked=true]]:bg-primary/10 transition-colors"
        >
          <Switch id="switch-1" size="sm" />
          <div className="grid gap-1.5 font-normal">
            <p className="text-sm leading-none font-medium">Enable notifications</p>
            <p className="text-muted-foreground text-sm">
              You can enable or disable notifications at any time.
            </p>
          </div>
        </Label>
      );
    }
    ```
  </Tab>
</Tabs>

### URL State [#url-state]

Sync a switch state with the URL. Try toggling the switch and refreshing the page or sharing the URL.

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="SwitchURLStateExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Switch, Label } from "@tilt-legal/cubitt-components/primitives";

    export default function Component() {
      return (
        <Label orientation="horizontal">
          <Switch paramName="demo-notifications" defaultChecked={false} />
          Enable notifications
        </Label>
      );
    }
    ```
  </Tab>
</Tabs>

## API Reference [#api-reference]

### Switch [#switch]

The root component for creating switches with multiple size variants.

| Prop              | Type                         | Default | Description                                                              |
| ----------------- | ---------------------------- | ------- | ------------------------------------------------------------------------ |
| `checked`         | `boolean`                    | —       | The controlled checked state of the switch.                              |
| `defaultChecked`  | `boolean`                    | `false` | The default checked state when uncontrolled.                             |
| `onCheckedChange` | `(checked: boolean) => void` | —       | Callback fired when the checked state changes.                           |
| `size`            | `"sm"` \| `"md"` \| `"lg"`   | `"md"`  | The size of the switch.                                                  |
| `disabled`        | `boolean`                    | `false` | Whether the switch is disabled.                                          |
| `required`        | `boolean`                    | `false` | Whether the switch is required.                                          |
| `name`            | `string`                     | —       | The name of the switch for form submission.                              |
| `value`           | `string`                     | `"on"`  | The value of the switch when in a form.                                  |
| `id`              | `string`                     | —       | The HTML id for label association.                                       |
| `className`       | `string`                     | —       | Additional CSS classes for the switch.                                   |
| `children`        | `React.ReactNode`            | —       | Custom thumb content (defaults to `<code>&lt;SwitchThumb /&gt;</code>`). |

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

When provided with a `paramName`, the switch 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. |
| `onUrlValueChange`    | `(checked: boolean) => void` | —       | Callback when URL parameter value changes.                                   |
| `paramClearOnDefault` | `boolean`                    | `true`  | Remove URL param when value equals default.                                  |
| `paramDebounce`       | `number`                     | —       | Debounce URL updates in milliseconds.                                        |
| `paramThrottle`       | `number`                     | —       | Throttle URL updates in milliseconds.                                        |

### SwitchThumb [#switchthumb]

The thumb component that slides within the switch track.

| Prop        | Type                       | Default | Description                           |
| ----------- | -------------------------- | ------- | ------------------------------------- |
| `size`      | `"sm"` \| `"md"` \| `"lg"` | —       | Override the size from parent Switch. |
| `className` | `string`                   | —       | Additional CSS classes for the thumb. |
