Prototype Library

Switch Toggle

An on/off switch for instant settings — a native <button role="switch"> with Space/Enter toggling and a sliding thumb. Form-associated; emits a composed change event.

Inherited wc import '@esa/ecology/esa-switch-toggle';

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

PropTypeDefaultDescription
label string '' Text rendered beside the track.
size 'xs' | 'sm' | 'md' | 'lg' 'md' Track and thumb size.
disabled boolean false Disables interaction.
name string | undefined — Form field name — the key this control submits under.
label-position 'before' | 'after' 'after' Whether the label sits before or after the track. Property: `labelPosition`.
checked boolean false On/off state of the switch.

Events

EventTypeDefaultDescription
change CustomEvent<{ checked: boolean }> — Fired when toggled. Composed and bubbling; detail.checked is the new state.
Binding these events from Angular

Every one of these is a CustomEvent, so the payload is on $event.detail — $event.target.value reads empty, with no error. The names are lowercase and Angular passes them to addEventListener verbatim, so camel-casing one means it never fires.

  • (change)="onChange($event.detail)"

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.