Stepper

A multi-step flow with numbered headers.

Installation

Import the class, and @use the entry point in your global styles: without it the component renders unstyled.

import { Component } from '@angular/core';
import { WrStep, WrStepper } from 'ngwr/stepper';

@Component({ imports: [WrStep, WrStepper] })
export class MyComponent {}

Basic

Bind [(active)] to the step index. A header click jumps to its step.

<wr-stepper [(active)]="step">
  <wr-step label="Account">Account form…</wr-step>
  <wr-step label="Profile" description="Optional">Profile form…</wr-step>
  <wr-step label="Confirm">Review and submit…</wr-step>
</wr-stepper>

Tell us about your account.

Fill in your profile details.

Review and submit.

Linear

With linear, steps past the last completed one are locked. Move with next() and prev().

<wr-stepper #stepper [(active)]="step" linear>
  <wr-step label="One" [completed]="oneDone()">…</wr-step>
  <wr-step label="Two" [completed]="twoDone()">…</wr-step>
  <wr-step label="Three">…</wr-step>
</wr-stepper>

<button (click)="stepper.next()">Next</button>

Step one — click Next to advance.

Step two.

Final step.

PrevNext

Vertical

<wr-stepper [(active)]="step" orientation="vertical">
  <wr-step label="Pick a plan">…</wr-step>
  <wr-step label="Billing">…</wr-step>
  <wr-step label="Done">…</wr-step>
</wr-stepper>

Choose monthly or yearly.

Enter payment details.

All set.

Narrow container (container query)

With responsive, a horizontal stepper turns vertical when it is narrow.

Tell us about your account.

Fill in your profile details.

Review and submit.

<div style="width: 340px"><wr-stepper responsive>…</wr-stepper></div>

API

NameDescriptionTypeDefault
[(active)]Active step index (two-way bindable).number0
orientationLayout direction.'horizontal' | 'vertical''horizontal'
linearLock steps after the latest completed one.booleanfalse
responsiveTurn vertical when the stepper itself is narrow.booleanfalse
next() / prev() / goTo(i)Imperative navigation.method—
<wr-step>.labelHeader text.string''
<wr-step>.descriptionSecondary header text.string''
<wr-step>.optionalMarks the step as optional in the header.booleanfalse
<wr-step>.completedOverride completion. When null, derived from active > index.boolean | nullnull
<wr-step>.disabledBlocks header clicks.booleanfalse

CSS variables

Set these on the component's selector or a wrapper, not on :root: the defaults are declared on ngwr/stepper's own element.

VariableDefaultDeclared on
--wr-stepper-connectorvar(--wr-border-base).wr-stepper
--wr-stepper-connector-margin-blockvar(--wr-space-xs).wr-stepper__connector
--wr-stepper-connector-margin-inlinevar(--wr-space-sm).wr-stepper__connector
--wr-stepper-font-familyvar(--wr-font-family-base).wr-stepper
--wr-stepper-gapvar(--wr-space-lg).wr-stepper
--wr-stepper-header-button-gapvar(--wr-space-md).wr-stepper__header-button
--wr-stepper-header-gapvar(--wr-space-md).wr-stepper__header
--wr-stepper-hint-font-sizevar(--wr-text-xs).wr-stepper__description
--wr-stepper-hint-font-weightvar(--wr-font-weight-medium).wr-stepper__description
--wr-stepper-hint-letter-spacingvar(--wr-tracking-normal).wr-stepper__description +1 variant override
--wr-stepper-indicator-bordervar(--wr-border-base).wr-stepper__indicator
--wr-stepper-indicator-font-sizevar(--wr-text-sm).wr-stepper__indicator
--wr-stepper-indicator-font-weightvar(--wr-font-weight-semibold).wr-stepper__indicator
--wr-stepper-indicator-size1.75rem.wr-stepper
--wr-stepper-label-font-sizevar(--wr-text-sm).wr-stepper__label
--wr-stepper-label-font-weightvar(--wr-font-weight-medium).wr-stepper__label
--wr-stepper-label-gap0.0625rem.wr-stepper__label
--wr-stepper-mutedvar(--wr-color-on-surface-muted).wr-stepper

See also