Toggle

A switch that turns something on or off immediately, implementing the full ARIA switch pattern in Alpine over a hidden checkbox.

<x-atlas::toggle>

<x-atlas::toggle name="notifications" label="Email notifications" />
Preview follows the site's light/dark mode. Open standalone →

Reach for a toggle when flipping it takes effect straight away — a setting, a preference, a feature being switched on. When the answer only counts once the form is submitted, use a checkbox instead.

The switch pattern

Nothing here is a native switch, because HTML has none. The visible control is a custom element that Alpine drives into the full ARIA switch pattern, and a hidden checkbox rides along so forms still work:

  • role="switch" with aria-checked bound to the Alpine checked value, so screen readers announce on and off rather than a nameless element.
  • tabindex="0" puts the switch in the tab order — and -1 takes it back out while disabled.
  • Click, Space and Enter all toggle it. Space and Enter are bound with .prevent, so the page neither scrolls nor submits.
  • The real <input type="checkbox"> is hidden, aria-hidden, tabindex="-1" and bound with x-model. It is invisible to assistive technology and to the keyboard, but it is what the form posts.
  • Every rule in the stylesheet keys off aria-checked and aria-disabled, so the visual state is the announced state by construction.

On and off

<x-atlas::toggle name="two-factor" label="Two-factor authentication" checked />
<x-atlas::toggle name="beta-features" label="Beta features" />
Preview follows the site's light/dark mode. Open standalone →

Disabled

disabled is held in the same Alpine scope as checked, so the click and keydown handlers check it before doing anything — the switch cannot be flipped, and it is skipped when tabbing through the page.

<x-atlas::toggle name="sso" label="Single sign-on" checked disabled />
<x-atlas::toggle name="audit-log" label="Audit log" disabled />
Preview follows the site's light/dark mode. Open standalone →

Submitted value

name defaults to a generated toggle-… string, which is fine for a switch wired up in JavaScript and useless for one you intend to read on the server. Set both name and value in a form.

<x-atlas::toggle name="visibility" value="public" label="Publish this page" checked />
Preview follows the site's light/dark mode. Open standalone →

Reference

<x-atlas::toggle>

  • Name
    name
    Type
    string
    Default
    default: toggle-{uniqid}
    Description
    Name of the hidden checkbox that is submitted. Set it explicitly whenever the value is read server-side.
  • Name
    label
    Type
    string
    Default
    default: null
    Description
    Accessible name. It is merged onto the switch as aria-label, so it is never visible.
  • Name
    value
    Type
    string
    Default
    default: 1
    Description
    Value submitted while the toggle is on. Nothing is submitted while it is off.
  • Name
    checked
    Type
    bool
    Default
    default: false
    Description
    Initial state of the Alpine <code>checked</code> value.
  • Name
    disabled
    Type
    bool
    Default
    default: false
    Description
    Blocks clicks and key presses, sets aria-disabled, and drops the switch out of the tab order.