Skip to content
HyperUX Experimental
Demo

Stepper pattern for linear progress with selectable steps, optional view-only step clicks, and previous/next controls.

Contact details

Capture the customer name, email, and phone number.

Shipping information

Collect shipping address and delivery preferences.

Payment method

Confirm card details and billing information.

Alpine.js Stepper

huxStepper manages active step state for linear or direct-navigation flows. Use it as a base primitive for Wizard-style experiences where each stage has its own content, validation, and completion rules.

Runtime Constraints

No special browser or runtime constraints beyond Alpine.js initialization.

API

huxStepper(config)

Returns an Alpine data object with:

Internal helper methods are private implementation details and are not part of the supported API contract.

Options

Quick Start

<div
  x-data="huxStepper({
    stepItems: [
      { label: 'Contact', id: 'contact' },
      { label: 'Shipping', id: 'shipping' },
      { label: 'Payment', id: 'payment' }
    ]
  })"
>
  <ol aria-label="Checkout steps">
    <template x-for="stepItem in stepItems" x-bind:key="stepItem.id">
      <li>
        <button
          type="button"
          x-bind:id="`step-${stepItem.id}`"
          x-bind:aria-controls="`step-panel-${stepItem.id}`"
          x-bind:aria-current="isStepCurrent(stepItem.id) ? 'step' : null"
          x-on:click="goToStep(stepItem.id)"
          x-text="stepItem.label"
        ></button>
      </li>
    </template>
  </ol>

  <section
    id="step-panel-contact"
    role="region"
    aria-labelledby="step-contact"
    aria-live="polite"
    x-show="activeStepId === 'contact'"
    x-cloak
  >
    ...
  </section>

  <button type="button" x-bind:disabled="isFirstStep" x-on:click="goToPreviousStep()">
    Previous
  </button>
  <button type="button" x-bind:disabled="isLastStep" x-on:click="goToNextStep()">Next</button>
</div>

Common Usage Patterns

Set an Explicit Initial Step

huxStepper({
  stepsAreViewable: true,
  activeStep: 'shipping',
  stepItems: [
    { label: 'Contact', id: 'contact' },
    { label: 'Shipping', id: 'shipping' },
    { label: 'Payment', id: 'payment' },
  ],
})

Subscribe to Change Events for Decoupled Composition

Use id to emit changes and coordinate external UI or validation logic.

huxStepper({
  id: 'checkout',
  stepItems: [
    { label: 'Contact', id: 'contact' },
    { label: 'Shipping', id: 'shipping' },
    { label: 'Payment', id: 'payment' },
  ],
})
window.addEventListener('hux-stepper:checkout:change', (event) => {
  const { stepId, stepIndex, totalSteps } = event.detail
  console.log(stepId, stepIndex, totalSteps)
})

Behavior Contract

Error Handling

Accessibility Notes

Notes