Skip to content

Commit a5ab8e9

Browse files
authored
fix(material/tooltip): decouple removal logic from change detection (#19432)
* fix(material/tooltip): decouple removal logic from change detection Currently the logic in the tooltip that removes it from the DOM is run either if the trigger is destroyed or the exit animation has finished. The problem is that if the trigger is detached from change detection, but hasn't been destroyed, the exit animation will never run and the element won't be cleaned up. These changes switch to using CSS animations and manipulating the DOM node directly to trigger the animation. Fixes #19365. * fixup! fix(material/tooltip): decouple removal logic from change detection
1 parent 5edcc68 commit a5ab8e9

File tree

13 files changed

+344
-194
lines changed

13 files changed

+344
-194
lines changed

src/material-experimental/mdc-tooltip/testing/tooltip-harness.ts

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ export class MatTooltipHarness extends _MatTooltipHarnessBase {
1414
protected _optionalPanel =
1515
this.documentRootLocatorFactory().locatorForOptional('.mat-mdc-tooltip');
1616
static hostSelector = '.mat-mdc-tooltip-trigger';
17+
protected _hiddenClass = 'mat-mdc-tooltip-hide';
18+
protected _showAnimationName = 'mat-mdc-tooltip-show';
19+
protected _hideAnimationName = 'mat-mdc-tooltip-hide';
1720

1821
/**
1922
* Gets a `HarnessPredicate` that can be used to search
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
<div
2+
#tooltip
23
class="mdc-tooltip mdc-tooltip--shown mat-mdc-tooltip"
34
[ngClass]="tooltipClass"
4-
[class.mdc-tooltip--multiline]="_isMultiline"
5-
[@state]="_visibility"
6-
(@state.start)="_animationStart()"
7-
(@state.done)="_animationDone($event)">
5+
(animationend)="_handleAnimationEnd($event)"
6+
[class.mdc-tooltip--multiline]="_isMultiline">
87
<div class="mdc-tooltip__surface mdc-tooltip__surface-animation">{{message}}</div>
98
</div>

src/material-experimental/mdc-tooltip/tooltip.scss

+40
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
.mat-mdc-tooltip {
77
// We don't use MDC's positioning so this has to be relative.
88
position: relative;
9+
transform: scale(0);
910

1011
// Increases the area of the tooltip so the user's pointer can go from the trigger directly to it.
1112
&::before {
@@ -18,8 +19,47 @@
1819
z-index: -1;
1920
position: absolute;
2021
}
22+
23+
&._mat-animation-noopable {
24+
animation: none;
25+
transform: scale(1);
26+
}
2127
}
2228

2329
.mat-mdc-tooltip-panel-non-interactive {
2430
pointer-events: none;
2531
}
32+
33+
// TODO(crisbeto): we may be able to use MDC directly for these animations.
34+
35+
@keyframes mat-mdc-tooltip-show {
36+
0% {
37+
opacity: 0;
38+
transform: scale(0.8);
39+
}
40+
41+
100% {
42+
opacity: 1;
43+
transform: scale(1);
44+
}
45+
}
46+
47+
@keyframes mat-mdc-tooltip-hide {
48+
0% {
49+
opacity: 1;
50+
transform: scale(1);
51+
}
52+
53+
100% {
54+
opacity: 0;
55+
transform: scale(0.8);
56+
}
57+
}
58+
59+
.mat-mdc-tooltip-show {
60+
animation: mat-mdc-tooltip-show 150ms cubic-bezier(0, 0, 0.2, 1) forwards;
61+
}
62+
63+
.mat-mdc-tooltip-hide {
64+
animation: mat-mdc-tooltip-hide 75ms cubic-bezier(0.4, 0, 1, 1) forwards;
65+
}

0 commit comments

Comments
 (0)