Documents v0.9.0 · previews run the real runtime · experimental features are marked exp

Step wizard

Three steps with Back and Next buttons, a step list you can click, and aria-current on the current step.

Live previewreal runtime

Use Next and Back, or click a step in the list.

How it works

  • state()line 2Makes each matching element the owner of an independent state with an initial value.
  • :on()lines 5, 6, 7An event rule: when the event happens on the matched element (or inside it, for bubbling events), the rule’s state mutations run. The cascade picks one winning mutation per state, per trigger and per element.
  • set()lines 5, 6, 7Sets a state to a value. In an :on() rule it is a mutation of the state on the left, --x: set(5), with typed expressions.
  • :nth-var()lines 9, 10Matches the sibling whose one-based index equals the integer value of a custom property or state, read on the parent.
  • --attr-*lines 10, 13, 14--attr-<name>: <value> writes one allowlisted HTML attribute of the matched element from a reactive value: ARIA states such as aria-expanded, aria-checked or aria-disabled, disabled, hidden, tabindex or data-*. The only custom-property namespace with DOM semantics.

One number state drives a multi-step flow from three directions: the step list, Next and Back. Next and Back compute their value at the click, clamped with min() and max(), so the step stays between 1 and 3.

Native CSS alternative

None: CSS has no counter that a button can change.

Limitations

  • The steps do not validate anything: this example shows navigation only.

Implementation

2 files · 14 lines
style.cssreactive
/* ---- Reactive CSS -------------------------------------------------------------------------- */.wizard { --step: state(1); }/* The list item's position is the step: the buttons are the only child of each li. */.wizard li:on(click) { --step: set(sibling-index()); }.wizard .next:on(click) { --step: set(min(var(--step) + 1, 3)); }.wizard .back:on(click) { --step: set(max(var(--step) - 1, 1)); }.wizard .panel:nth-var(--step) { display: block; }.wizard li:nth-var(--step) .step { background: var(--ink); color: #fff; --attr-aria-current: step; }/* No Back on the first step, no Next on the last: disabled, so they leave the Tab order too. */.wizard:when(--step == 1) .back { --attr-disabled: true; }.wizard:when(--step == 3) .next { --attr-disabled: true; }
state()Function · hover any red tokenMakes each matching element the owner of an independent state with an initial value.Reference →

Source: site/src/catalog/interfaces/step-wizard/. style.css from its Reactive CSS divider; the layout above it and the shared api.css run but are not shown.

Related

Pricing toggle

A billing switch changes the price and shows the annual saving, with role="switch" kept in sync.

experimentalstate()toggle()--attr-*when()content

Tabs

Tabs selected by click or arrow keys, with the ARIA tab pattern written from one state.

experimentalstate():on()cycle():nth-var()--attr-*focus:

Accordion

Each item opens and closes on its own, and its button reports the state with aria-expanded.

experimentalstate()toggle()--attr-*when()