Skip to content

Commit

Permalink
fix(tooltip): not closing if escape is pressed while trigger isn't fo…
Browse files Browse the repository at this point in the history
…cused

Currently the tooltip's `keydown` handler is on the trigger, which means that it won't fire if the trigger doesn't have focus. This could happen when a tooltip was opened by hovering over the trigger. These changes use the `OverlayKeyboardDispatcher` to handle the events instead.

Fixes #14278.
  • Loading branch information
crisbeto committed Sep 21, 2019
1 parent 7f6972f commit b50ab13
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 17 deletions.
25 changes: 22 additions & 3 deletions src/material/tooltip/tooltip.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -639,9 +639,28 @@ describe('MatTooltip', () => {
expect(overlayContainerElement.textContent).toContain(initialTooltipMessage);
}));

it('should hide when pressing escape', fakeAsync(() => {
tooltipDirective.show();
tick(0);
fixture.detectChanges();
tick(500);

expect(tooltipDirective._isTooltipVisible()).toBe(true);
expect(overlayContainerElement.textContent).toContain(initialTooltipMessage);

dispatchKeyboardEvent(document.body, 'keydown', ESCAPE);
tick(0);
fixture.detectChanges();
tick(500);
fixture.detectChanges();

expect(tooltipDirective._isTooltipVisible()).toBe(false);
expect(overlayContainerElement.textContent).toBe('');
}));

it('should not throw when pressing ESCAPE', fakeAsync(() => {
expect(() => {
dispatchKeyboardEvent(buttonElement, 'keydown', ESCAPE);
dispatchKeyboardEvent(document.body, 'keydown', ESCAPE);
fixture.detectChanges();
}).not.toThrow();

Expand All @@ -654,7 +673,7 @@ describe('MatTooltip', () => {
tick(0);
fixture.detectChanges();

const event = dispatchKeyboardEvent(buttonElement, 'keydown', ESCAPE);
const event = dispatchKeyboardEvent(document.body, 'keydown', ESCAPE);
fixture.detectChanges();
flush();

Expand All @@ -668,7 +687,7 @@ describe('MatTooltip', () => {

const event = createKeyboardEvent('keydown', ESCAPE);
Object.defineProperty(event, 'altKey', {get: () => true});
dispatchEvent(buttonElement, event);
dispatchEvent(document.body, event);
fixture.detectChanges();
flush();

Expand Down
26 changes: 13 additions & 13 deletions src/material/tooltip/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ export function MAT_TOOLTIP_DEFAULT_OPTIONS_FACTORY(): MatTooltipDefaultOptions
exportAs: 'matTooltip',
host: {
'(longpress)': 'show()',
'(keydown)': '_handleKeydown($event)',
'(touchend)': '_handleTouchend()',
},
})
Expand Down Expand Up @@ -337,15 +336,6 @@ export class MatTooltip implements OnDestroy, OnInit {
return !!this._tooltipInstance && this._tooltipInstance.isVisible();
}

/** Handles the keydown events on the host element. */
_handleKeydown(e: KeyboardEvent) {
if (this._isTooltipVisible() && e.keyCode === ESCAPE && !hasModifierKey(e)) {
e.preventDefault();
e.stopPropagation();
this.hide(0);
}
}

/** Handles the touchend events on the host element. */
_handleTouchend() {
this.hide(this._defaultOptions.touchendHideDelay);
Expand Down Expand Up @@ -378,7 +368,7 @@ export class MatTooltip implements OnDestroy, OnInit {
}
});

this._overlayRef = this._overlay.create({
const overlayRef = this._overlayRef = this._overlay.create({
direction: this._dir,
positionStrategy: strategy,
panelClass: TOOLTIP_PANEL_CLASS,
Expand All @@ -387,11 +377,21 @@ export class MatTooltip implements OnDestroy, OnInit {

this._updatePosition();

this._overlayRef.detachments()
overlayRef.keydownEvents()
.pipe(takeUntil(this._destroyed))
.subscribe(event => {
if (this._isTooltipVisible() && event.keyCode === ESCAPE && !hasModifierKey(event)) {
event.preventDefault();
event.stopPropagation();
this.hide(0);
}
});

overlayRef.detachments()
.pipe(takeUntil(this._destroyed))
.subscribe(() => this._detach());

return this._overlayRef;
return overlayRef;
}

/** Detaches the currently-attached tooltip. */
Expand Down
1 change: 0 additions & 1 deletion tools/public_api_guard/material/tooltip.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ export declare class MatTooltip implements OnDestroy, OnInit {
main: OverlayConnectionPosition;
fallback: OverlayConnectionPosition;
};
_handleKeydown(e: KeyboardEvent): void;
_handleTouchend(): void;
_isTooltipVisible(): boolean;
hide(delay?: number): void;
Expand Down

0 comments on commit b50ab13

Please sign in to comment.