Skip to content
Esc
navigateopen⌘Jpreview
On this page

Switch

A control that allows the user to toggle between on and off.

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

npx shadcn@latest add @madeui/switch

Usage

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

<Switch defaultChecked />

Sizes

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.

Receive emails about new products and features.

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

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.

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. 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 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.

Was this page helpful?