# Switch

Toggles a single setting on or off.

## Installation

```tsx
import { Switch } from "@makeplane/propel/components/switch";
```
## Usage

```tsx
import { Switch } from "@makeplane/propel/components/switch";
import * as React from "react";

export default function BasicDemo() {
  const [checked, setChecked] = React.useState(true);

  return (
    <Switch
      size="md"
      aria-label="Enable notifications"
      checked={checked}
      onCheckedChange={setChecked}
    />
  );
}
```
## Examples

### Sizes

`size` sets the track, in the order Figma lists it: `lg` 30×18, `md` 27×16, `sm` 23×14 px. The
thumb derives from the track and is not its own axis. Every track is under WCAG 2.5.8's 24px
floor, so each size carries a transparent ring that brings the pointer target up to it.

```tsx
import { Switch, type SwitchSize } from "@makeplane/propel/components/switch";

const SIZES: SwitchSize[] = ["lg", "md", "sm"];

export default function SizesDemo() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      {SIZES.map((size) => (
        <Switch key={size} size={size} defaultChecked aria-label={`Size ${size}`} />
      ))}
    </div>
  );
}
```

### States

Switches read as off, on, disabled, or read-only. A disabled _on_ switch dims to 40% opacity; a disabled _off_ switch swaps to a solid muted track instead. Read-only dims either state without blocking the pointer.

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

export default function StatesDemo() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <Switch size="md" defaultChecked aria-label="On" />
      <Switch size="md" defaultChecked={false} aria-label="Off" />
      <Switch size="md" defaultChecked disabled aria-label="Disabled on" />
      <Switch size="md" defaultChecked={false} disabled aria-label="Disabled off" />
      <Switch size="md" defaultChecked readOnly aria-label="Read only on" />
      <Switch size="md" defaultChecked={false} readOnly aria-label="Read only off" />
    </div>
  );
}
```

### With description

```tsx
import { SwitchField } from "@makeplane/propel/components/switch-field";

export default function WithDescriptionDemo() {
  return (
    <SwitchField
      name="restartOnFailure"
      label="Restart on failure"
      description="Automatically restart the service after a crash."
      switchSize="md"
      size="lg"
      defaultChecked
    />
  );
}
```

### Native button

The switch renders as a `<span>` by default, so the simplest way to label it is wrapping it in a `<label>` element. When the label needs to be a sibling instead — wired up with `htmlFor`/`id` rather than a wrapper — pass `nativeButton` and a host element via `render` (typically `<button type="button" />`). The styled track (and its `size`) stay on `Switch`; only the underlying element swaps. The look is unchanged, and clicking the sibling label still toggles the switch.

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

export default function NativeButtonDemo() {
  return (
    <div className="flex items-center gap-2">
      <Switch
        size="md"
        defaultChecked
        id="notifications-switch"
        nativeButton
        render={<button type="button" />}
      />
      <label htmlFor="notifications-switch" className="text-body-xs-regular text-secondary">
        Notifications
      </label>
    </div>
  );
}
```
## API Reference

### Switch

The ready-made switch: grafts Base UI's `Switch` behavior onto the styled `Switch` track and
`SwitchThumb` knob. The track owns the required `size`; the thumb sizes itself from it. Base UI
supplies `role="switch"` and full keyboard/form support. Maps to Figma's "Toggle" component.

On/off, `disabled`, and `readOnly` are control state from the primitive, not variants — pass them
as props (`checked`/`defaultChecked`, `disabled`, `readOnly`). Only the size axis (`size`) is a
visual variant.

When `nativeButton` is set, pass a host element via `render` (typically `<button type="button"
/>`) — `size` still lives on this component and is applied to the styled track that wraps the
host, so callers do not re-specify size on `SwitchTrack`.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `size` (required) | `"lg" \| "md" \| "sm"` | — | The switch size axis. |
| `render` | `ReactElement<unknown, string \| JSXElementConstructor<any>> \| ComponentRenderFn<HTMLProps, SwitchRootState>` | — | 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. |
