diff --git a/src/lib/stepper/stepper-horizontal.html b/src/lib/stepper/stepper-horizontal.html index f64f6e09c9fe..b7a116537b1b 100644 --- a/src/lib/stepper/stepper-horizontal.html +++ b/src/lib/stepper/stepper-horizontal.html @@ -23,6 +23,7 @@
diff --git a/src/lib/stepper/stepper-vertical.html b/src/lib/stepper/stepper-vertical.html index b703aaafe272..72a1f2af45cc 100644 --- a/src/lib/stepper/stepper-vertical.html +++ b/src/lib/stepper/stepper-vertical.html @@ -18,6 +18,7 @@
diff --git a/src/lib/stepper/stepper.spec.ts b/src/lib/stepper/stepper.spec.ts index 46bd4d992e82..dd6a18383888 100644 --- a/src/lib/stepper/stepper.spec.ts +++ b/src/lib/stepper/stepper.spec.ts @@ -12,7 +12,7 @@ import { import {StepperOrientation} from '@angular/cdk/stepper'; import {dispatchKeyboardEvent} from '@angular/cdk/testing'; import {Component, DebugElement} from '@angular/core'; -import {async, ComponentFixture, inject, TestBed} from '@angular/core/testing'; +import {async, ComponentFixture, inject, TestBed, fakeAsync, flush} from '@angular/core/testing'; import { AbstractControl, AsyncValidatorFn, @@ -318,6 +318,28 @@ describe('MatStepper', () => { expect(optionalLabel.textContent).toBe('Valgfri'); })); + + it('should emit an event when the enter animation is done', fakeAsync(() => { + let stepper = fixture.debugElement.query(By.directive(MatStepper)).componentInstance; + let selectionChangeSpy = jasmine.createSpy('selectionChange spy'); + let animationDoneSpy = jasmine.createSpy('animationDone spy'); + let selectionChangeSubscription = stepper.selectionChange.subscribe(selectionChangeSpy); + let animationDoneSubscription = stepper.animationDone.subscribe(animationDoneSpy); + + stepper.selectedIndex = 1; + fixture.detectChanges(); + + expect(selectionChangeSpy).toHaveBeenCalledTimes(1); + expect(animationDoneSpy).not.toHaveBeenCalled(); + + flush(); + + expect(selectionChangeSpy).toHaveBeenCalledTimes(1); + expect(animationDoneSpy).toHaveBeenCalledTimes(1); + + selectionChangeSubscription.unsubscribe(); + animationDoneSubscription.unsubscribe(); + })); }); describe('icon overrides', () => { diff --git a/src/lib/stepper/stepper.ts b/src/lib/stepper/stepper.ts index c8c83263cc4a..b97a9f452f5d 100644 --- a/src/lib/stepper/stepper.ts +++ b/src/lib/stepper/stepper.ts @@ -7,7 +7,8 @@ */ import {Directionality} from '@angular/cdk/bidi'; -import {CdkStep, CdkStepper} from '@angular/cdk/stepper'; +import {CdkStep, CdkStepper, StepContentPositionState} from '@angular/cdk/stepper'; +import {AnimationEvent} from '@angular/animations'; import { AfterContentInit, ChangeDetectionStrategy, @@ -16,9 +17,11 @@ import { ContentChild, ContentChildren, Directive, + EventEmitter, forwardRef, Inject, Optional, + Output, QueryList, SkipSelf, TemplateRef, @@ -82,6 +85,9 @@ export class MatStepper extends CdkStepper implements AfterContentInit { /** Custom icon overrides passed in by the consumer. */ @ContentChildren(MatStepperIcon) _icons: QueryList; + /** Event emitted when the current step is done transitioning in. */ + @Output() readonly animationDone: EventEmitter = new EventEmitter(); + /** Consumer-specified template-refs to be used to override the header icons. */ _iconOverrides: {[key: string]: TemplateRef} = {}; @@ -99,6 +105,12 @@ export class MatStepper extends CdkStepper implements AfterContentInit { // Mark the component for change detection whenever the content children query changes this._steps.changes.pipe(takeUntil(this._destroyed)).subscribe(() => this._stateChanged()); } + + _animationDone(event: AnimationEvent) { + if ((event.toState as StepContentPositionState) === 'current') { + this.animationDone.emit(); + } + } } @Component({