Toggle
Accessible switch: a real <button role="switch"> with aria-checked in sync with state. No hidden checkbox needed; one boolean field controls the visual and the announced state.
Live preview
Markup
<div data-component="toggle-demo" data-label="Email notifications">
<button class="toggle" role="switch" type="button"
@click="flip"
data-class="on:checked, disabled:disabled"
data-bind="aria-checked:checked, aria-disabled:disabled">
<span class="toggle-track"><span class="toggle-thumb"></span></span>
<span class="toggle-label" data-text="label"></span>
</button>
</div>
Definition
Micra.define('toggle-demo', {
state: { checked: false, label: '', disabled: false },
onCreate() {
// this.prop() auto-casts "true"/"false" to booleans, so a default of
// `false` covers both "attribute missing" and "data-checked='false'".
this.state.label = this.prop('label', '')
this.state.checked = this.prop('checked', false)
this.state.disabled = this.prop('disabled', false)
},
flip() {
if (this.state.disabled) return
this.state.checked = !this.state.checked
Micra.emit('toggle:changed', {
label: this.state.label,
checked: this.state.checked,
})
},
})
Integration
- Real semantics. role="switch" + aria-checked let screen readers announce "on" / "off". Wrapping in a <label> isn't needed because the button itself is the labeled target.
- Props from the server. Initial value, label, and disabled flag come in via data-* attrs; read once in onCreate with this.prop().
- Bus notification. Micra.emit('toggle:changed', …) lets any other component (e.g. a save-bar showing "Saving…") react without sharing a parent.
- Keyboard. Native button gives you Space and Enter for free — no extra handler needed.
Pitfalls
- Don't use a hidden checkbox + custom label — the focus order gets weird, the value isn't directly bindable, and aria-checked on the visible control is what assistive tech actually reads.
- Don't put two state fields like on and off — derive one from the other if you must (off() { return !this.state.checked }).
- Don't forget the type="button" attribute when the toggle lives inside a form — without it, pressing Space submits the form.