Skip to content

Commit 642483b

Browse files
committed
fix(tooltip): not closing if escape is pressed while trigger isn't focused
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.
1 parent bc563b7 commit 642483b

File tree

2 files changed

+30
-12
lines changed

2 files changed

+30
-12
lines changed

src/lib/tooltip/tooltip.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,25 @@ describe('MatTooltip', () => {
580580
expect(overlayContainerElement.textContent).toContain(initialTooltipMessage);
581581
}));
582582

583+
it('should hide when pressing escape', fakeAsync(() => {
584+
tooltipDirective.show();
585+
tick(0);
586+
fixture.detectChanges();
587+
tick(500);
588+
589+
expect(tooltipDirective._isTooltipVisible()).toBe(true);
590+
expect(overlayContainerElement.textContent).toContain(initialTooltipMessage);
591+
592+
dispatchKeyboardEvent(document.body, 'keydown', ESCAPE);
593+
tick(0);
594+
fixture.detectChanges();
595+
tick(500);
596+
fixture.detectChanges();
597+
598+
expect(tooltipDirective._isTooltipVisible()).toBe(false);
599+
expect(overlayContainerElement.textContent).toBe('');
600+
}));
601+
583602
it('should not throw when pressing ESCAPE', fakeAsync(() => {
584603
expect(() => {
585604
dispatchKeyboardEvent(buttonElement, 'keydown', ESCAPE);

src/lib/tooltip/tooltip.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ export function MAT_TOOLTIP_DEFAULT_OPTIONS_FACTORY(): MatTooltipDefaultOptions
111111
exportAs: 'matTooltip',
112112
host: {
113113
'(longpress)': 'show()',
114-
'(keydown)': '_handleKeydown($event)',
115114
'(touchend)': '_handleTouchend()',
116115
},
117116
})
@@ -315,14 +314,6 @@ export class MatTooltip implements OnDestroy {
315314
return !!this._tooltipInstance && this._tooltipInstance.isVisible();
316315
}
317316

318-
/** Handles the keydown events on the host element. */
319-
_handleKeydown(e: KeyboardEvent) {
320-
if (this._isTooltipVisible() && e.keyCode === ESCAPE) {
321-
e.stopPropagation();
322-
this.hide(0);
323-
}
324-
}
325-
326317
/** Handles the touchend events on the host element. */
327318
_handleTouchend() {
328319
this.hide(this._defaultOptions.touchendHideDelay);
@@ -356,7 +347,7 @@ export class MatTooltip implements OnDestroy {
356347
}
357348
});
358349

359-
this._overlayRef = this._overlay.create({
350+
const overlayRef = this._overlayRef = this._overlay.create({
360351
direction: this._dir,
361352
positionStrategy: strategy,
362353
panelClass: TOOLTIP_PANEL_CLASS,
@@ -365,11 +356,19 @@ export class MatTooltip implements OnDestroy {
365356

366357
this._updatePosition();
367358

368-
this._overlayRef.detachments()
359+
overlayRef.keydownEvents()
360+
.pipe(takeUntil(this._destroyed))
361+
.subscribe(event => {
362+
if (this._isTooltipVisible() && event.keyCode === ESCAPE) {
363+
this.hide(0);
364+
}
365+
});
366+
367+
overlayRef.detachments()
369368
.pipe(takeUntil(this._destroyed))
370369
.subscribe(() => this._detach());
371370

372-
return this._overlayRef;
371+
return overlayRef;
373372
}
374373

375374
/** Detaches the currently-attached tooltip. */

0 commit comments

Comments
 (0)