Skip to content

Commit 0b3d6a8

Browse files
committed
fix(stepper): last step not being marked as interacted
Fixes the last step in the stepper never being marked as `interacted`. Also fixes some weird logic where we were changing the step state inside `_anyControlsInvalidOrPending` which is a getter method. Fixes #17974.
1 parent 527f1b5 commit 0b3d6a8

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

src/cdk/stepper/stepper.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,16 @@ export class CdkStepper implements AfterViewInit, OnDestroy {
297297
throw Error('cdkStepper: Cannot assign out-of-bounds value to `selectedIndex`.');
298298
}
299299

300+
const selectedStep = this.selected;
301+
302+
if (selectedStep) {
303+
// TODO: this should really be called something like `visited` instead. Just because
304+
// the user has seen the step doesn't guarantee that they've interacted with it.
305+
selectedStep.interacted = true;
306+
}
307+
300308
if (this._selectedIndex != newIndex && !this._anyControlsInvalidOrPending(newIndex) &&
301-
(newIndex >= this._selectedIndex || this.steps.toArray()[newIndex].editable)) {
309+
(newIndex >= this._selectedIndex || this._steps.toArray()[newIndex].editable)) {
302310
this._updateSelectedItemIndex(index);
303311
}
304312
} else {
@@ -487,12 +495,8 @@ export class CdkStepper implements AfterViewInit, OnDestroy {
487495
}
488496

489497
private _anyControlsInvalidOrPending(index: number): boolean {
490-
const steps = this.steps.toArray();
491-
492-
steps[this._selectedIndex].interacted = true;
493-
494498
if (this._linear && index >= 0) {
495-
return steps.slice(0, index).some(step => {
499+
return this.steps.toArray().slice(0, index).some(step => {
496500
const control = step.stepControl;
497501
const isIncomplete =
498502
control ? (control.invalid || control.pending || !step.interacted) : !step.completed;

src/material/stepper/stepper.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -937,6 +937,28 @@ describe('MatStepper', () => {
937937

938938
expect(headerRipples.every(ripple => ripple.disabled)).toBe(true);
939939
});
940+
941+
it('should be able to mark all steps as interacted', () => {
942+
const fixture = createComponent(SimpleMatHorizontalStepperApp);
943+
fixture.detectChanges();
944+
945+
const stepper: MatStepper =
946+
fixture.debugElement.query(By.directive(MatStepper)).componentInstance;
947+
948+
expect(stepper.steps.map(step => step.interacted)).toEqual([false, false, false]);
949+
950+
stepper.next();
951+
fixture.detectChanges();
952+
expect(stepper.steps.map(step => step.interacted)).toEqual([true, false, false]);
953+
954+
stepper.next();
955+
fixture.detectChanges();
956+
expect(stepper.steps.map(step => step.interacted)).toEqual([true, true, false]);
957+
958+
stepper.next();
959+
fixture.detectChanges();
960+
expect(stepper.steps.map(step => step.interacted)).toEqual([true, true, true]);
961+
});
940962
});
941963

942964
describe('linear stepper with valid step', () => {

0 commit comments

Comments
 (0)