---
title: Switch
description: "A control that allows the user to toggle between on and off."
---

```tsx
import * as stylex from '@stylexjs/stylex';

import { Switch } from '@/components/ui/switch';
import { space, fontSize } from '@/lib/constants.stylex';
import { colors, font } from '@/lib/tokens.stylex';

export default function SwitchDemo() {
  return (
    <label {...stylex.props(styles.label)}>
      <Switch defaultChecked /> Airplane mode
    </label>
  );
}

const styles = stylex.create({
  label: {
    alignItems: 'center',
    color: colors.foreground,
    display: 'flex',
    fontFamily: font.sans,
    fontSize: fontSize.sm,
    gap: space.s2,
  },
});
```

## Install

```bash
npx shadcn@latest add @madeui/switch
```

## Usage

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

<Switch defaultChecked />
```

## Sizes

```tsx
import * as stylex from '@stylexjs/stylex';

import { Label } from '@/components/ui/label';
import { Switch } from '@/components/ui/switch';
import { space } from '@/lib/constants.stylex';

export default function SwitchSizes() {
  return (
    <div {...stylex.props(styles.row)}>
      <Label>
        <Switch size="sm" defaultChecked />
        Small
      </Label>
      <Label>
        <Switch defaultChecked />
        Medium
      </Label>
    </div>
  );
}

const styles = stylex.create({
  row: {
    alignItems: 'center',
    display: 'flex',
    gap: space.s6,
  },
});
```

## Description

Pair `Switch` with `Field`, `FieldContent`, and `FieldDescription` for a labeled setting row.

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

export default function SwitchDescription() {
  return (
    <Field orientation="horizontal">
      <FieldContent>
        <FieldLabel htmlFor="switch-description-marketing">
          Marketing emails
        </FieldLabel>
        <FieldDescription>
          Receive emails about new products and features.
        </FieldDescription>
      </FieldContent>
      <Switch id="switch-description-marketing" />
    </Field>
  );
}
```

## Disabled

```tsx
import * as stylex from '@stylexjs/stylex';

import { Switch } from '@/components/ui/switch';
import { space, fontSize } from '@/lib/constants.stylex';
import { colors, font } from '@/lib/tokens.stylex';

export default function SwitchDisabled() {
  return (
    <label {...stylex.props(styles.label, styles.disabled)}>
      <Switch disabled /> Disabled
    </label>
  );
}

const styles = stylex.create({
  label: {
    alignItems: 'center',
    color: colors.foreground,
    display: 'flex',
    fontFamily: font.sans,
    fontSize: fontSize.sm,
    gap: space.s2,
  },
  disabled: {
    opacity: 0.5,
  },
});
```

## Invalid

Set `invalid` on `Field` to show validation errors — the label and error message pick up the invalid styling, and `aria-invalid` is applied to the switch automatically.

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

export default function SwitchInvalid() {
  return (
    <Field orientation="horizontal" invalid>
      <FieldContent>
        <FieldLabel htmlFor="switch-invalid-two-factor">
          Two-factor authentication
        </FieldLabel>
        <FieldError>Two-factor authentication is required.</FieldError>
      </FieldContent>
      <Switch id="switch-invalid-two-factor" />
    </Field>
  );
}
```

## API reference

Built on [Base UI Switch](https://base-ui.com/react/components/switch). The tables below cover the props this library adds or changes — every other prop is forwarded to the underlying Base UI part; see the [Base UI Switch API reference](https://base-ui.com/react/components/switch#api-reference) for the full list.

### Switch

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `size` | `'sm' \| 'md'` | `'md'` |  |
| `checked` | `boolean` | — | Controlled checked state. |
| `defaultChecked` | `boolean` | `false` |  |
| `onCheckedChange` | `(checked: boolean) => void` | — |  |
| `disabled` | `boolean` | `false` |  |
| `style` | `StyleXStyles` | — | StyleX styles merged last — always win over the component's own styles. |
