The Stepper component displays a wizard-like workflow by guiding users through the multi-step progression.
import { StepperModule } from 'primeng/stepper';
Stepper consists of one or more StepperPanel elements to encapsulate each step in the progress. The elements to navigate between the steps are not built-in for ease of customization, instead prevCallback and nextCallback events should be bound to your custom UI elements.
<p-stepper>
<p-stepper-panel header="Header I">
<ng-template pTemplate="content" let-nextCallback="nextCallback" let-index="index">
<div class="flex flex-col h-48">
<div class="border-2 border-dashed border-surface rounded-border bg-surface-50 dark:bg-surface-950 flex-auto flex justify-center items-center font-medium">
Content I
</div>
</div>
<div class="flex pt-6 justify-end">
<p-button
label="Next"
icon="pi pi-arrow-right"
iconPos="right"
(onClick)="nextCallback.emit()" />
</div>
</ng-template>
</p-stepper-panel>
<p-stepper-panel header="Header II">
<ng-template pTemplate="content" let-prevCallback="prevCallback" let-nextCallback="nextCallback" let-index="index">
<div class="flex flex-col h-48">
<div class="border-2 border-dashed border-surface rounded-border bg-surface-50 dark:bg-surface-950 flex-auto flex justify-center items-center font-medium">
Content II
</div>
</div>
<div class="flex pt-6 justify-between">
<p-button
label="Back"
icon="pi pi-arrow-left"
(onClick)="prevCallback.emit()" />
<p-button
label="Next"
icon="pi pi-arrow-right"
iconPos="right"
(onClick)="nextCallback.emit()" />
</div>
</ng-template>
</p-stepper-panel>
<p-stepper-panel header="Header III">
<ng-template pTemplate="content" let-prevCallback="prevCallback" let-index="index">
<div class="flex flex-col h-48">
<div class="border-2 border-dashed border-surface rounded-border bg-surface-50 dark:bg-surface-950 flex-auto flex justify-center items-center font-medium">
Content III
</div>
</div>
<div class="flex pt-6 justify-start">
<p-button label="Back" icon="pi pi-arrow-left" (onClick)="prevCallback.emit()" />
</div>
</ng-template>
</p-stepper-panel>
</p-stepper>
Layout of the Stepper is configured with the orientation property that accepts horizontal and vertical as available options.
<p-stepper orientation="vertical">
<p-stepper-panel header="Header I">
<ng-template pTemplate="content" let-nextCallback="nextCallback" let-index="index">
<div class="flex flex-col h-48">
<div class="border-2 border-dashed border-surface rounded-border bg-surface-50 dark:bg-surface-950 flex-auto flex justify-center items-center font-medium">Content I</div>
</div>
<div class="flex py-6">
<p-button label="Next" (onClick)="nextCallback.emit()" />
</div
></ng-template>
</p-stepper-panel>
<p-stepper-panel header="Header II">
<ng-template pTemplate="content" let-prevCallback="prevCallback" let-nextCallback="nextCallback" let-index="index">
<div class="flex flex-col h-48">
<div class="border-2 border-dashed border-surface rounded-border bg-surface-50 dark:bg-surface-950 flex-auto flex justify-center items-center font-medium">
Content II
</div>
</div>
<div class="flex py-6 gap-2">
<p-button label="Back" severity="secondary" (onClick)="prevCallback.emit()" />
<p-button label="Next" (onClick)="nextCallback.emit()" />
</div>
</ng-template>
</p-stepper-panel>
<p-stepper-panel header="Header III">
<ng-template pTemplate="content" let-prevCallback="prevCallback" let-index="index">
<div class="flex flex-col h-48">
<div class="border-2 border-dashed border-surface rounded-border bg-surface-50 dark:bg-surface-950 flex-auto flex justify-center items-center font-medium">
Content III
</div>
</div>
<div class="flex py-6">
<p-button label="Back" (onClick)="prevCallback.emit()" />
</div>
</ng-template>
</p-stepper-panel>
</p-stepper>
When linear property is present, current step must be completed in order to move to the next step.
<p-stepper [linear]="true">
<p-stepper-panel header="Header I">
<ng-template pTemplate="content" let-nextCallback="nextCallback" let-index="index">
<div class="flex flex-col h-48">
<div class="border-2 border-dashed border-surface rounded-border bg-surface-50 dark:bg-surface-950 flex-auto flex justify-center items-center font-medium">
Content I
</div>
</div>
<div class="flex pt-6 justify-end">
<p-button label="Next" icon="pi pi-arrow-right" iconPos="right" (onClick)="nextCallback.emit()" />
</div>
</ng-template>
</p-stepper-panel>
<p-stepper-panel header="Header II">
<ng-template pTemplate="content" let-prevCallback="prevCallback" let-nextCallback="nextCallback" let-index="index">
<div class="flex flex-col h-48">
<div class="border-2 border-dashed border-surface rounded-border bg-surface-50 dark:bg-surface-950 flex-auto flex justify-center items-center font-medium">
Content II
</div>
</div>
<div class="flex pt-6 justify-between">
<p-button label="Back" icon="pi pi-arrow-left" (onClick)="prevCallback.emit()" />
<p-button label="Next" icon="pi pi-arrow-right" iconPos="right" (onClick)="nextCallback.emit()" />
</div>
</ng-template>
</p-stepper-panel>
<p-stepper-panel header="Header III">
<ng-template pTemplate="content" let-prevCallback="prevCallback" let-index="index">
<div class="flex flex-col h-48">
<div class="border-2 border-dashed border-surface rounded-border bg-surface-50 dark:bg-surface-950 flex-auto flex justify-center items-center font-medium">
Content III
</div>
</div>
<div class="flex pt-6 justify-start">
<p-button label="Back" icon="pi pi-arrow-left" (onClick)="prevCallback.emit()" />
</div>
</ng-template>
</p-stepper-panel>
</p-stepper>
Stepper provides various templating options to customize the default UI design.
<p-stepper [(activeStep)]="active">
<p-stepper-panel>
<ng-template pTemplate="header" let-onClick="onClick" let-index="index">
<button class="bg-transparent border-0 inline-flex flex-col gap-2" (click)="onClick.emit()">
<span
class="rounded-border border-2 w-12 h-12 inline-flex items-center justify-center"
[ngClass]="{
'bg-primary text-primary-contrast border-primary': index <= active,
'border-surface': index > active
}"
>
<i class="pi pi-user"></i>
</span>
</button>
</ng-template>
<ng-template pTemplate="content" let-nextCallback="nextCallback">
<div class="flex flex-col gap-2 mx-auto" style="min-height: 16rem; max-width: 20rem">
<div class="text-center mt-4 mb-4 text-xl font-semibold">Create your account</div>
<div class="field p-fluid">
<p-iconfield>
<p-inputicon>
<i class="pi pi-user"></i>
</p-inputicon>
<input [(ngModel)]="name" pInputText id="input" type="text" placeholder="Name" />
</p-iconfield>
</div>
<div class="field p-fluid">
<p-iconfield>
<p-inputicon>
<i class="pi pi-envelope"></i>
</p-inputicon>
<input [(ngModel)]="email" pInputText id="email" type="email" placeholder="Email" />
</p-iconfield>
</div>
<div class="field p-fluid">
<p-password [(ngModel)]="password" [toggleMask]="true" placeholder="Password" />
</div>
</div>
<div class="flex pt-6 justify-end">
<p-button (onClick)="nextCallback.emit()" label="Next" icon="pi pi-arrow-right" iconPos="right" />
</div>
</ng-template>
</p-stepper-panel>
<p-stepper-panel>
<ng-template pTemplate="header" let-onClick="onClick" let-index="index">
<button class="bg-transparent border-0 inline-flex flex-col gap-2" (click)="onClick.emit()">
<span
class="rounded-border border-2 w-12 h-12 inline-flex items-center justify-center"
[ngClass]="{
'bg-primary text-primary-contrast border-primary': index <= active,
'border-surface': index > active
}"
>
<i class="pi pi-star"></i>
</span>
</button>
</ng-template>
<ng-template pTemplate="content" let-prevCallback="prevCallback" let-nextCallback="nextCallback">
<div class="flex flex-col gap-2 mx-auto" style="min-height: 16rem; max-width: 24rem">
<div class="text-center mt-4 mb-4 text-xl font-semibold">Choose your interests</div>
<div class="flex flex-wrap justify-center gap-4">
<p-togglebutton [(ngModel)]="option1" onLabel="Nature" offLabel="Nature" />
<p-togglebutton [(ngModel)]="option2" onLabel="Art" offLabel="Art" />
<p-togglebutton [(ngModel)]="option3" onLabel="Music" offLabel="Music" />
<p-togglebutton [(ngModel)]="option4" onLabel="Design" offLabel="Design" />
<p-togglebutton [(ngModel)]="option5" onLabel="Photography" offLabel="Photography" />
<p-togglebutton [(ngModel)]="option6" onLabel="Movies" offLabel="Movies" />
<p-togglebutton [(ngModel)]="option7" onLabel="Sports" offLabel="Sports" />
<p-togglebutton [(ngModel)]="option8" onLabel="Gaming" offLabel="Gaming" />
<p-togglebutton [(ngModel)]="option9" onLabel="Traveling" offLabel="Traveling" />
<p-togglebutton [(ngModel)]="option10" onLabel="Dancing" offLabel="Dancing" />
</div>
</div>
<div class="flex pt-6 justify-between">
<p-button (onClick)="prevCallback.emit()" label="Back" severity="secondary" icon="pi pi-arrow-left" />
<p-button (onClick)="nextCallback.emit()" label="Next" icon="pi pi-arrow-right" iconPos="right" />
</div>
</ng-template>
</p-stepper-panel>
<p-stepper-panel>
<ng-template pTemplate="header" let-onClick="onClick" let-index="index">
<button class="bg-transparent border-0 inline-flex flex-col gap-2" (click)="onClick.emit()">
<span
class="rounded-border border-2 w-12 h-12 inline-flex items-center justify-center"
[ngClass]="{
'bg-primary text-primary-contrast border-primary': index <= active,
'border-surface': index > active
}"
>
<i class="pi pi-id-card"></i>
</span>
</button>
</ng-template>
<ng-template pTemplate="content" let-prevCallback="prevCallback">
<div class="flex flex-col gap-2 mx-auto" style="min-height: 16rem; max-width: 24rem">
<div class="text-center mt-4 mb-4 text-xl font-semibold">Account created successfully</div>
<div class="text-center">
<img alt="logo" src="https://primefaces.org/cdn/primeng/images/stepper/content.svg" />
</div>
</div>
<div class="flex pt-6 justify-start">
<p-button (onClick)="prevCallback.emit()" label="Back" severity="secondary" icon="pi pi-arrow-left" />
</div>
</ng-template>
</p-stepper-panel>
</p-stepper>
Stepper container is defined with the tablist role, as any attribute is passed to the container element aria-labelledby can be optionally used to specify an element to describe the Stepper. Each stepper header has a tab role and aria-controls to refer to the corresponding stepper content element. The content element of each stepper has tabpanel role, an id to match the aria-controls of the header and aria-labelledby reference to the header as the accessible name.
Key | Function |
---|---|
tab | Moves focus through the header. |
enter | Activates the focused stepper header. |
space | Activates the focused stepper header. |