Overview of the Phoenix and LiveView Headless Switch Component
The Mishka Chelekom Headless Switch
ships zero opinionated styling
- only the semantic markup, full WAI-ARIA
wiring, and paired-presence state
(
data-checked
/
data-unchecked
).
Every part - root, track, thumb
and label
- is addressable through a
*_class
attribute, so you style it entirely with your own Tailwind
classes while
the accessibility and behavior keep working underneath.
Base UI Switch example (Phoenix headless)
<.switch id="baseui-switch-hero" checked class="group inline-flex items-center gap-2 text-sm font-normal text-neutral-950 select-none dark:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-neutral-950 dark:focus-visible:outline-white" track_class="flex h-5 w-9 shrink-0 items-center border border-neutral-950 bg-white p-0.5 transition-colors duration-150 ease-[ease] dark:border-white dark:bg-neutral-950 group-data-[checked]:bg-neutral-950 dark:group-data-[checked]:bg-white" thumb_class="block size-3.5 bg-neutral-950 transition-[translate,background-color] duration-150 ease-[ease] data-[checked]:translate-x-4 data-[checked]:bg-white dark:bg-white dark:data-[checked]:bg-neutral-950" > Notifications </.switch>
Parts & data attributes
Each part carries a stable
data-part
and a structural
chelekom-switch__*
class you can target, plus paired-presence state for checked/unchecked mirrored on both
the root and the thumb.
| Part | data-part | State / ARIA | Purpose |
|---|---|---|---|
| Root | (button) | role="switch", aria-checked, aria-labelledby, aria-readonly, aria-required, data-checked, data-unchecked, data-disabled, data-readonly, data-required | The clickable control itself. |
| Input | input | aria-hidden | Hidden checkbox that carries the value for form submission. |
| Thumb | thumb | aria-hidden, data-checked, data-unchecked | The sliding dot; mirrors the root's checked state. |
| Label | label | - | Wraps the switch's inner content. |
Accessibility
Follows the
WAI-ARIA Switch pattern
: the root exposes
role="switch"
with a live
aria-checked
(
true
/
false
),
and Enter or Space toggles the state.
readonly
blocks the flip but keeps the control focusable, while
disabled
ignores interaction entirely.