Toggle

Molecule

role="switch" toggle/switch with three sizes, description slot, and disabled support. Fully accessible via CSS transform without a native input.

Checked

Preview
Code
<%- include('modules/ui/Toggle', { id: 'notif', label: 'Notifications enabled', checked: true }) %>

Unchecked

Preview
Code
<%- include('modules/ui/Toggle', { id: 'dark', label: 'Dark mode' }) %>

No visible label

Preview
Code
<%- include('modules/ui/Toggle', { id: 't', checked: true, ariaLabel: 'Enable notifications' }) %>

Disabled

Preview
Code
<%- include('modules/ui/Toggle', { id: 'a', label: 'Enabled (disabled)', checked: true,  disabled: true }) %>
<%- include('modules/ui/Toggle', { id: 'b', label: 'Disabled option',     checked: false, disabled: true }) %>

Sizes

Preview
Code
<%- include('modules/ui/Toggle', { id: 'sm', label: 'Small',  size: 'sm', checked: true }) %>
<%- include('modules/ui/Toggle', { id: 'md', label: 'Medium', size: 'md', checked: true }) %>
<%- include('modules/ui/Toggle', { id: 'lg', label: 'Large',  size: 'lg', checked: true }) %>

Pending (a write is in flight)

Preview
Code
<%- include('modules/ui/Toggle', { id: 'heater', label: 'Heater', checked: true, pending: true }) %>
<!-- at runtime: document.querySelector('[data-toggle-root="heater"]').__toggle.setPending(false) -->

Mismatch (the device reports another value)

Preview

The device reports a different value.

Code
<%- include('modules/ui/Toggle', { id: 'heater', label: 'Heater', checked: true, mismatch: true, describedBy: 'heater-hint' }) %>
<p id="heater-hint">The device reports a different value.</p>

With description

Preview
Code
<%- include('modules/ui/Toggle', { id: 'marketing', label: 'Marketing emails', description: 'Receive weekly updates.', checked: true }) %>

Settings list (controlled)

Preview

Push notifications

Alerts for new activity

Marketing emails

Weekly updates and offers

Dark mode

Switch to dark theme

Code
<div class="divide-y border rounded-lg">
  <div class="flex items-center justify-between px-4 py-3">
    <div>
      <p class="text-sm font-medium">Push notifications</p>
      <p class="text-xs text-text-secondary">Alerts for new activity</p>
    </div>
    <%- include('modules/ui/Toggle', { id: 'notifications', label: '', ariaLabel: 'Push notifications', checked: true }) %>
  </div>
  <!-- … one row per setting -->
</div>
Source modules/ui/Toggle.ejs