Switch
stimeo--switch
An accessible on/off toggle button driven entirely by aria-checked.
The stimeo--switch controller implements the WAI-ARIA Switch pattern. The control's state lives solely in aria-checked; clicking or pressing Space/Enter toggles it, and an stimeo--switch:changed event is dispatched with the new boolean state. The library provides behavior only — styling (keyed off aria-checked) is owned by this Playground.
Keyboard
| Key | Action |
|---|---|
| Space / Enter | Toggle the switch on or off. |
<%# Markup for the switch (APG Switch) demo.
The controller element itself is a role="switch" button, with state expressed only via
aria-checked. Space/Enter and click toggle it. The look switches on aria-checked in
the Playground's CSS. %>
<button
type="button"
class="switch"
role="switch"
aria-checked="false"
data-controller="stimeo--switch"
data-action="click->stimeo--switch#toggle keydown->stimeo--switch#onKeydown">
<span class="switch__track" aria-hidden="true"><span class="switch__thumb"></span></span>
<span class="switch__label"><%= t("components.switch.demo.label") %></span>
</button>
/*
* Presentation-only styles for the switch demo.
* On/off is expressed via aria-checked (set by the library).
*/
.switch {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0;
background: transparent;
border: 0;
cursor: pointer;
font-size: 1rem;
}
.switch__track {
position: relative;
width: 2.75rem;
height: 1.5rem;
border-radius: 999px;
background: var(--border-strong);
transition: background 0.15s ease;
}
.switch[aria-checked="true"] .switch__track {
background: var(--accent);
}
.switch__thumb {
position: absolute;
top: 0.125rem;
left: 0.125rem;
width: 1.25rem;
height: 1.25rem;
border-radius: 50%;
background: var(--surface-card);
transition: transform 0.15s ease;
}
.switch[aria-checked="true"] .switch__thumb {
transform: translateX(1.25rem);
}
.switch__label {
color: var(--fg);
}
This demo needs no consumer-side JS (the controller handles the behavior).
These demo styles use shared design tokens (light + dark). Copy the shared styles too, then toggle data-theme on your root element for dark mode.
The data-* attributes you add to your own HTML to wire this component. Put the data-controller below on a root element, then place its targets / values / actions inside that element.
On the root element
data-controller="stimeo--switch"
Actions
| Name | Description | Action |
|---|---|---|
onKeydown
|
Activates the switch on Space/Enter for non-button hosts (native buttons are skipped). | stimeo--switch#onKeydown |
toggle
|
Toggles the on/off state via aria-checked. |
stimeo--switch#toggle |
Events
| Name | Description | Event |
|---|---|---|
changed
|
Dispatched on every toggle, with the new checked boolean in detail. |
stimeo--switch:changed |
State hooks
The library only manages these ARIA/data attributes and custom properties. Your CSS reads them to render the look — selectors like [aria-selected], [aria-expanded], or var(--stimeo--…) hook into this state.
| Hook | Target | Meaning |
|---|---|---|
aria-checked |
Root element | "true" when on, "false" when off. |