# Switch

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Switch } from "@/components/starwind/switch";
---

<Switch id="demo-switch" label="Switch" />
```
  </div>
  <div slot="react">
```tsx
import { Switch } from "@/components/starwind/switch";

export function Example() {
  return (
    <>
      <Switch id="demo-switch" label="Switch" />
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Switch } from "@/components/starwind/switch";
</script>

<template>
  <Switch id="demo-switch" label="Switch" />
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Installation

```bash
npx starwind@latest add switch --framework astro
```
</DocsTabsContent>
```bash
npx starwind@latest add switch --framework react
```
</DocsTabsContent>
```bash
npx starwind@latest add switch --framework vue
```
</DocsTabsContent>
</DocsTabs>

## Usage

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Switch } from "@/components/starwind/switch";
---

<Switch id="demo-switch" label="Switch" />
```
  </div>
  <div slot="react">
```tsx
import { Switch } from "@/components/starwind/switch";

export function Example() {
  return (
    <>
      <Switch id="demo-switch" label="Switch" />
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Switch } from "@/components/starwind/switch";
</script>

<template>
  <Switch id="demo-switch" label="Switch" />
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Variants

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Switch } from "@/components/starwind/switch";
---

<Switch id="default" label="Default" variant="default" defaultChecked />
<Switch id="primary" label="Primary" variant="primary" defaultChecked />
<Switch id="secondary" label="Secondary" variant="secondary" defaultChecked />
<Switch id="info" label="Info" variant="info" defaultChecked />
<Switch id="success" label="Success" variant="success" defaultChecked />
<Switch id="warning" label="Warning" variant="warning" defaultChecked />
<Switch id="error" label="Error" variant="error" defaultChecked />
```
  </div>
  <div slot="react">
```tsx
import { Switch } from "@/components/starwind/switch";

export function Example() {
  return (
    <>
      <Switch id="default" label="Default" variant="default" defaultChecked />
      <Switch id="primary" label="Primary" variant="primary" defaultChecked />
      <Switch id="secondary" label="Secondary" variant="secondary" defaultChecked />
      <Switch id="info" label="Info" variant="info" defaultChecked />
      <Switch id="success" label="Success" variant="success" defaultChecked />
      <Switch id="warning" label="Warning" variant="warning" defaultChecked />
      <Switch id="error" label="Error" variant="error" defaultChecked />
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Switch } from "@/components/starwind/switch";
</script>

<template>
  <Switch id="default" label="Default" variant="default" defaultChecked />
  <Switch id="primary" label="Primary" variant="primary" defaultChecked />
  <Switch id="secondary" label="Secondary" variant="secondary" defaultChecked />
  <Switch id="info" label="Info" variant="info" defaultChecked />
  <Switch id="success" label="Success" variant="success" defaultChecked />
  <Switch id="warning" label="Warning" variant="warning" defaultChecked />
  <Switch id="error" label="Error" variant="error" defaultChecked />
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Sizes

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Switch } from "@/components/starwind/switch";
---

<Switch id="small" label="Small" size="sm" />
<Switch id="medium" label="Medium" size="md" />
<Switch id="large" label="Large" size="lg" />
```
  </div>
  <div slot="react">
```tsx
import { Switch } from "@/components/starwind/switch";

export function Example() {
  return (
    <>
      <Switch id="small" label="Small" size="sm" />
      <Switch id="medium" label="Medium" size="md" />
      <Switch id="large" label="Large" size="lg" />
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Switch } from "@/components/starwind/switch";
</script>

<template>
  <Switch id="small" label="Small" size="sm" />
  <Switch id="medium" label="Medium" size="md" />
  <Switch id="large" label="Large" size="lg" />
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Event Handling

Whenever toggled, the Switch root emits `starwind:checked-change`. Read the next state from
`event.detail.checked`.

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Switch } from "@/components/starwind/switch";
---

<div class="mt-8 space-y-4">
  <h2 class="text-xl font-semibold">Switch Event Test</h2>

  <div class="space-y-4">
    <Switch id="test-switch" label="Test Switch" variant="primary" />

    <div id="status-display" class="text-muted-foreground text-sm">
      Switch is currently: <span class="text-foreground font-medium">off</span>
    </div>
  </div>
</div>

<script>
  const root = document.querySelector<HTMLElement>("#test-switch");
  const output = document.querySelector<HTMLElement>("#status-display span");

  root?.addEventListener("starwind:checked-change", (event) => {
    const { checked } = (event as CustomEvent<{ checked: boolean }>).detail;
    if (output) output.textContent = checked ? "on" : "off";
  });
</script>
```
  </div>
  <div slot="react">
```tsx
import { useState } from "react";
import { Switch } from "@/components/starwind/switch";

export function Example() {
  const [checked, setChecked] = useState(false);

  return (
    <div className="mt-8 space-y-4">
      <h2 className="text-xl font-semibold">Switch Event Test</h2>
      <div className="space-y-4">
        <Switch
          id="test-switch"
          label="Test Switch"
          variant="primary"
          checked={checked}
          onCheckedChange={setChecked}
        />
        <div className="text-muted-foreground text-sm">
          Switch is currently:{" "}
          <span className="text-foreground font-medium">{checked ? "on" : "off"}</span>
        </div>
      </div>
    </div>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { Switch } from "@/components/starwind/switch";
import { ref } from "vue";
const checked = ref(false);
</script>

<template>
  <div class="mt-8 space-y-4">
    <h2 class="text-xl font-semibold">Switch Event Test</h2>

    <div class="space-y-4">
      <Switch v-model:checked="checked" id="test-switch" label="Test Switch" variant="primary" />

      <div id="status-display" class="text-muted-foreground text-sm">
        Switch is currently:
        <span class="text-foreground font-medium">{{ checked ? "on" : "off" }}</span>
      </div>
    </div>
  </div>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## API Reference
### Switch
| Prop | Type | Required | Default | Kind | Description |
| --- | --- | --- | --- | --- | --- |
| `defaultChecked` | `boolean` | No | - | Primitive override | Sets the initial checked state when the choice is uncontrolled. |
| `id` | `string` | Yes | - | Primitive override | Sets the element id used by labels and related controls. |
| `label` | `string` | No | - | Wrapper prop | Provides accessible text for the component. |
| `padding` | `number` | No | - | Wrapper prop | Sets the component's internal padding. |
| `size` | `"sm" \| "md" \| "lg"` | No | `"md"` | Styled variant | Selects the component's visual size. |
| `variant` | `"primary" \| "secondary" \| "default" \| "info" \| "success" \| "warning" \| "error"` | No | `"default"` | Styled variant | Selects the component's visual variant. |
- Inherits button attributes. Omits `aria-checked`, `defaultChecked`, `onChange`, `role`, and `type`.
### Primitive And Runtime API
Behavior, state, events, form participation, and imperative methods are documented in the lower-level references.
- Primitive: [Switch Primitive](/docs/primitives/switch/)
- Runtime factory: [`createSwitch`](/docs/runtime/#create-switch) from `@starwind-ui/runtime/switch`

## Changelog

### v2.0.1

- Updated React Runtime state synchronization so canceled proposals stay uncommitted and accepted changes remain aligned.
- Associated the React Switch with its native form owner for submission and reset behavior.

### v2.0.0

- Rebuilt Switch on Starwind Runtime for checked state, native form participation, and checked-change events.
- See the [Switch Primitive](/docs/primitives/switch/) for the underlying unstyled anatomy and behavior API.

### v1.3.3

- Refactor tailwind variants functions into separate `variants.ts` file

### v1.3.1

- Add `starwind:init` event listener to enable initialization of additional Switches loaded after an initial page load, such as when using server islands

### v1.3.0

- style and focus state updates

### v1.2.0

- Add a `data-slot` attribute to all components to enable global styling updates

### v1.1.0

- `tailwind-variants` now implemented. This uses `tailwind-merge` under the hood to merge Tailwind classes without style conflicts, allowing you to override any existing classes using the "class" prop.