SwitchUpdated
A toggle switch component for boolean states
Import
import { Switch, SwitchGroup, Label } from '@heroui/react';Usage
Anatomy
Import the Switch component and access all parts using dot notation.
import { Switch, Description, FieldError } from '@heroui/react';
export default () => (
<Switch>
<Switch.Content>
<Switch.Control>
<Switch.Thumb>
<Switch.Icon /> {/* Optional */}
</Switch.Thumb>
</Switch.Control>
Label {/* plain text — the clickable label + accessible name */}
</Switch.Content>
<Description /> {/* Optional — field-level help text */}
<FieldError /> {/* Optional — validation message */}
</Switch>
);For grouping multiple switches, use the SwitchGroup component:
import { Switch, SwitchGroup, Label } from '@heroui/react';
export default () => (
<SwitchGroup>
<Switch>
<Switch.Content>
<Switch.Control>
<Switch.Thumb />
</Switch.Control>
Option 1
</Switch.Content>
</Switch>
<Switch>
<Switch.Content>
<Switch.Control>
<Switch.Thumb />
</Switch.Control>
Option 2
</Switch.Content>
</Switch>
</SwitchGroup>
);Disabled
Default Selected
Controlled
Without Label
Sizes
Label Position
With Icons
With Description
Group
Group Horizontal
Render Props
Form Integration
Custom Styles
Custom Render Function
Styling
Passing Tailwind CSS classes
You can customize individual Switch components:
import { Switch, Label } from '@heroui/react';
function CustomSwitch() {
return (
<Switch>
{({isSelected}) => (
<>
<Switch.Control
className={`h-[31px] w-[51px] bg-blue-500 ${isSelected ? "bg-cyan-500 shadow-[0_0_12px_rgba(6,182,212,0.5)]" : ""}`}
>
<Switch.Thumb
className={`size-[27px] bg-white shadow-sm ${isSelected ? "translate-x-5 shadow-lg" : ""}`}
/>
</Switch.Control>
Custom Switch
</>
)}
</Switch>
);
}Or customize the SwitchGroup layout:
import { Switch, SwitchGroup, Label } from '@heroui/react';
function CustomSwitchGroup() {
return (
<SwitchGroup className="gap-8" orientation="horizontal">
<Switch>
<Switch.Content>
<Switch.Control>
<Switch.Thumb />
</Switch.Control>
Option 1
</Switch.Content>
</Switch>
<Switch>
<Switch.Content>
<Switch.Control>
<Switch.Thumb />
</Switch.Control>
Option 2
</Switch.Content>
</Switch>
</SwitchGroup>
);
}Customizing the component classes
To customize the Switch component classes, you can use the @layer components directive.
Learn more.
@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 items-center gap-3;
}
.switch__icon {
@apply h-3 w-3 text-current;
}
}HeroUI follows the BEM methodology to ensure component variants and states are reusable and easy to customize.
CSS Classes
Switch Classes
The Switch component uses these CSS classes (View source styles):
.switch- Base switch container (the field).switch__content- Clickable label wrapping the control and label text.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
The SwitchGroup component uses these CSS classes (View source styles):
.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:
:hoveror[data-hovered="true"]onSwitch.Control(button) - Focus:
:focus-visibleor[data-focus-visible="true"]on the button (shows focus ring on track) - Disabled:
[data-disabled="true"]on the field (reduced opacity, including help text) - Pressed:
:activeor[data-pressed="true"]
API Reference
Switch Props
Inherits from React Aria SwitchField.
| 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: SwitchFieldRenderProps) => React.ReactNode | - | Switch content or field render prop |
render | DOMRenderFunction<keyof React.JSX.IntrinsicElements, SwitchFieldRenderProps> | - | Overrides the default DOM element with a custom render function. |
Switch.Content Props
The clickable <label> that wraps the control and label text. Put Switch.Control and the Label inside it; keep Description/FieldError as siblings of Switch.Content. For a switch with no label, omit the Label and pass an aria-label on Switch.
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | (values: SwitchButtonRenderProps) => React.ReactNode | - | Button content (control + label), or a button render prop |
className | string | (values: SwitchButtonRenderProps) => string | - | Classes applied to the clickable label |
SwitchFieldRenderProps
When using a render prop on the root Switch, these field-level values are provided:
| Prop | Type | Description |
|---|---|---|
isSelected | boolean | Whether the switch is currently on |
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 | ToggleState | State of the switch |
SwitchButtonRenderProps
Switch.Control uses button-level render props (isHovered, isPressed, isFocusVisible, etc.). Pass a function as Switch.Control children to access them.
SwitchGroup Props
| 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 |







