A control that allows the user to toggle between checked and not checked.
<form>
<div style="display: flex; align-items: center;">
<label
id="switch-airplane-label"
for="switch-airplane-mode"
class="DemoLabel"
style="padding-right: 15px;"
>
Airplane mode
</label>
<Switch.root
id="switch-airplane-mode"
class="DemoSwitchRoot"
aria-labelledby="switch-airplane-label"
>
<Switch.thumb class="DemoSwitchThumb" />
</Switch.root>
</div>
</form>
/* reset */
button {
all: unset;
}
.DemoSwitchRoot {
width: 42px;
height: 25px;
background-color: var(--black-a9);
border-radius: 9999px;
position: relative;
box-shadow: 0 2px 10px var(--black-a7);
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
&:focus {
box-shadow: 0 0 0 2px black;
}
&[data-state="checked"] {
background-color: black;
}
}
.DemoSwitchThumb {
display: block;
width: 21px;
height: 21px;
background-color: white;
border-radius: 9999px;
box-shadow: 0 2px 2px var(--black-a7);
transition: transform 100ms;
transform: translateX(2px);
will-change: transform;
&[data-state="checked"] {
transform: translateX(19px);
}
}
.DemoLabel {
color: white;
font-size: 15px;
line-height: 1;
user-select: none;
}
Anatomy
Import all parts and piece them together.
<Switch.root id="…">
<Switch.thumb />
</Switch.root>
Anatomy
-
Root - Composes `trigger` and `bubble_input` for the default switch experience.
-
Trigger - The interactive button with `role="switch"`.
-
Thumb - The thumb that visually indicates whether the switch is on or off.
-
Bubble Input - The visually hidden native input used for form submission.
API Reference
Root
Contains all the parts of a switch. Renders a trigger and bubble_input; a visually hidden input is included for form submission.
Use checked with on_checked_change for controlled state in LiveView:
<Switch.root id="airplane-mode" checked={@checked} on_checked_change="switch_checked_change">
<Switch.thumb class="DemoSwitchThumb" />
</Switch.root>
def handle_event("switch_checked_change", %{"checked" => checked}, socket) do
{:noreply, assign(socket, :checked, checked == "true" or checked == true)}
end
| Prop | Type | Default | Description |
|---|---|---|---|
checked
|
boolean
|
nil
|
|
default_checked
|
boolean
|
false
|
|
disabled
|
boolean
|
false
|
|
form
|
string
|
nil
|
|
id
|
string
|
—
|
|
name
|
string
|
nil
|
|
on_checked_change
|
string
|
nil
|
|
required
|
boolean
|
false
|
|
value
|
string
|
"on"
|
checked
boolean
Default
nil
default_checked
boolean
Default
false
disabled
boolean
Default
false
form
string
Default
nil
id
string
Default
—
name
string
Default
nil
on_checked_change
string
Default
nil
required
boolean
Default
false
value
string
Default
"on"
Data attributes
| Attribute | Values | Description |
|---|---|---|
[data-state]
|
checked | unchecked
|
Reflects whether the switch is on or off. |
[data-disabled]
|
Present when disabled
|
Present when the switch is disabled. |
Trigger
The clickable button that toggles the switch state. Used directly when decoupling from the hidden input.
| Prop | Type | Default | Description |
|---|---|---|---|
checked
|
boolean
|
nil
|
|
default_checked
|
boolean
|
false
|
|
disabled
|
boolean
|
false
|
|
form
|
string
|
nil
|
|
id
|
string
|
nil
|
|
name
|
string
|
nil
|
|
on_checked_change
|
string
|
nil
|
|
required
|
boolean
|
false
|
|
value
|
string
|
"on"
|
checked
boolean
Default
nil
default_checked
boolean
Default
false
disabled
boolean
Default
false
form
string
Default
nil
id
string
Default
nil
name
string
Default
nil
on_checked_change
string
Default
nil
required
boolean
Default
false
value
string
Default
"on"
Data attributes
| Attribute | Values | Description |
|---|---|---|
[data-state]
|
checked | unchecked
|
Reflects whether the switch is on or off. |
[data-disabled]
|
Present when disabled
|
Present when the switch is disabled. |
Thumb
The thumb that is used to visually indicate whether the switch is on or off.
| Prop | Type | Default | Description |
|---|
Data attributes
| Attribute | Values | Description |
|---|---|---|
[data-state]
|
checked | unchecked
|
Reflects whether the switch is on or off. |
[data-disabled]
|
Present when disabled
|
Present when the switch is disabled. |
Bubble Input
The visually hidden native input that Switch.root renders by default. Omit it when you do not need form submission.
| Prop | Type | Default | Description |
|---|---|---|---|
checked
|
boolean
|
nil
|
|
default_checked
|
boolean
|
false
|
|
disabled
|
boolean
|
false
|
|
form
|
string
|
nil
|
|
name
|
string
|
nil
|
|
required
|
boolean
|
false
|
|
value
|
string
|
"on"
|
checked
boolean
Default
nil
default_checked
boolean
Default
false
disabled
boolean
Default
false
form
string
Default
nil
name
string
Default
nil
required
boolean
Default
false
value
string
Default
"on"
Examples
Decoupling the hidden input
By default, Switch.root renders a visually hidden input for form submission. To recompose, move, or exclude that input, build the switch from trigger and bubble_input instead.
Switch.triggeris the interactive button that wrapsSwitch.thumb.Switch.bubble_inputis the visually hidden input thatSwitch.rootrenders by default. Omit it when you do not need form submission.
Place trigger immediately before bubble_input so the hook can sync state between them.
<Switch.trigger id="airplane-mode" name="airplane-mode" class="DemoSwitchRoot">
<Switch.thumb class="DemoSwitchThumb" />
</Switch.trigger>
<Switch.bubble_input name="airplane-mode" />
Accessibility
Adheres to the switch role requirements.
Keyboard Interactions
Keyboard Interactions
| Key | Description |
|---|---|
Space
|
Toggles the component's state. |
Enter
|
Toggles the component's state. |