---
title: Switch
description: A toggle switch component for boolean states
icon: updated
links:
  rac: Switch
  source: switch/switch.tsx
  styles: switch.css
  storybook: Components/Controls/Switch
  figma: true
---

## Usage

```tsx
import { Switch, SwitchGroup, Label } from '@heroui/react';
```

<ComponentPreview
  name="switch-basic"
/>

## Anatomy

```tsx
import { Switch, Label, Description } from '@heroui/react';

export default () => (
  <Switch>
    <Switch.Control>
      <Switch.Thumb>
        <Switch.Icon/> {/* Optional */}
      </Switch.Thumb>
    </Switch.Control>
    <Switch.Content>
      <Label />
      <Description /> {/* Optional */}
    </Switch.Content>
  </Switch>
);
```

For grouping multiple switches, use the `SwitchGroup` component:

```tsx
import { Switch, SwitchGroup, Label } from '@heroui/react';

export default () => (
  <SwitchGroup>
    <Switch>
      <Switch.Control>
        <Switch.Thumb />
      </Switch.Control>
      <Label>Option 1</Label>
    </Switch>
    <Switch>
      <Switch.Control>
        <Switch.Thumb />
      </Switch.Control>
      <Label>Option 2</Label>
    </Switch>
  </SwitchGroup>
);
```

## Examples

### Sizes

<ComponentPreview
  name="switch-sizes"
/>

### With Icons

<ComponentPreview
  name="switch-with-icons"
/>

### Disabled

<ComponentPreview
  name="switch-disabled"
/>

### Without Label

<ComponentPreview
  name="switch-without-label"
/>

### With Description

<ComponentPreview
  name="switch-with-description"
/>

### Default Selected

<ComponentPreview
  name="switch-default-selected"
/>

### Controlled

<ComponentPreview
  name="switch-controlled"
/>

### Label Position

<ComponentPreview
  name="switch-label-position"
/>

### Group

<ComponentPreview
  name="switch-group"
/>

### Group Horizontal

<ComponentPreview
  name="switch-group-horizontal"
/>

### Form Integration

<ComponentPreview
  name="switch-form"
/>

### Render Props

<ComponentPreview
  name="switch-render-props"
/>

### Render Function

<ComponentPreview
  name="switch-render-function"
/>

## Customization

### Tailwind CSS

<ComponentPreview name="switch-custom-styles" />

### Global CSS

To customize the Switch component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes).

```css
@layer components {
  .switch {
    @apply inline-flex gap-3 items-center;
  }

  .switch__control {
    @apply h-5 w-8 bg-gray-400 data-[selected=true]:bg-blue-500;
  }

  .switch__thumb {
    @apply bg-white shadow-sm;
  }

  .switch__content {
    @apply flex flex-col gap-1;
  }

  .switch__icon {
    @apply h-3 w-3 text-current;
  }
}
```

## Styling Reference

HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize.

### CSS Classes

#### Switch Classes [!toc]

The Switch component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/switch.css)):

- `.switch` - Base switch container
- `.switch__content` - Optional content container
- `.switch__control` - Switch control track
- `.switch__thumb` - Switch thumb that moves
- `.switch__icon` - Optional icon inside the thumb
- `.switch--sm` - Small size variant
- `.switch--md` - Medium size variant (default)
- `.switch--lg` - Large size variant

#### SwitchGroup Classes [!toc]

The SwitchGroup component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/switch-group.css)):

- `.switch-group` - Switch group container
- `.switch-group__items` - Container for switch items
- `.switch-group--horizontal` - Horizontal layout
- `.switch-group--vertical` - Vertical layout (default)

### Interactive States

The switch supports both CSS pseudo-classes and data attributes for flexibility:

- **Selected**: `[data-selected="true"]` (thumb position and background color change)
- **Hover**: `:hover` or `[data-hovered="true"]`
- **Focus**: `:focus-visible` or `[data-focus-visible="true"]` (shows focus ring)
- **Disabled**: `:disabled` or `[aria-disabled="true"]` (reduced opacity, no pointer events)
- **Pressed**: `:active` or `[data-pressed="true"]`

## API Reference

### Switch

Inherits from [React Aria Switch](https://react-spectrum.adobe.com/react-aria/Switch.html).

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | The size of the switch |
| `isSelected` | `boolean` | `false` | Whether the switch is on |
| `defaultSelected` | `boolean` | `false` | Whether the switch is on by default (uncontrolled) |
| `isDisabled` | `boolean` | `false` | Whether the switch is disabled |
| `isInvalid` | `boolean` | `false` | Whether the switch is invalid |
| `isReadOnly` | `boolean` | `false` | Whether the switch is read only |
| `isRequired` | `boolean` | `false` | Whether the switch must be selected |
| `validate` | `(value: boolean) => ValidationError \| true \| null \| undefined` | - | Custom validation function |
| `validationBehavior` | `'native' \| 'aria'` | `'native'` | Whether to use native HTML form validation or ARIA |
| `name` | `string` | - | The name of the input element, used when submitting an HTML form |
| `value` | `string` | - | The value of the input element, used when submitting an HTML form |
| `onChange` | `(isSelected: boolean) => void` | - | Handler called when the switch value changes |
| `onPress` | `(e: PressEvent) => void` | - | Handler called when the switch is pressed |
| `children` | `React.ReactNode \| (values: SwitchRenderProps) => React.ReactNode` | - | Switch content or render prop |
| `render` | `DOMRenderFunction<keyof React.JSX.IntrinsicElements, SwitchRenderProps>` | - | Overrides the default DOM element with a custom render function.|

### Render Props

When using the render prop pattern, these values are provided:

| Prop | Type | Description |
|------|------|-------------|
| `isSelected` | `boolean` | Whether the switch is currently on |
| `isHovered` | `boolean` | Whether the switch is hovered |
| `isPressed` | `boolean` | Whether the switch is currently pressed |
| `isFocused` | `boolean` | Whether the switch is focused |
| `isFocusVisible` | `boolean` | Whether the switch is keyboard focused |
| `isDisabled` | `boolean` | Whether the switch is disabled |
| `isReadOnly` | `boolean` | Whether the switch is read only |
| `isInvalid` | `boolean` | Whether the switch is invalid |
| `isRequired` | `boolean` | Whether the switch is required |
| `state` | `-` | State of the switch. |

### SwitchGroup

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `orientation` | `'horizontal' \| 'vertical'` | `'vertical'` | The orientation of the switch group |
| `children` | `React.ReactNode` | - | The switch items to render |
| `className` | `string` | - | Additional CSS class names |

## Related Components

<RelatedComponents component="switch" />
