Skip to content

Commit fb516c0

Browse files
committed
fixup! fix(material/tooltip): decouple removal logic from change detection
1 parent af09cc4 commit fb516c0

File tree

6 files changed

+27
-25
lines changed

6 files changed

+27
-25
lines changed

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
class="mdc-tooltip mdc-tooltip--shown mat-mdc-tooltip"
44
[ngClass]="tooltipClass"
55
(animationend)="_handleAnimationEnd($event)"
6-
[class._mat-animation-noopable]="_animationsDisabled"
76
[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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
&._mat-animation-noopable {
2424
animation: none;
25-
transform: none;
25+
transform: scale(1);
2626
}
2727
}
2828

src/material/tooltip/tooltip.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@
22
class="mat-tooltip"
33
(animationend)="_handleAnimationEnd($event)"
44
[ngClass]="tooltipClass"
5-
[class._mat-animation-noopable]="_animationsDisabled"
65
[class.mat-tooltip-handset]="(_isHandset | async)?.matches">{{message}}</div>

src/material/tooltip/tooltip.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ $handset-margin: 24px;
2020

2121
&._mat-animation-noopable {
2222
animation: none;
23-
transform: none;
23+
transform: scale(1);
2424
}
2525

2626
@include a11y.high-contrast(active, off) {

src/material/tooltip/tooltip.ts

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -860,7 +860,7 @@ export abstract class _TooltipComponentBase implements OnDestroy {
860860
_mouseLeaveHideDelay: number;
861861

862862
/** Whether animations are currently disabled. */
863-
_animationsDisabled: boolean;
863+
private _animationsDisabled: boolean;
864864

865865
/** Reference to the internal tooltip element. */
866866
abstract _tooltip: ElementRef<HTMLElement>;
@@ -895,15 +895,9 @@ export abstract class _TooltipComponentBase implements OnDestroy {
895895
// Cancel the delayed hide if it is scheduled
896896
clearTimeout(this._hideTimeoutId);
897897

898-
// Body interactions should cancel the tooltip if there is a delay in showing.
899-
this._closeOnInteraction = true;
900898
this._showTimeoutId = setTimeout(() => {
901-
this._toogleVisibility(true);
899+
this._toggleVisibility(true);
902900
this._showTimeoutId = undefined;
903-
904-
// Mark for check so if any parent component has set the
905-
// ChangeDetectionStrategy to OnPush it will be checked anyways
906-
this._markForCheck();
907901
}, delay);
908902
}
909903

@@ -916,12 +910,8 @@ export abstract class _TooltipComponentBase implements OnDestroy {
916910
clearTimeout(this._showTimeoutId);
917911

918912
this._hideTimeoutId = setTimeout(() => {
919-
this._toogleVisibility(false);
913+
this._toggleVisibility(false);
920914
this._hideTimeoutId = undefined;
921-
922-
// Mark for check so if any parent component has set the
923-
// ChangeDetectionStrategy to OnPush it will be checked anyways
924-
this._markForCheck();
925915
}, delay);
926916
}
927917

@@ -984,30 +974,45 @@ export abstract class _TooltipComponentBase implements OnDestroy {
984974

985975
/** Handles the cleanup after an animation has finished. */
986976
private _finalizeAnimation(toVisible: boolean) {
987-
if (!toVisible && !this.isVisible()) {
977+
if (toVisible) {
978+
this._closeOnInteraction = true;
979+
} else if (!this.isVisible()) {
988980
this._onHide.next();
989981
}
990-
991-
this._closeOnInteraction = true;
992982
}
993983

994984
/** Toggles the visibility of the tooltip element. */
995-
private _toogleVisibility(isVisible: boolean) {
985+
private _toggleVisibility(isVisible: boolean) {
996986
// We set the classes directly here ourselves so that toggling the tooltip state
997987
// isn't bound by change detection. This allows us to hide it even if the
998988
// view ref has been detached from the CD tree.
999-
const classList = this._tooltip.nativeElement.classList;
989+
const tooltip = this._tooltip.nativeElement;
1000990
const showClass = this._showAnimation;
1001991
const hideClass = this._hideAnimation;
1002-
classList.remove(isVisible ? hideClass : showClass);
1003-
classList.add(isVisible ? showClass : hideClass);
992+
tooltip.classList.remove(isVisible ? hideClass : showClass);
993+
tooltip.classList.add(isVisible ? showClass : hideClass);
1004994
this._isVisible = isVisible;
1005995

996+
// It's common for internal apps to disable animations using `* { animation: none !important }`
997+
// which can break the opening sequence. Try to detect such cases and work around them.
998+
if (isVisible && !this._animationsDisabled && typeof getComputedStyle === 'function') {
999+
const styles = getComputedStyle(tooltip);
1000+
1001+
// Use `getPropertyValue` to avoid issues with property renaming.
1002+
if (
1003+
styles.getPropertyValue('animation-duration') === '0s' ||
1004+
styles.getPropertyValue('animation-name') === 'none'
1005+
) {
1006+
this._animationsDisabled = true;
1007+
}
1008+
}
1009+
10061010
if (isVisible) {
10071011
this._onShow();
10081012
}
10091013

10101014
if (this._animationsDisabled) {
1015+
tooltip.classList.add('_mat-animation-noopable');
10111016
this._finalizeAnimation(isVisible);
10121017
}
10131018
}

tools/public_api_guard/material/tooltip.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,6 @@ export class TooltipComponent extends _TooltipComponentBase {
174174
export abstract class _TooltipComponentBase implements OnDestroy {
175175
constructor(_changeDetectorRef: ChangeDetectorRef, animationMode?: string);
176176
afterHidden(): Observable<void>;
177-
_animationsDisabled: boolean;
178177
_handleAnimationEnd({ animationName }: AnimationEvent): void;
179178
_handleBodyInteraction(): void;
180179
// (undocumented)

0 commit comments

Comments
 (0)