From d04230c0848fd059f88d6d069ad2e6904a099df7 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Fri, 14 Jul 2017 02:12:01 +0200 Subject: [PATCH] fix(tooltip): panel element blocks hover effects (#5514) By default the overlay container always has pointer events disabled. Currently the tooltip component also has pointer events disabled. The only thing that has pointer events enabled is the overlay panel element. This can be problematic because as soon as someone hovers of the overlay panel element, the pointer events & hover effects are going to the overlay panel element instead of the element that the tooltip just overlays. Fixes #4691 --- src/lib/tooltip/tooltip.scss | 7 +++++-- src/lib/tooltip/tooltip.spec.ts | 21 +++++++++++++++++++-- src/lib/tooltip/tooltip.ts | 4 ++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/lib/tooltip/tooltip.scss b/src/lib/tooltip/tooltip.scss index 4f53397f25e..1b69d057673 100644 --- a/src/lib/tooltip/tooltip.scss +++ b/src/lib/tooltip/tooltip.scss @@ -5,8 +5,11 @@ $mat-tooltip-horizontal-padding: 8px; $mat-tooltip-max-width: 250px; $mat-tooltip-margin: 14px; -:host { - pointer-events: none; +.mat-tooltip-panel { + // The overlay reference updates the pointer-events style property directly on the HTMLElement + // depending on the state of the overlay. For tooltips the overlay panel should never enable + // pointer events. To overwrite the inline CSS from the overlay reference `!important` is needed. + pointer-events: none !important; } .mat-tooltip { diff --git a/src/lib/tooltip/tooltip.spec.ts b/src/lib/tooltip/tooltip.spec.ts index 681c97bec68..1834f0ccd5b 100644 --- a/src/lib/tooltip/tooltip.spec.ts +++ b/src/lib/tooltip/tooltip.spec.ts @@ -12,16 +12,21 @@ import { ViewChild, ChangeDetectionStrategy } from '@angular/core'; +import { + TooltipPosition, + MdTooltip, + MdTooltipModule, + SCROLL_THROTTLE_MS, + TOOLTIP_PANEL_CLASS +} from './index'; import {AnimationEvent} from '@angular/animations'; import {By} from '@angular/platform-browser'; import {NoopAnimationsModule} from '@angular/platform-browser/animations'; -import {TooltipPosition, MdTooltip, MdTooltipModule, SCROLL_THROTTLE_MS} from './index'; import {Directionality, Direction} from '../core/bidi/index'; import {OverlayModule, Scrollable, OverlayContainer} from '../core/overlay/index'; import {Platform} from '../core/platform/platform'; import {dispatchFakeEvent} from '@angular/cdk/testing'; - const initialTooltipMessage = 'initial tooltip message'; describe('MdTooltip', () => { @@ -115,6 +120,18 @@ describe('MdTooltip', () => { expect(overlayContainerElement.textContent).toContain(initialTooltipMessage); })); + it('should set a css class on the overlay panel element', fakeAsync(() => { + tooltipDirective.show(); + fixture.detectChanges(); + tick(0); + + const overlayRef = tooltipDirective._overlayRef; + + expect(overlayRef).not.toBeNull(); + expect(overlayRef!.overlayElement.classList).toContain(TOOLTIP_PANEL_CLASS, + 'Expected the overlay panel element to have the tooltip panel class set.'); + })); + it('should not show if disabled', fakeAsync(() => { // Test that disabling the tooltip will not set the tooltip visible tooltipDirective.disabled = true; diff --git a/src/lib/tooltip/tooltip.ts b/src/lib/tooltip/tooltip.ts index 88d0297e3b1..ae6b78bdf5b 100644 --- a/src/lib/tooltip/tooltip.ts +++ b/src/lib/tooltip/tooltip.ts @@ -52,6 +52,9 @@ export const TOUCHEND_HIDE_DELAY = 1500; /** Time in ms to throttle repositioning after scroll events. */ export const SCROLL_THROTTLE_MS = 20; +/** CSS class that will be attached to the overlay panel. */ +export const TOOLTIP_PANEL_CLASS = 'mat-tooltip-panel'; + /** Creates an error to be thrown if the user supplied an invalid tooltip position. */ export function getMdTooltipInvalidPositionError(position: string) { return Error(`Tooltip position "${position}" is invalid.`); @@ -275,6 +278,7 @@ export class MdTooltip implements OnDestroy { config.direction = this._dir ? this._dir.value : 'ltr'; config.positionStrategy = strategy; + config.panelClass = TOOLTIP_PANEL_CLASS; config.scrollStrategy = this._overlay.scrollStrategies.reposition({ scrollThrottle: SCROLL_THROTTLE_MS });