diff --git a/src/cdk/stepper/stepper.ts b/src/cdk/stepper/stepper.ts index da2b61dd018c..7379154ec9e2 100644 --- a/src/cdk/stepper/stepper.ts +++ b/src/cdk/stepper/stepper.ts @@ -297,6 +297,14 @@ export class CdkStepper implements AfterContentInit, AfterViewInit, OnDestroy { throw Error('cdkStepper: Cannot assign out-of-bounds value to `selectedIndex`.'); } + const selectedStep = this.selected; + + if (selectedStep) { + // TODO: this should really be called something like `visited` instead. Just because + // the user has seen the step doesn't guarantee that they've interacted with it. + selectedStep.interacted = true; + } + if (this._selectedIndex !== newIndex && !this._anyControlsInvalidOrPending(newIndex) && (newIndex >= this._selectedIndex || this.steps.toArray()[newIndex].editable)) { this._updateSelectedItemIndex(index); @@ -500,12 +508,8 @@ export class CdkStepper implements AfterContentInit, AfterViewInit, OnDestroy { } private _anyControlsInvalidOrPending(index: number): boolean { - const steps = this.steps.toArray(); - - steps[this._selectedIndex].interacted = true; - if (this._linear && index >= 0) { - return steps.slice(0, index).some(step => { + return this.steps.toArray().slice(0, index).some(step => { const control = step.stepControl; const isIncomplete = control ? (control.invalid || control.pending || !step.interacted) : !step.completed; diff --git a/src/material/stepper/stepper.spec.ts b/src/material/stepper/stepper.spec.ts index b7657dbb6f3e..44bb3c334018 100644 --- a/src/material/stepper/stepper.spec.ts +++ b/src/material/stepper/stepper.spec.ts @@ -1025,6 +1025,28 @@ describe('MatStepper', () => { expect(headers[2].classList.contains('mat-primary')).toBe(true); expect(headers[1].classList.contains('mat-accent')).toBe(true); }); + + it('should be able to mark all steps as interacted', () => { + const fixture = createComponent(SimpleMatHorizontalStepperApp); + fixture.detectChanges(); + + const stepper: MatStepper = + fixture.debugElement.query(By.directive(MatStepper)).componentInstance; + + expect(stepper.steps.map(step => step.interacted)).toEqual([false, false, false]); + + stepper.next(); + fixture.detectChanges(); + expect(stepper.steps.map(step => step.interacted)).toEqual([true, false, false]); + + stepper.next(); + fixture.detectChanges(); + expect(stepper.steps.map(step => step.interacted)).toEqual([true, true, false]); + + stepper.next(); + fixture.detectChanges(); + expect(stepper.steps.map(step => step.interacted)).toEqual([true, true, true]); + }); }); describe('linear stepper with valid step', () => {