Skip to content

Commit 6acb98d

Browse files
crisbetojosephperrott
authored andcommitted
fix(overlay): backdrop exit animation not working (#10145)
Fixes the transition when closing an overlay with an opaque backdrop appearing broken. The issue comes the fact that when we start animating the backdrop out, we also remove the `backdropClass` which makes the backdrop transparent. We don't need to remove the class, because we'll remove the backdrop from the DOM and clear the reference once the transition is done.
1 parent b0d9a3d commit 6acb98d

File tree

1 file changed

+31
-29
lines changed

1 file changed

+31
-29
lines changed

src/cdk/overlay/overlay-ref.ts

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -395,43 +395,45 @@ export class OverlayRef implements PortalOutlet, OverlayReference {
395395
detachBackdrop(): void {
396396
let backdropToDetach = this._backdropElement;
397397

398-
if (backdropToDetach) {
399-
let timeoutId: number;
400-
let finishDetach = () => {
401-
// It may not be attached to anything in certain cases (e.g. unit tests).
402-
if (backdropToDetach && backdropToDetach.parentNode) {
403-
backdropToDetach.parentNode.removeChild(backdropToDetach);
404-
}
405-
406-
// It is possible that a new portal has been attached to this overlay since we started
407-
// removing the backdrop. If that is the case, only clear the backdrop reference if it
408-
// is still the same instance that we started to remove.
409-
if (this._backdropElement == backdropToDetach) {
410-
this._backdropElement = null;
411-
}
398+
if (!backdropToDetach) {
399+
return;
400+
}
412401

413-
clearTimeout(timeoutId);
414-
};
402+
let timeoutId: number;
403+
let finishDetach = () => {
404+
// It may not be attached to anything in certain cases (e.g. unit tests).
405+
if (backdropToDetach && backdropToDetach.parentNode) {
406+
backdropToDetach.parentNode.removeChild(backdropToDetach);
407+
}
415408

416-
backdropToDetach.classList.remove('cdk-overlay-backdrop-showing');
409+
// It is possible that a new portal has been attached to this overlay since we started
410+
// removing the backdrop. If that is the case, only clear the backdrop reference if it
411+
// is still the same instance that we started to remove.
412+
if (this._backdropElement == backdropToDetach) {
413+
this._backdropElement = null;
414+
}
417415

418416
if (this._config.backdropClass) {
419-
this._toggleClasses(backdropToDetach, this._config.backdropClass, false);
417+
this._toggleClasses(backdropToDetach!, this._config.backdropClass, false);
420418
}
421419

422-
this._ngZone.runOutsideAngular(() => {
423-
backdropToDetach!.addEventListener('transitionend', finishDetach);
424-
});
420+
clearTimeout(timeoutId);
421+
};
425422

426-
// If the backdrop doesn't have a transition, the `transitionend` event won't fire.
427-
// In this case we make it unclickable and we try to remove it after a delay.
428-
backdropToDetach.style.pointerEvents = 'none';
423+
backdropToDetach.classList.remove('cdk-overlay-backdrop-showing');
429424

430-
// Run this outside the Angular zone because there's nothing that Angular cares about.
431-
// If it were to run inside the Angular zone, every test that used Overlay would have to be
432-
// either async or fakeAsync.
433-
timeoutId = this._ngZone.runOutsideAngular(() => setTimeout(finishDetach, 500));
434-
}
425+
this._ngZone.runOutsideAngular(() => {
426+
backdropToDetach!.addEventListener('transitionend', finishDetach);
427+
});
428+
429+
// If the backdrop doesn't have a transition, the `transitionend` event won't fire.
430+
// In this case we make it unclickable and we try to remove it after a delay.
431+
backdropToDetach.style.pointerEvents = 'none';
432+
433+
// Run this outside the Angular zone because there's nothing that Angular cares about.
434+
// If it were to run inside the Angular zone, every test that used Overlay would have to be
435+
// either async or fakeAsync.
436+
timeoutId = this._ngZone.runOutsideAngular(() => setTimeout(finishDetach, 500));
435437
}
436438

437439
/** Toggles a single CSS class or an array of classes on an element. */

0 commit comments

Comments
 (0)