---
id: "packages/active-ui/switch"
title: "Switch"
description: "An on and off control for a setting that takes effect at once, in two sizes."
url: "/packages/active-ui/switch"
locale: "en"
revision: "77df6cc4e0c0189e"
---

# Switch

A switch turns a setting on or off, and the change applies immediately, like a light switch:
email alerts, compact rows. When the choice is submitted with a form, or needs confirmation, use a
[checkbox](/packages/active-ui/checkbox) instead.

**Example: Settings that take effect at once**

Client: Runs entirely in your browser. Source: `examples/ui/switch.tsx`.

```tsx
// apps/docs/examples/ui/switch.tsx
'use client';

import {useState} from 'react';

import {
  Field,
  FieldContent,
  FieldDescription,
  FieldGroup,
  FieldLabel,
} from '@workspace/active-ui/components/primitives/field';
import {Switch} from '@workspace/active-ui/components/primitives/switch';

/**
 * Settings that take effect at once: a switch beside its label and
 * description, the small size, and a disabled switch. A switch reports its
 * state with `role="switch"` and `aria-checked`.
 */
export default function SwitchExample() {
  const [alerts, setAlerts] = useState(true);
  return (
    <FieldGroup className="w-full max-w-md">
      <Field orientation="horizontal">
        <FieldContent>
          <FieldLabel htmlFor="switch-alerts">Email alerts</FieldLabel>
          <FieldDescription>
            {alerts
              ? 'You receive an email when a payment fails.'
              : 'You receive no emails about failed payments.'}
          </FieldDescription>
        </FieldContent>
        <Switch
          id="switch-alerts"
          checked={alerts}
          onCheckedChange={setAlerts}
        />
      </Field>
      <Field orientation="horizontal">
        <Switch id="switch-compact" size="sm" />
        <FieldLabel htmlFor="switch-compact">Compact rows</FieldLabel>
      </Field>
      <Field orientation="horizontal" data-disabled>
        <Switch id="switch-sync" disabled defaultChecked />
        <FieldLabel htmlFor="switch-sync">
          Synchronise with the archive (managed by your administrator)
        </FieldLabel>
      </Field>
    </FieldGroup>
  );
}
```

## Usage

```tsx
import {
  Field,
  FieldLabel,
} from '@workspace/active-ui/components/primitives/field';
import {Switch} from '@workspace/active-ui/components/primitives/switch';

<Field orientation="horizontal">
  <Switch id="alerts" checked={alerts} onCheckedChange={setAlerts} />
  <FieldLabel htmlFor="alerts">Email alerts</FieldLabel>
</Field>;
```

## States and sizes

- `checked` and `onCheckedChange` (controlled) or `defaultChecked`.
- `size`: `default`, or `sm` for dense lists and tables.
- `disabled` dims the switch and skips it with the keyboard; `aria-invalid` gives it the error
  ring.

## What your application provides

- A label, and a description when the effect is not obvious from the label. Keep the label the
  same in both states: it names the setting, the switch shows its state.
- The effect of the change, and its feedback. When the change can fail, such as a setting saved on
  a server, show the result and set the switch back if it failed.

## Accessibility and keyboard

- `Space` and `Enter` toggle the focused switch.
- It is a `role="switch"` button with `aria-checked`; a hidden checkbox carries `name` and
  `value` into a native form.
- The hit area extends beyond the visible track.

## API

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `size` | `"default" \| "sm"` | no | The size of the track and thumb: `default`, or `sm` for dense lists and tables. |
| `checked` | `boolean` | no | Whether the switch is currently active.  To render an uncontrolled switch, use the `defaultChecked` prop instead. |
| `defaultChecked` | `boolean` | no | Whether the switch is initially active.  To render a controlled switch, use the `checked` prop instead. |
| `disabled` | `boolean` | no | Whether the component should ignore user interaction. |
| `form` | `string` | no | Identifies the form that owns the hidden input. Useful when the switch is rendered outside the form. |
| `id` | `string` | no | The id of the hidden input element.  When `nativeButton` is `true`, the id is applied to the root element. |
| `inputRef` | `Ref<HTMLInputElement>` | no | A ref to access the hidden `<input>` element. |
| `name` | `string` | no | Identifies the field when a form is submitted. |
| `nativeButton` | `boolean` | no | 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. |
| `onCheckedChange` | `((checked: boolean, eventDetails: SwitchRoot.ChangeEventDetails) => void)` | no | Event handler called when the switch is activated or deactivated. |
| `readOnly` | `boolean` | no | Whether the user should be unable to activate or deactivate the switch. |
| `render` | `ComponentRenderFn<HTMLProps, SwitchRootState> \| ReactElement<unknown, string \| JSXElementConstructor<any>>` | no | Allows you to replace the component's HTML element with a different tag, or compose it with another component.  Accepts a `ReactElement` or a function that returns the element to render. |
| `required` | `boolean` | no | Whether the user must activate the switch before submitting a form. |
| `uncheckedValue` | `string` | no | The value submitted with the form when the switch is off. By default, unchecked switches do not submit any value, matching native checkbox behavior. |
| `value` | `string` | no | The value submitted with the form when the switch is on. By default, switch submits the "on" value, matching native checkbox behavior. |

> [!NOTE]
> **Based on shadcn/ui**
>
> This page adapts the Switch documentation of shadcn/ui (MIT licence) to this
> package; see [Third-party notices](/third-party-notices).
