# Switch

URL: https://ark-ui.com/docs/components/switch
LLM: https://ark-ui.com/llms.txt/components/switch

A control element that allows for a binary selection.

---



## Anatomy



```tsx
<Switch.Root>
  <Switch.Control>
    <Switch.Thumb />
  </Switch.Control>
  <Switch.Label />
  <Switch.HiddenInput />
</Switch.Root>
```

## Examples

```tsx
import { Switch } from '@ark-ui/react/switch'
import styles from 'styles/switch.module.css'

export const Basic = () => (
  <Switch.Root className={styles.Root}>
    <Switch.Control className={styles.Control}>
      <Switch.Thumb className={styles.Thumb} />
    </Switch.Control>
    <Switch.Label className={styles.Label}>Label</Switch.Label>
    <Switch.HiddenInput />
  </Switch.Root>
)
```

### Controlled

For a controlled Switch component, the state of the toggle is managed using the checked prop, and updates when the
`onCheckedChange` event handler is called:

```tsx
import { Switch } from '@ark-ui/react/switch'
import { useState } from 'react'
import styles from 'styles/switch.module.css'

export const Controlled = () => {
  const [checked, setChecked] = useState(false)

  return (
    <Switch.Root className={styles.Root} checked={checked} onCheckedChange={(e) => setChecked(e.checked)}>
      <Switch.Control className={styles.Control}>
        <Switch.Thumb className={styles.Thumb} />
      </Switch.Control>
      <Switch.Label className={styles.Label}>Label</Switch.Label>
      <Switch.HiddenInput />
    </Switch.Root>
  )
}
```

### Root Provider

An alternative way to control the switch is to use the `RootProvider` component and the `useSwitch` hook. This way you
can access the state and methods from outside the component.

```tsx
import { Switch, useSwitch } from '@ark-ui/react/switch'
import button from 'styles/button.module.css'
import styles from 'styles/switch.module.css'

export const RootProvider = () => {
  const _switch = useSwitch()

  return (
    <div className="stack">
      <button className={button.Root} onClick={() => _switch.toggleChecked()}>
        Toggle
      </button>

      <Switch.RootProvider className={styles.Root} value={_switch}>
        <Switch.Control className={styles.Control}>
          <Switch.Thumb className={styles.Thumb} />
        </Switch.Control>
        <Switch.Label className={styles.Label}>Label</Switch.Label>
        <Switch.HiddenInput />
      </Switch.RootProvider>
    </div>
  )
}
```

### Field

The `Field` component helps manage form-related state and accessibility attributes of a switch. It includes handling
ARIA labels, helper text, and error text to ensure proper accessibility.

```tsx
import { Field } from '@ark-ui/react/field'
import { Switch } from '@ark-ui/react/switch'
import field from 'styles/field.module.css'
import styles from 'styles/switch.module.css'

export const WithField = () => (
  <Field.Root className={field.Root}>
    <Switch.Root className={styles.Root}>
      <Switch.Control className={styles.Control}>
        <Switch.Thumb className={styles.Thumb} />
      </Switch.Control>
      <Switch.Label className={styles.Label}>Label</Switch.Label>
      <Switch.HiddenInput />
    </Switch.Root>
    <Field.HelperText className={field.HelperText}>Additional Info</Field.HelperText>
    <Field.ErrorText className={field.ErrorText}>Error Info</Field.ErrorText>
  </Field.Root>
)
```

### Context

Access the switch's state with `Switch.Context` or the `useSwitchContext` hook. This lets you customize the component
based on its current state:

```tsx
import { Switch } from '@ark-ui/react/switch'
import styles from 'styles/switch.module.css'

export const Context = () => (
  <Switch.Root className={styles.Root}>
    <Switch.Control className={styles.Control}>
      <Switch.Thumb className={styles.Thumb} />
    </Switch.Control>
    <Switch.Context>
      {(context) => (
        <Switch.Label className={styles.Label}>Feature is {context.checked ? 'enabled' : 'disabled'}</Switch.Label>
      )}
    </Switch.Context>
    <Switch.HiddenInput />
  </Switch.Root>
)
```

## Guides

### asChild

The `Switch.Root` element of the switch is a `label` element. This is because the switch is a form control and should be
associated with a label to provide context and meaning to the user. Otherwise, the HTML and accessibility structure will
be invalid.

> If you need to use the `asChild` property, make sure that the `label` element is the direct child of the `Switch.Root`
> component.

## API Reference

### Props

### Root

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

**`checked`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: The controlled checked state of the switch

**`disabled`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the switch is disabled.

**`ids`**
Type: `Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string }>`
Required: false
Default Value: `undefined`
Description: The ids of the elements in the switch. Useful for composition.

**`invalid`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: If `true`, the switch is marked as invalid.

**`label`**
Type: `string`
Required: false
Default Value: `undefined`
Description: Specifies the localized strings that identifies the accessibility elements and their states

**`name`**
Type: `string`
Required: false
Default Value: `undefined`
Description: The name of the input field in a switch
(Useful for form submission).

**`onCheckedChange`**
Type: `(details: CheckedChangeDetails) => void`
Required: false
Default Value: `undefined`
Description: Function to call when the switch is clicked.

**`readOnly`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the switch is read-only

**`required`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: If `true`, the switch input is marked as required,

**`value`**
Type: `string | number`
Required: false
Default Value: `"on"`
Description: The value of switch input. Useful for form submission.

#### Data Attributes

**`data-active`**: Present when active or pressed
**`data-focus`**: Present when focused
**`data-focus-visible`**: Present when focused with keyboard
**`data-readonly`**: Present when read-only
**`data-hover`**: Present when hovered
**`data-disabled`**: Present when disabled
**`data-state`**: "checked" | "unchecked"
**`data-invalid`**: Present when invalid
**`data-required`**: Present when required

### Control

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-active`**: Present when active or pressed
**`data-focus`**: Present when focused
**`data-focus-visible`**: Present when focused with keyboard
**`data-readonly`**: Present when read-only
**`data-hover`**: Present when hovered
**`data-disabled`**: Present when disabled
**`data-state`**: "checked" | "unchecked"
**`data-invalid`**: Present when invalid
**`data-required`**: Present when required

### HiddenInput

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### Label

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-active`**: Present when active or pressed
**`data-focus`**: Present when focused
**`data-focus-visible`**: Present when focused with keyboard
**`data-readonly`**: Present when read-only
**`data-hover`**: Present when hovered
**`data-disabled`**: Present when disabled
**`data-state`**: "checked" | "unchecked"
**`data-invalid`**: Present when invalid
**`data-required`**: Present when required

### RootProvider

#### Props

**`value`**
Type: `UseSwitchReturn`
Required: true
Default Value: `undefined`
Description: undefined

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### Thumb

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-active`**: Present when active or pressed
**`data-focus`**: Present when focused
**`data-focus-visible`**: Present when focused with keyboard
**`data-readonly`**: Present when read-only
**`data-hover`**: Present when hovered
**`data-disabled`**: Present when disabled
**`data-state`**: "checked" | "unchecked"
**`data-invalid`**: Present when invalid
**`data-required`**: Present when required

### Context

**API:**

| Property | Type | Description |
|----------|------|-------------|
| `checked` | `boolean` | Whether the switch is checked |
| `disabled` | `boolean | undefined` | Whether the switch is disabled |
| `focused` | `boolean | undefined` | Whether the switch is focused |
| `setChecked` | `(checked: boolean) => void` | Sets the checked state of the switch. |
| `toggleChecked` | `VoidFunction` | Toggles the checked state of the switch. |


## Accessibility

Complies with the [Switch WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/switch/).

### Keyboard Support

**`Space + Enter`**
Description: Toggle the switch