# Switch

A control that toggles between on and off.

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

```tsx
import { Field, FieldContent, FieldDescription, FieldLabel } from "@/components/ui/field";
import { Switch } from "@/components/ui/switch";

export default function SwitchWithDescription() {
  return (
    <Field orientation="horizontal" className="w-full max-w-sm">
      <FieldContent>
        <FieldLabel htmlFor="autosave">Auto-save drafts</FieldLabel>
        <FieldDescription>Save changes every few seconds.</FieldDescription>
      </FieldContent>
      <Switch id="autosave" defaultChecked />
    </Field>
  );
}
```

## 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/switch
```

## Usage

```tsx
import { Field, FieldLabel } from "@/components/ui/field";
import { Switch } from "@/components/ui/switch";

export function NotificationsSetting() {
  return (
    <Field orientation="horizontal">
      <FieldLabel>Email notifications</FieldLabel>
      <Switch defaultChecked />
    </Field>
  );
}
```

Use a switch for settings that apply right away. For a choice that applies when a form is
submitted, use a [Checkbox](https://ui.jarv.is/components/checkbox.md).

## Examples

### With a label

Nest the switch in a `FieldLabel` so clicking the text toggles it.

```tsx
import { FieldLabel } from "@/components/ui/field";
import { Switch } from "@/components/ui/switch";

export default function SwitchWithLabel() {
  return (
    <FieldLabel className="gap-2 font-normal">
      <Switch />
      Show completed tasks
    </FieldLabel>
  );
}
```

### Sizes

`size="sm"` makes a smaller switch. Without visible text, give it an `aria-label`.

```tsx
import { Switch } from "@/components/ui/switch";

export default function SwitchSizes() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <Switch size="sm" aria-label="Small, off" />
      <Switch size="sm" defaultChecked aria-label="Small, on" />
      <Switch aria-label="Default, off" />
      <Switch defaultChecked aria-label="Default, on" />
    </div>
  );
}
```

### Disabled

```tsx
import { Switch } from "@/components/ui/switch";

export default function SwitchDisabled() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <Switch disabled aria-label="Disabled, off" />
      <Switch disabled defaultChecked aria-label="Disabled, on" />
    </div>
  );
}
```

### Invalid

Set `invalid` on the `Field` and explain the problem with a `FieldError`.

```tsx
import { Field, FieldContent, FieldError, FieldLabel } from "@/components/ui/field";
import { Switch } from "@/components/ui/switch";

export default function SwitchInvalid() {
  return (
    <Field invalid orientation="horizontal" className="w-full max-w-sm">
      <FieldContent>
        <FieldLabel>Accept the terms of service</FieldLabel>
        <FieldError>You need to accept the terms to continue.</FieldError>
      </FieldContent>
      <Switch />
    </Field>
  );
}
```

## Props

| Part | Extends |
| --- | --- |
| `Switch` | [`Switch.Root`](https://base-ui.com/react/components/switch#root) |

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.

### Switch

| Prop               | Type                                                                         | Description                                                                                                                                                                   |
| ------------------ | ---------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nativeButton?`    | `boolean`                                                                    | Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `true` if the rendered element is a native button. Default: `false` |
| `id?`              | `string`                                                                     | The id of the hidden input element. When `nativeButton` is `true`, the id is applied to the root element.                                                                     |
| `checked?`         | `boolean`                                                                    | Whether the switch is currently active. To render an uncontrolled switch, use the `defaultChecked` prop instead.                                                              |
| `defaultChecked?`  | `boolean`                                                                    | Whether the switch is initially active. To render a controlled switch, use the `checked` prop instead. Default: `false`                                                       |
| `disabled?`        | `boolean`                                                                    | Whether the component should ignore user interaction. Default: `false`                                                                                                        |
| `inputRef?`        | `React.Ref<HTMLInputElement>`                                                | A ref to access the hidden `<input>` element.                                                                                                                                 |
| `name?`            | `string`                                                                     | Identifies the field when a form is submitted.                                                                                                                                |
| `form?`            | `string`                                                                     | Identifies the form that owns the hidden input. Useful when the switch is rendered outside the form.                                                                          |
| `onCheckedChange?` | `((checked: boolean, eventDetails: Switch.Root.ChangeEventDetails) => void)` | Event handler called when the switch is activated or deactivated.                                                                                                             |
| `readOnly?`        | `boolean`                                                                    | Whether the user should be unable to activate or deactivate the switch. Default: `false`                                                                                      |
| `required?`        | `boolean`                                                                    | Whether the user must activate the switch before submitting a form. Default: `false`                                                                                          |
| `value?`           | `string`                                                                     | The value submitted with the form when the switch is on. By default, switch submits the "on" value, matching native checkbox behavior.                                        |
| `uncheckedValue?`  | `string`                                                                     | The value submitted with the form when the switch is off. By default, unchecked switches do not submit any value, matching native checkbox behavior.                          |
| `size?`            | `"default" \| "sm"`                                                          | Default: `"default"`                                                                                                                                                          |
