BladewindUI: Stepper Component

Stepper

Stepper guides people through a named sequence of related tasks. Each step can reveal its own content panel, which makes the component suitable for account setup, checkout, onboarding, reviews, and other multi-stage forms. The root current value is the canonical initial selection.

<x-bladewind::stepper name="account-setup" current="profile" aria-label="Account setup progress">
    <x-bladewind::stepper.item name="account" label="Account" state="complete" />
    <x-bladewind::stepper.item name="profile" label="Profile" description="Personal details" />
    <x-bladewind::stepper.item name="security" label="Security" />
    <x-bladewind::stepper.content name="account" has-border="false">
        <x-bladewind::card has-shadow="false">Account details</x-bladewind::card>
    </x-bladewind::stepper.content>
    <x-bladewind::stepper.content name="profile" has-border="false">
        <x-bladewind::card has-shadow="false">Profile form</x-bladewind::card>
    </x-bladewind::stepper.content>
    <x-bladewind::stepper.content name="security" has-border="false">
        <x-bladewind::card has-shadow="false">Security options</x-bladewind::card>
    </x-bladewind::stepper.content>
</x-bladewind::stepper>

Visual Styles

Use the style attribute to change how the sequence is presented without changing its content, state, events, or keyboard behavior. The available values are circles, chevrons, bars, and line. Circles is the default and works with both orientations.

StyleHorizontalVerticalBehavior
circlesYesYesDefault numbered or icon indicators with connecting lines.
chevronsYesNoHorizontal-only segmented path. Vertical requests fall back to circles.
barsYesYesTop bars horizontally and side bars vertically.
lineYesYesCompact dots on a horizontal or vertical line.

Chevron style

Chevrons create a connected, bordered path that suits short application and onboarding flows.

Bar style

Bars provide strong stage emphasis with compact labels and work well above full-width forms.

Line style

Line uses smaller markers for a quiet progress treatment. It is useful when the form content should carry most of the visual weight.

Horizontal Stepper

Horizontal is the default orientation and works well when step names are short and the available width is generous. Labels sit below their indicators so connectors remain centred on the circles and never pass through text. When the sequence cannot fit, only the step list scrolls horizontally.

Vertical Stepper

Use orientation="vertical" for narrow regions, longer descriptions, and forms with substantial content. The connector follows the centre of each indicator while the label and description remain in a separate text column.

Step States

Available states are complete, current, upcoming, error, and disabled. Complete and error indicators include icons and screen-reader state text, so meaning does not depend on colour.

Numbered and Icon Steps

Numbers are shown by default and are assigned in list order. Set an explicit number, or use icon, icon-type, and icon-dir on an item.

Labels and Descriptions

Every step requires a short label. Descriptions are optional. Long text wraps without expanding the page.

Linear Wizard

Linear mode is enabled by default and is appropriate when each stage depends on the one before it. Users can return to completed steps, but direct activation cannot skip ahead to an inaccessible step. Run application validation first, then call nextStepperStep() when the current panel is valid.

Non-linear and Clickable Workflow

Set linear="false" when the stages are independent and users may complete them in any order. Enabled indicators can then open their associated panels directly. Set root or item clickable="false" when a stage should be displayed but must be opened by application logic.

Indicator-only Usage

Content panels are recommended for complete wizard interfaces and are used by every working example on this page. You may still omit them when Stepper only communicates the status of a process that is rendered elsewhere. The indicators, states, events, and keyboard behavior continue to work.

<x-bladewind::stepper name="delivery" current="dispatch">
    <x-bladewind::stepper.item name="paid" label="Paid" state="complete" />
    <x-bladewind::stepper.item name="dispatch" label="Dispatch" />
    <x-bladewind::stepper.item name="delivered" label="Delivered" />
</x-bladewind::stepper>

Content Panels

A stepper.content name connects a panel to the item with the same name. Place one panel beside every item when building a wizard. Only the current panel is visible and keyboard reachable; the others are hidden and inert until selected.

Stepper content is a semantic panel, not a Card dependency. This keeps the standalone Stepper package small. Its panel has a border by default. Set has-border="false" when Card or another composed component provides the visible border. Compose Bladewind Card, Input, Textarea, Select, Alert, and other components inside the panel as needed. Every working example on this page uses Card for its visible content surface.

<x-bladewind::stepper.content name="profile" has-border="false">
    <x-bladewind::card has-shadow="false">
        <x-bladewind::input label="Display name" />
        <x-bladewind::textarea label="Biography" />
    </x-bladewind::card>
</x-bladewind::stepper.content>

Use the public helpers from buttons, form handlers, or other application code. All helpers return true on success and false when the stepper, step, or requested movement is unavailable. A successful move updates the indicator, panel, ARIA relationships, state, and focus together.

previousStepperStep('account-setup');
nextStepperStep('account-setup');
showStepperStep('account-setup', 'security');
resetStepper('account-setup');

Validation Event

Listen for the cancelable bladewind:stepper:before-change event and call preventDefault() when the current panel is invalid. The Stepper owns navigation state but does not impose form rules, so validation remains application-owned.

document.querySelector('[data-name="account-setup"]')
    .addEventListener('bladewind:stepper:before-change', (event) => {
        if (!profileFormIsValid()) event.preventDefault();
    });

Multiple Steppers

Each helper resolves one named root. State, panels, focus, and events do not leak between instances. Use a unique root name for every Stepper, even when the step names inside them are identical.

Responsive Behavior, Dark Mode, and RTL

Horizontal lists scroll inside the component on narrow screens, while content panels remain within the page width. Vertical layouts stay fluid. Colours follow the active theme. In RTL, horizontal ordering and Left and Right Arrow behavior follow visual direction. Reduced-motion preferences remove transition timing without disabling navigation.

Accessibility and Keyboard Guidance

  • Provide a specific aria-label for each stepper landmark.
  • The current item uses aria-current="step". Disabled items use native and ARIA disabled semantics.
  • Left and Right Arrow move focus in horizontal layouts. Up and Down Arrow move focus in vertical layouts.
  • Home and End move to the first and last enabled indicators. Disabled steps are skipped.
  • Enter and Space activate a focused clickable indicator.
  • Initial rendering does not steal focus. Explicit navigation moves focus to the new indicator.

Full List of Attributes

Stepper Attributes

AttributeDefaultDescription
namegeneratedUnique public name used by helpers and events.
currentfirst enabled stepCanonical initial current step name.
orientationhorizontalhorizontal or vertical.
stylecirclescircles, chevrons, bars, or line.
lineartrueBlock direct forward navigation when true.
clickabletrueAllow enabled indicators to activate steps.
show-numberstrueShow ordered step numbers when an item has no icon.
completed-iconcheckIcon used for complete steps.
error-iconexclamation-triangleIcon used for error steps.
aria-labelProgressAccessible name for the navigation landmark.
classClasses merged onto the root nav.

Stepper Item Attributes

AttributeDefaultDescription
namerequiredStep name shared with an optional content panel.
labelrequiredVisible step label.
descriptionOptional supporting text.
stateupcomingcomplete, current, upcoming, error, or disabled.
disabledfalseDisable activation and keyboard focus.
clickableroot valueOverride clickability for this item.
numberlist positionExplicit indicator number.
iconIcon component name.
icon-typeoutlineoutline or solid.
icon-dirCustom public icon directory.
classClasses merged onto the indicator button.

Stepper Content Attributes

AttributeDefaultDescription
namerequiredMatches the associated item name.
has-bordertrueShows the panel border. Set to false when a nested Card supplies the visible border.
classClasses merged onto the panel section.
Any HTML attributeForwarded through the Blade attribute bag.

Slots

Component and slotDescription
stepper defaultStepper items and optional content panels.
stepper.item defaultCustom indicator content that replaces the number or icon.
stepper.content defaultWizard panel content.

JavaScript API

Function or eventDescription
showStepperStep(stepperName, stepName)Select an accessible step and synchronize its panel.
nextStepperStep(stepperName)Move to the next enabled step. On the final step, emit completion.
previousStepperStep(stepperName)Move to the previous enabled step.
resetStepper(stepperName)Restore initial states and the canonical initial current step.
bladewind:stepper:before-changeCancelable bubbling event before navigation.
bladewind:stepper:changedBubbling event after a successful change.
bladewind:stepper:completeBubbling event when Next is called on the final enabled step.

Navigation event details contain stepperName, previousStep, nextStep, and direction.

Stepper with all attributes defined

<x-bladewind::stepper
    name="account-setup"
    current="profile"
    orientation="horizontal"
    style="circles"
    linear="true"
    clickable="true"
    show-numbers="true"
    completed-icon="check"
    error-icon="exclamation-triangle"
    aria-label="Account setup progress"
    class="account-stepper">
    <x-bladewind::stepper.item
        name="profile"
        label="Profile"
        description="Personal details"
        state="current"
        disabled="false"
        clickable="true"
        number="2"
        icon="user"
        icon-type="solid"
        icon-dir=""
        class="profile-step" />
    <x-bladewind::stepper.content name="profile" has-border="false" class="profile-panel">
        <x-bladewind::card has-shadow="false">
            <x-bladewind::input label="Display name" />
        </x-bladewind::card>
    </x-bladewind::stepper.content>
</x-bladewind::stepper>
The source file for this component is available in resources > views > components > bladewind > stepper > index.blade.php