From c0ed437e8fed618c47fe90feca7969fde934b9eb Mon Sep 17 00:00:00 2001 From: Marcos Gil Date: Wed, 5 Feb 2020 16:30:27 +0100 Subject: [PATCH] feat(overlay): add hide on outside esc handler --- packages/overlays/src/OverlayController.js | 13 +++++++ .../overlays/test/OverlayController.test.js | 23 ++++++++++++ packages/tooltip/src/LionTooltip.js | 1 + packages/tooltip/test/lion-tooltip.test.js | 35 ------------------- 4 files changed, 37 insertions(+), 35 deletions(-) diff --git a/packages/overlays/src/OverlayController.js b/packages/overlays/src/OverlayController.js index 22fd296fd..f92b871da 100644 --- a/packages/overlays/src/OverlayController.js +++ b/packages/overlays/src/OverlayController.js @@ -32,6 +32,7 @@ export class OverlayController { preventsScroll: false, trapsKeyboardFocus: false, hidesOnEsc: false, + hidesOnOutsideEsc: false, hidesOnOutsideClick: false, isTooltip: false, handlesUserInteraction: false, @@ -376,6 +377,9 @@ export class OverlayController { if (this.hidesOnEsc) { this._handleHidesOnEsc({ phase }); } + if (this.hidesOnOutsideEsc) { + this._handleHidesOnOutsideEsc({ phase }); + } if (this.hidesOnOutsideClick) { this._handleHidesOnOutsideClick({ phase }); } @@ -537,6 +541,15 @@ export class OverlayController { } } + _handleHidesOnOutsideEsc({ phase }) { + if (phase === 'show') { + this.__escKeyHandler = ev => ev.key === 'Escape' && this.hide(); + document.addEventListener('keyup', this.__escKeyHandler); + } else if (phase === 'hide') { + document.removeEventListener('keyup', this.__escKeyHandler); + } + } + _handleInheritsReferenceWidth() { if (!this._referenceNode) { return; diff --git a/packages/overlays/test/OverlayController.test.js b/packages/overlays/test/OverlayController.test.js index e31b59a57..f8d607f48 100644 --- a/packages/overlays/test/OverlayController.test.js +++ b/packages/overlays/test/OverlayController.test.js @@ -314,6 +314,29 @@ describe('OverlayController', () => { }); }); + describe('hidesOnOutsideEsc', () => { + it('hides when [escape] is pressed on outside element', async () => { + const ctrl = new OverlayController({ + ...withGlobalTestConfig(), + hidesOnOutsideEsc: true, + }); + await ctrl.show(); + document.dispatchEvent(new KeyboardEvent('keyup', { key: 'Escape' })); + await aTimeout(); + expect(ctrl.isShown).to.be.false; + }); + + it('stays shown when [escape] is pressed on inside element', async () => { + const ctrl = new OverlayController({ + ...withGlobalTestConfig(), + hidesOnOutsideEsc: true, + }); + await ctrl.show(); + ctrl.contentNode.dispatchEvent(new KeyboardEvent('keyup', { key: 'Escape' })); + expect(ctrl.isShown).to.be.true; + }); + }); + describe('hidesOnOutsideClick', () => { it('hides on outside click', async () => { const contentNode = await fixture('
Content
'); diff --git a/packages/tooltip/src/LionTooltip.js b/packages/tooltip/src/LionTooltip.js index 2ac6f2430..315d99e14 100644 --- a/packages/tooltip/src/LionTooltip.js +++ b/packages/tooltip/src/LionTooltip.js @@ -44,6 +44,7 @@ export class LionTooltip extends OverlayMixin(LitElement) { placementMode: 'local', elementToFocusAfterHide: null, hidesOnEsc: true, + hidesOnOutsideEsc: true, popperConfig: { placement: 'top', // default modifiers: { diff --git a/packages/tooltip/test/lion-tooltip.test.js b/packages/tooltip/test/lion-tooltip.test.js index 3dabb59b6..83151b10f 100644 --- a/packages/tooltip/test/lion-tooltip.test.js +++ b/packages/tooltip/test/lion-tooltip.test.js @@ -85,41 +85,6 @@ describe('lion-tooltip', () => { expect(el._overlayCtrl.isShown).to.equal(true); }); - it('should show content on focusin and hide on Escape key press', async () => { - const el = await fixture(html` - -
Hey there
- -
- `); - const invoker = Array.from(el.children).find(child => child.slot === 'invoker'); - const eventFocusIn = new Event('focusin'); - invoker.dispatchEvent(eventFocusIn); - await el.updateComplete; - expect(el._overlayCtrl.isShown).to.equal(true); - const eventEscapeKeypress = new KeyboardEvent('keyup', { key: 'Escape' }); - invoker.dispatchEvent(eventEscapeKeypress); - await el.updateComplete; - expect(el._overlayCtrl.isShown).to.equal(false); - }); - - it('should show content on mouseenter and hide on Escape key press', async () => { - const el = await fixture(html` - -
Hey there
- -
- `); - const eventMouseEnter = new Event('mouseenter'); - el.dispatchEvent(eventMouseEnter); - await el.updateComplete; - expect(el._overlayCtrl.isShown).to.equal(true); - const eventEscapeKeypress = new KeyboardEvent('keyup', { key: 'Escape' }); - document.dispatchEvent(eventEscapeKeypress); - await el.updateComplete; - expect(el._overlayCtrl.isShown).to.equal(false); - }); - it('should tooltip contains html when specified in tooltip content body', async () => { const el = await fixture(html`