@@ -39,7 +39,8 @@ import {
39
39
import { FormControl , FormGroupDirective , NgForm } from '@angular/forms' ;
40
40
import { DOCUMENT } from '@angular/common' ;
41
41
import { ErrorStateMatcher } from '@angular/material/core' ;
42
- import { takeUntil } from 'rxjs/operators' ;
42
+ import { Subject } from 'rxjs' ;
43
+ import { takeUntil , distinctUntilChanged } from 'rxjs/operators' ;
43
44
44
45
import { MatStepHeader } from './step-header' ;
45
46
import { MatStepLabel } from './step-label' ;
@@ -102,18 +103,26 @@ export class MatStepper extends _CdkStepper implements AfterContentInit {
102
103
/** Consumer-specified template-refs to be used to override the header icons. */
103
104
_iconOverrides : { [ key : string ] : TemplateRef < MatStepperIconContext > } = { } ;
104
105
106
+ /** Stream of animation `done` events when the body expands/collapses. */
107
+ _animationDone = new Subject < AnimationEvent > ( ) ;
108
+
105
109
ngAfterContentInit ( ) {
106
- const icons = this . _icons . toArray ( ) ;
107
- icons . forEach ( ( { name, templateRef} ) => this . _iconOverrides [ name ] = templateRef ) ;
110
+ this . _icons . forEach ( ( { name, templateRef} ) => this . _iconOverrides [ name ] = templateRef ) ;
108
111
109
112
// Mark the component for change detection whenever the content children query changes
110
113
this . _steps . changes . pipe ( takeUntil ( this . _destroyed ) ) . subscribe ( ( ) => this . _stateChanged ( ) ) ;
111
- }
112
114
113
- _animationDone ( event : AnimationEvent ) {
114
- if ( ( event . toState as StepContentPositionState ) === 'current' ) {
115
- this . animationDone . emit ( ) ;
116
- }
115
+ this . _animationDone . pipe (
116
+ // This needs a `distinctUntilChanged` in order to avoid emitting the same event twice due
117
+ // to a bug in animations where the `.done` callback gets invoked twice on some browsers.
118
+ // See https://github.com/angular/angular/issues/24084
119
+ distinctUntilChanged ( ( x , y ) => x . fromState === y . fromState && x . toState === y . toState ) ,
120
+ takeUntil ( this . _destroyed )
121
+ ) . subscribe ( event => {
122
+ if ( ( event . toState as StepContentPositionState ) === 'current' ) {
123
+ this . animationDone . emit ( ) ;
124
+ }
125
+ } ) ;
117
126
}
118
127
}
119
128
0 commit comments