diff --git a/src/material-experimental/mdc-tooltip/tooltip.html b/src/material-experimental/mdc-tooltip/tooltip.html index f0ac5089f20f..28b374a88f8a 100644 --- a/src/material-experimental/mdc-tooltip/tooltip.html +++ b/src/material-experimental/mdc-tooltip/tooltip.html @@ -3,7 +3,6 @@ class="mdc-tooltip mdc-tooltip--shown mat-mdc-tooltip" [ngClass]="tooltipClass" (animationend)="_handleAnimationEnd($event)" - [class._mat-animation-noopable]="_animationsDisabled" [class.mdc-tooltip--multiline]="_isMultiline">
{{message}}
diff --git a/src/material/tooltip/tooltip.html b/src/material/tooltip/tooltip.html index e3a3b35031d0..cf6bd74a0592 100644 --- a/src/material/tooltip/tooltip.html +++ b/src/material/tooltip/tooltip.html @@ -2,5 +2,4 @@ class="mat-tooltip" (animationend)="_handleAnimationEnd($event)" [ngClass]="tooltipClass" - [class._mat-animation-noopable]="_animationsDisabled" [class.mat-tooltip-handset]="(_isHandset | async)?.matches">{{message}} diff --git a/src/material/tooltip/tooltip.ts b/src/material/tooltip/tooltip.ts index 97e7f626948e..77c9a665acb4 100644 --- a/src/material/tooltip/tooltip.ts +++ b/src/material/tooltip/tooltip.ts @@ -860,7 +860,7 @@ export abstract class _TooltipComponentBase implements OnDestroy { _mouseLeaveHideDelay: number; /** Whether animations are currently disabled. */ - _animationsDisabled: boolean; + private _animationsDisabled: boolean; /** Reference to the internal tooltip element. */ abstract _tooltip: ElementRef; @@ -895,15 +895,9 @@ export abstract class _TooltipComponentBase implements OnDestroy { // Cancel the delayed hide if it is scheduled clearTimeout(this._hideTimeoutId); - // Body interactions should cancel the tooltip if there is a delay in showing. - this._closeOnInteraction = true; this._showTimeoutId = setTimeout(() => { - this._toogleVisibility(true); + this._toggleVisibility(true); this._showTimeoutId = undefined; - - // Mark for check so if any parent component has set the - // ChangeDetectionStrategy to OnPush it will be checked anyways - this._markForCheck(); }, delay); } @@ -916,12 +910,8 @@ export abstract class _TooltipComponentBase implements OnDestroy { clearTimeout(this._showTimeoutId); this._hideTimeoutId = setTimeout(() => { - this._toogleVisibility(false); + this._toggleVisibility(false); this._hideTimeoutId = undefined; - - // Mark for check so if any parent component has set the - // ChangeDetectionStrategy to OnPush it will be checked anyways - this._markForCheck(); }, delay); } @@ -984,30 +974,45 @@ export abstract class _TooltipComponentBase implements OnDestroy { /** Handles the cleanup after an animation has finished. */ private _finalizeAnimation(toVisible: boolean) { - if (!toVisible && !this.isVisible()) { + if (toVisible) { + this._closeOnInteraction = true; + } else if (!this.isVisible()) { this._onHide.next(); } - - this._closeOnInteraction = true; } /** Toggles the visibility of the tooltip element. */ - private _toogleVisibility(isVisible: boolean) { + private _toggleVisibility(isVisible: boolean) { // We set the classes directly here ourselves so that toggling the tooltip state // isn't bound by change detection. This allows us to hide it even if the // view ref has been detached from the CD tree. - const classList = this._tooltip.nativeElement.classList; + const tooltip = this._tooltip.nativeElement; const showClass = this._showAnimation; const hideClass = this._hideAnimation; - classList.remove(isVisible ? hideClass : showClass); - classList.add(isVisible ? showClass : hideClass); + tooltip.classList.remove(isVisible ? hideClass : showClass); + tooltip.classList.add(isVisible ? showClass : hideClass); this._isVisible = isVisible; + // It's common for internal apps to disable animations using `* { animation: none !important }` + // which can break the opening sequence. Try to detect such cases and work around them. + if (isVisible && !this._animationsDisabled && typeof getComputedStyle === 'function') { + const styles = getComputedStyle(tooltip); + + // Use `getPropertyValue` to avoid issues with property renaming. + if ( + styles.getPropertyValue('animation-duration') === '0s' || + styles.getPropertyValue('animation-name') === 'none' + ) { + this._animationsDisabled = true; + } + } + if (isVisible) { this._onShow(); } if (this._animationsDisabled) { + tooltip.classList.add('_mat-animation-noopable'); this._finalizeAnimation(isVisible); } }