Switch Toggle
An on/off switch for instant settings — a native with Space/Enter toggling and a sliding thumb. Form-associated; emits a composed change event.
Preview
<esa-switch-toggle label="Email notifications" checked></esa-switch-toggle> Sizes
<esa-switch-toggle label="Extra small" size="xs" checked></esa-switch-toggle>
<esa-switch-toggle label="Small" size="sm" checked></esa-switch-toggle>
<esa-switch-toggle label="Medium" size="md" checked></esa-switch-toggle>
<esa-switch-toggle label="Large" size="lg" checked></esa-switch-toggle> Label position
Place the label after the track (default) or before it.
<esa-switch-toggle label="Label after" checked></esa-switch-toggle>
<esa-switch-toggle label="Label before" label-position="before" checked></esa-switch-toggle> States
<esa-switch-toggle label="Off"></esa-switch-toggle>
<esa-switch-toggle label="On" checked></esa-switch-toggle>
<esa-switch-toggle label="Disabled" disabled></esa-switch-toggle>
<esa-switch-toggle label="Disabled + on" disabled checked></esa-switch-toggle> Form participation
A checked switch submits on under its name; off submits nothing. Submitting logs the alerts entry.
<form>
<esa-switch-toggle label="Enable alerts" name="alerts" checked></esa-switch-toggle>
<button type="submit">Submit</button>
</form> API
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | '' | Text rendered beside the track. |
checked | boolean | false | On/off state of the switch. |
label-position | 'before' | 'after' | 'after' | Whether the label sits before or after the track. |
size | 'xs' | 'sm' | 'md' | 'lg' | 'md' | Track and thumb size. |
disabled | boolean | false | Disables interaction. |
Events
| Event | Type | Default | Description |
|---|---|---|---|
change | CustomEvent<{ checked: boolean }> | — | Fired when toggled. Composed and bubbling; detail.checked is the new state. |
Accessibility
- Renders a native
<button role="switch">witharia-checkedreflecting state. - Keyboard and activation come for free; Space/Enter toggle.
- The
disabledattribute disables the underlying button. - Visible focus ring on the track via
--focus-ring-*tokens.
Theming surface
Every public token this component reads, extracted from its source at build time.
The Resolves to column walks each token's real lineage —
component → semantic → primitive → raw value — so you
can see exactly where re-pointing it lands. A spoke re-skins by overriding these in
its theme-<slug>.css; component internals are never edited. No
hook for what you need? File it with /request-lego.
| Token | Tier | Resolves to |
|---|---|---|
--focus-ring-color | component | #65ba74 via --color-border-focus → --color-grass-8 |
--focus-ring-width | component | 2px |
--switch-toggle-label-color | component | #202020 via --color-text-primary → --color-gray-12 |
--switch-toggle-thumb-bg | component | #fcfcfc via --color-surface → --color-gray-1 |
--switch-toggle-track-bg | component | #bbbbbb via --color-border-strong → --color-gray-8 |
--switch-toggle-track-bg-checked | component | #46a758 via --color-primary → --color-grass-9 |
--focus-ring-offset | semantic | 2px |
--line-height-normal | semantic | 1.6 |
--transition-fast | semantic | 150ms ease |
--type-size-200 | semantic | clamp(0.75rem, 0.66rem + 0.44vw, 0.9375rem) |
--radius-full | primitive | 9999px |
--shadow-50 | primitive | 0 1px 4px 0 rgba(0, 0, 0, 0.03) |
--spacing-200 | primitive | 0.5rem |