To implement a customized stepper component, you will need to create a new one tailored to your specific requirements. In my case, I needed a vertical stepper that could display a summary of completed steps. Fortunately, all the necessary code for this custom component is available on GitHub.
Start by copying a few essential files from https://github.com/angular/components/tree/master/src/material/stepper into a designated folder in your project:
- stepper-horizontal.html
- stepper.scss
After importing these files, proceed to create a new custom stepper component based on the new layout. Let's name it CustomHorizontalStepper
.
custom-horizontal-stepper.ts
// Importing required modules and components
import { MatStepper, matStepperAnimations } from "@angular/material";
// Defining the properties and functionalities of CustomHorizontalStepper component
@Component({
selector: 'custom-horizontal-stepper',
exportAs: 'customHorizontalStepper',
templateUrl: 'stepper-horizontal.html',
styleUrls: ['stepper.css'],
inputs: ['selectedIndex'],
host: {
'class': 'mat-stepper-horizontal',
'[class.mat-stepper-label-position-end]': 'labelPosition == "end"',
'[class.mat-stepper-label-position-bottom]': 'labelPosition == "bottom"',
'aria-orientation': 'horizontal',
'role': 'tablist',
},
animations: [matStepperAnimations.horizontalStepTransition],
// Setting up providers and configurations
providers: [
{provide: MatStepper, useExisting: CustomHorizontalStepper},
{provide: CdkStepper, useExisting: CustomHorizontalStepper}
],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CustomHorizontalStepper extends MatStepper {
/** Specify whether the label should be displayed at the bottom or end */
@Input()
labelPosition: 'bottom' | 'end' = 'end';
static ngAcceptInputType_editable: BooleanInput;
static ngAcceptInputType_optional: BooleanInput;
static ngAcceptInputType_completed: BooleanInput;
static ngAcceptInputType_hasError: BooleanInput;
}
Next, make alterations to the stepper-horizontal.html
file as specified below:
stepper-horizontal.html
<div class="mat-horizontal-content-container">
<div *ngFor="let step of steps; let i = index"
class="mat-horizontal-stepper-content" role="tabpanel"
[@stepTransition]="_getAnimationDirection(i)"
(@stepTransition.done)="_animationDone.next($event)"
[id]="_getStepContentId(i)"
[attr.aria-labelledby]="_getStepLabelId(i)"
[attr.aria-expanded]="selectedIndex === i">
<ng-container [ngTemplateOutlet]="step.content"></ng-container>
</div>
</div>
<div class="mat-horizontal-stepper-header-container">
<ng-container *ngFor="let step of steps; let i = index; let isLast = last">
<mat-step-header class="mat-horizontal-stepper-header"
(click)="step.select()"
(keydown)="_onKeydown($event)"
[tabIndex]="_getFocusIndex() === i ? 0 : -1"
[id]="_getStepLabelId(i)"
// Include other relevant attributes here
</mat-step-header>
<div *ngIf="!isLast" class="mat-stepper-horizontal-line"></div>
</ng-container>
</div>
Once you have adjusted the HTML template, remember to register your custom component in the module and utilize it in your application just like the standard stepper component, but using the newly defined selector.
<custom-horizontal-stepper></custom-horizontal-stepper>