Skip to content

Commit cd3d0e9

Browse files
authored
fix(material/stepper): last step not being marked as interacted (#17976)
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 24d20fb commit cd3d0e9

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

src/cdk/stepper/stepper.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,14 @@ export class CdkStepper implements AfterContentInit, 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) &&
301309
(newIndex >= this._selectedIndex || this.steps.toArray()[newIndex].editable)) {
302310
this._updateSelectedItemIndex(index);
@@ -500,12 +508,8 @@ export class CdkStepper implements AfterContentInit, AfterViewInit, OnDestroy {
500508
}
501509

502510
private _anyControlsInvalidOrPending(index: number): boolean {
503-
const steps = this.steps.toArray();
504-
505-
steps[this._selectedIndex].interacted = true;
506-
507511
if (this._linear && index >= 0) {
508-
return steps.slice(0, index).some(step => {
512+
return this.steps.toArray().slice(0, index).some(step => {
509513
const control = step.stepControl;
510514
const isIncomplete =
511515
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
@@ -1025,6 +1025,28 @@ describe('MatStepper', () => {
10251025
expect(headers[2].classList.contains('mat-primary')).toBe(true);
10261026
expect(headers[1].classList.contains('mat-accent')).toBe(true);
10271027
});
1028+
1029+
it('should be able to mark all steps as interacted', () => {
1030+
const fixture = createComponent(SimpleMatHorizontalStepperApp);
1031+
fixture.detectChanges();
1032+
1033+
const stepper: MatStepper =
1034+
fixture.debugElement.query(By.directive(MatStepper)).componentInstance;
1035+
1036+
expect(stepper.steps.map(step => step.interacted)).toEqual([false, false, false]);
1037+
1038+
stepper.next();
1039+
fixture.detectChanges();
1040+
expect(stepper.steps.map(step => step.interacted)).toEqual([true, false, false]);
1041+
1042+
stepper.next();
1043+
fixture.detectChanges();
1044+
expect(stepper.steps.map(step => step.interacted)).toEqual([true, true, false]);
1045+
1046+
stepper.next();
1047+
fixture.detectChanges();
1048+
expect(stepper.steps.map(step => step.interacted)).toEqual([true, true, true]);
1049+
});
10281050
});
10291051

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

0 commit comments

Comments
 (0)