j3w1 / SwitchVue · HTML · React · Astro

J3W1 / DESIGN SYSTEM

Switch

An on/off control that takes effect immediately; a button with role switch and aria-checked, drawn as a square-cornered track with a square thumb that fills with the primary colour when on.

stable · LIGHT DOM · 1.1.0

Light DOM retains static content, native semantics, label relationships and host composition without duplicating controls.

Live variants

default

<j3w1-switch id="example-switch-default"><button class="switch" type="button" role="switch" aria-checked="false" aria-label="Wrap long lines">
  <span class="switch-track"><span class="switch-thumb"></span></span>
</button></j3w1-switch>

with-labels

Follow system theme

<j3w1-switch id="example-switch-with-labels"><div class="switch-row">
  <span class="switch-name" id="example-switch-with-labels-sw-follow-name">Follow system theme</span>
  <button class="switch" type="button" role="switch" aria-checked="false" aria-labelledby="example-switch-with-labels-sw-follow-name">
    <span class="switch-track"><span class="switch-thumb"></span></span>
    <span class="switch-state" aria-hidden="true"><span class="switch-state-off">Off</span><span class="switch-state-on">On</span></span>
  </button>
</div></j3w1-switch>

Install and register

Use the exact version. If npm publication is pending, install the release tarball from the installation guide.

npm install --save-exact @j3w1/ui@1.1.0
import '@j3w1/ui/tokens.css';
import '@j3w1/ui/styles/switch.css';
import '@j3w1/ui/register/switch';

Insert the maintained markup above after loading these imports. Its native children provide accessible names and form behavior; the empty custom tag alone does not create a control.

Vue SFC, React, Astro and plain HTML integration →

Copy the complete implementation

npx --package=@j3w1/ui@1.1.0 j3w1-ui copy switch --out ./vendor/j3w1/switch

The CLI verifies every file before writing and refuses overwrites. Serve the output over HTTP and open index.html. Keep its modules, CSS, tokens and licence notices together.

Public API

attributes

NameType / signatureMeaning
disabledCustomEventDisable the native controls owned by this instance.
loadingCustomEventMark the primary control busy and prevent duplicate activation.
checkedCustomEventDefault switch checked.
valueCustomEventDefault switch value.

properties

NameType / signatureMeaning
disabledbooleanDelegates disabled state to native children.
namestringNative control name; application form keys remain explicit.
checkedbooleanImmediate switch state; a named switch exposes a matching native hidden form value.

methods

NameType / signatureMeaning
refresh(): voidReconnect behavior after replacing native child structure.
focus(options?: FocusOptions): voidFocus the first usable native control.

events

NameType / signatureMeaning
j3w1-changeCustomEventThe user toggled the switch.

Dependencies and verification

Registered components: none. Style dependencies: none.

Package presence establishes an available implementation. Actual passes depend on the tested artifact and environment. Read specification execution evidence; read packed-consumer evidence; inspect the complete state matrix.

Full implementation manifest, API and token dependency closure

Canonical specification

Purpose

A setting that turns on or off the moment it is toggled: notifications, wrap lines, follow system theme. A choice that is only applied on submit is a checkbox. The switch is a button because it acts; it is not a form field.

Anatomy

A <button role="switch">; inside it the track, a 32×16px box with square corners, and the thumb, a 10px square that sits at the start when off and at the end when on. The with-labels variant adds a visible name before the button and an “Off” / “On” word after the track.

States

StateVisualNon-colour channel
defaulttrack 1px color.border.control on color.surface.input; thumb color.text.default at the startthumb position
hovertrack background → color.interaction.hover.bg; on track → color.action.primary.hover-bgcursor: pointer; hover-capable pointers only
focus-visiblering 1px dashed color.interaction.focus.ring at −2px on the trackthe ring
checkedtrack fills color.action.primary.bg; thumb color.action.primary.text moves to the end; border stays color.border.control; the word reads “On”aria-checked="true"; thumb position; the word
checked+focus-visiblethe fill and a ring in color.interaction.focus.ring-container on the trackposition and ring
disabledtrack color.interaction.disabled.bg with 1px color.border.disabled; thumb and name color.text.disableddisabled; cursor: not-allowed
checked+disabledas disabled with the thumb at the enddisabled; aria-checked="true"; thumb position

The thumb moves without animation by default; a host may transition transform for at most 120ms under prefers-reduced-motion: no-preference. Precedence: disabled > checked > hover; focus-visible is always drawn.

Keyboard

Space and Enter toggle. Nothing else is bound; there is no arrow-key movement between switches. Focus never moves as a result of toggling.

Accessibility

role="switch" on a native button gives the correct name, role and value with the button’s own keyboard handling; only aria-checked is scripted. The name states what is on (“Wrap long lines”), never the current value; the “Off” / “On” word is aria-hidden because assistive technology reads aria-checked. The state is also carried by thumb position and, in the with-labels variant, the word. Contrast: thumb 8.65:1 on the off track, 9.28:1 on the on track; track edge 4.45:1; ring 4.69:1 off, 5.57:1 on.

Portability

Two nested rectangles, a border and a fill; the thumb position is layout, not a transform, so it survives hosts with no animation. Hosts with a native switch use it, square it, and map the two fills.

Non-examples

A pill-shaped track or a round thumb. A switch that only takes effect on submit. A checkbox input styled as a switch. Colour as the only difference between on and off. A green on colour. A label that reads “On” as the name. Disabling by opacity. A sliding animation longer than 120ms or one that runs under reduced motion.

j3w1 / command

  • SPEC Overview
  • SPEC Foundations
  • SPEC Components
  • SPEC Patterns
  • SPEC Tokens
  • SPEC Tools
  • SPEC Implement
  • SPEC For agents
  • SPEC Ports
  • SPEC Releases
  • DEMO Vue application demo
  • SPEC Complete UI theme specification