Skip to content

HyStepper

Usage examples on this page are written for Lit / plain HTML (<hy-stepper>). The same component ships as HyStepper in @whitespaceux/harmony-react (native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.

An ordered, accessible progress stepper. Orchestrates a slotted set of hy-step children: it renders the step rail (indicators, labels, connectors), owns keyboard navigation and the active-step state machine, gates which steps can be reached (linear vs. non-linear), and emits a cancelable before-change plus a change event.

Accessibility model

The rail is an ordered navigation list<nav aria-label><ol><li> per step — NOT a tablist. The current step carries aria-current="step"; completed / upcoming status is conveyed by a visually-hidden text label per step. This is the convergent accessible-stepper pattern (USWDS, Carbon, PatternFly, WAI-ARIA aria-current guidance), not the tab pattern.

Controlled

active-step is controlled, like hy-tab-group's active-panel. The stepper emits intent (before-change, cancelable) and the resulting change; the consumer owns which step is active. The stepper self-manages each child's derived status (completed / active / upcoming), preserving a non-current step that the consumer flagged status="error".

Keyboard

  • Arrow Right/Left (horizontal) or Down/Up (vertical): move focus between navigable steps (roving tabindex).
  • Home / End: first / last navigable step.
  • Enter / Space / Click: activate the focused step (subject to gating and the before-change veto).

Examples

Linear wizard

html
<hy-stepper active-step="0" label="Checkout">
  <hy-step label="Cart"><p>…</p></hy-step>
  <hy-step label="Shipping"><p>…</p></hy-step>
  <hy-step label="Payment"><p>…</p></hy-step>
</hy-stepper>

API

Properties

PropertyAttributeTypeDefaultDescription
activeStepactive-stepnumber0The controlled, 0-indexed active step.
orientationorientation'horizontal' | 'vertical''horizontal'Rail layout direction.
labelPlacementlabel-placement'inline' | 'bottom''inline'Where the label sits relative to the indicator (horizontal only).
nonLinearnon-linearbooleanfalseWhen true, any non-disabled step is reachable; otherwise only steps up to active-step + 1.
labellabelstring'Progress'Accessible name for the <nav> landmark.

Events

EventDetailDescription
changeFired when the active step changes (user or programmatic). Detail: { activeStep: number, previousStep: number }
before-changeCancelable. Fired on a user-initiated step change before change. Call event.preventDefault() to veto (e.g. block advancing until the current step validates). Not fired for programmatic active-step updates. Detail: { activeStep: number, previousStep: number }

Slots

SlotDescription
defaultThe hy-step children.

CSS Parts

PartDescription
baseThe <nav> landmark wrapper.
railThe ordered list of steps.
contentThe active step's content region.

CSS Custom Properties

PropertyDescription
--hy-stepper-indicator-sizeDiameter of the step indicator. Default: var(--hy-indicator-size-lg).
--hy-stepper-gapGap between the rail and the content region. Default: var(--hy-gap-row-nav-md-block).
--hy-stepper-connector-colorConnector line color (incomplete). Default: var(--hy-border-default-rest).
--hy-stepper-connector-color-completeConnector line color (complete). Default: var(--hy-background-success-rest).

Methods

next()

Advance to the next step. Returns true if it moved.

previous()

Go back one step. Returns true if it moved.

goTo()

Jump to a specific step (subject to gating + before-change). Returns true if it moved.

reset()

Reset to the first step and clear any error statuses. Always succeeds; emits change.

Built with Lit. Documented with VitePress.