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({