GitHub

Switch Toggle

An on/off switch for instant settings — a native

<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

PropTypeDefaultDescription
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

EventTypeDefaultDescription
change CustomEvent<{ checked: boolean }> Fired when toggled. Composed and bubbling; detail.checked is the new state.

Accessibility

  • Renders a native <button role="switch"> with aria-checked reflecting state.
  • Keyboard and activation come for free; Space/Enter toggle.
  • The disabled attribute 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.

TokenTierResolves 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