@@ -166,7 +166,7 @@ export class MatDialogContainer extends _MatDialogContainerBase implements OnDes
166
166
? parseCssTime ( this . _config . exitAnimationDuration ) ?? CLOSE_ANIMATION_DURATION
167
167
: 0 ;
168
168
/** Current timer for dialog animations. */
169
- private _animationTimer : number | null = null ;
169
+ private _animationTimer : ReturnType < typeof setTimeout > | null = null ;
170
170
171
171
constructor (
172
172
elementRef : ElementRef ,
@@ -221,14 +221,15 @@ export class MatDialogContainer extends _MatDialogContainerBase implements OnDes
221
221
this . _animationStateChanged . emit ( { state : 'opening' , totalTime : this . _openAnimationDuration } ) ;
222
222
223
223
if ( this . _animationsEnabled ) {
224
- // One would expect that the open class is added once the animation finished, but MDC
225
- // uses the open class in combination with the opening class to start the animation.
226
224
this . _hostElement . style . setProperty (
227
225
TRANSITION_DURATION_PROPERTY ,
228
226
`${ this . _openAnimationDuration } ms` ,
229
227
) ;
230
- this . _hostElement . classList . add ( OPENING_CLASS ) ;
231
- this . _hostElement . classList . add ( OPEN_CLASS ) ;
228
+
229
+ // We need to give the `setProperty` call from above some time to be applied.
230
+ // One would expect that the open class is added once the animation finished, but MDC
231
+ // uses the open class in combination with the opening class to start the animation.
232
+ this . _requestAnimationFrame ( ( ) => this . _hostElement . classList . add ( OPENING_CLASS , OPEN_CLASS ) ) ;
232
233
this . _waitForAnimationToComplete ( this . _openAnimationDuration , this . _finishDialogOpen ) ;
233
234
} else {
234
235
this . _hostElement . classList . add ( OPEN_CLASS ) ;
@@ -253,7 +254,9 @@ export class MatDialogContainer extends _MatDialogContainerBase implements OnDes
253
254
TRANSITION_DURATION_PROPERTY ,
254
255
`${ this . _openAnimationDuration } ms` ,
255
256
) ;
256
- this . _hostElement . classList . add ( CLOSING_CLASS ) ;
257
+
258
+ // We need to give the `setProperty` call from above some time to be applied.
259
+ this . _requestAnimationFrame ( ( ) => this . _hostElement . classList . add ( CLOSING_CLASS ) ) ;
257
260
this . _waitForAnimationToComplete ( this . _closeAnimationDuration , this . _finishDialogClose ) ;
258
261
} else {
259
262
// This subscription to the `OverlayRef#backdropClick` observable in the `DialogRef` is
@@ -297,8 +300,7 @@ export class MatDialogContainer extends _MatDialogContainerBase implements OnDes
297
300
298
301
/** Clears all dialog animation classes. */
299
302
private _clearAnimationClasses ( ) {
300
- this . _hostElement . classList . remove ( OPENING_CLASS ) ;
301
- this . _hostElement . classList . remove ( CLOSING_CLASS ) ;
303
+ this . _hostElement . classList . remove ( OPENING_CLASS , CLOSING_CLASS ) ;
302
304
}
303
305
304
306
private _waitForAnimationToComplete ( duration : number , callback : ( ) => void ) {
@@ -310,4 +312,15 @@ export class MatDialogContainer extends _MatDialogContainerBase implements OnDes
310
312
// the related events like `afterClosed` to be inside the zone as well.
311
313
this . _animationTimer = setTimeout ( callback , duration ) ;
312
314
}
315
+
316
+ /** Runs a callback in `requestAnimationFrame`, if available. */
317
+ private _requestAnimationFrame ( callback : ( ) => void ) {
318
+ this . _ngZone . runOutsideAngular ( ( ) => {
319
+ if ( typeof requestAnimationFrame === 'function' ) {
320
+ requestAnimationFrame ( callback ) ;
321
+ } else {
322
+ callback ( ) ;
323
+ }
324
+ } ) ;
325
+ }
313
326
}
0 commit comments