From baeedeeea6086feb8d732c2632f955a287d26e7e Mon Sep 17 00:00:00 2001 From: qa46hx Date: Thu, 15 Oct 2020 12:59:18 +0200 Subject: [PATCH] fix(tooltip): keeps tooltip closed when invoker is disabled --- .changeset/hip-peaches-shake.md | 5 +++ packages/tooltip/README.md | 15 +++++--- packages/tooltip/src/LionTooltip.js | 18 ++++++++- packages/tooltip/test/lion-tooltip.test.js | 44 ++++++++++++++++++++++ 4 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 .changeset/hip-peaches-shake.md diff --git a/.changeset/hip-peaches-shake.md b/.changeset/hip-peaches-shake.md new file mode 100644 index 000000000..fe595644a --- /dev/null +++ b/.changeset/hip-peaches-shake.md @@ -0,0 +1,5 @@ +--- +'@lion/tooltip': patch +--- + +Keep tooltip closed when invoker is disabled diff --git a/packages/tooltip/README.md b/packages/tooltip/README.md index 4bc63b7c3..1298a2e02 100644 --- a/packages/tooltip/README.md +++ b/packages/tooltip/README.md @@ -47,18 +47,21 @@ const tooltipDemoStyles = css` ```js preview-story export const main = () => html` - - - -
This is a tooltip
- - `; + + + +
This is a tooltip
+
+`; ``` ## Features - Show content when hovering the invoker - Show content when the invoker is focused +- Does not show content when invoker is disabled - Uses Popper.js under the hood, to have the content pop up relative to the invoker - Use `.config` to override the overlay configuration - Config has `popperConfig` property that has a one to one relation with Popper.js configuration API. diff --git a/packages/tooltip/src/LionTooltip.js b/packages/tooltip/src/LionTooltip.js index 666482d20..4d7b95696 100644 --- a/packages/tooltip/src/LionTooltip.js +++ b/packages/tooltip/src/LionTooltip.js @@ -66,6 +66,16 @@ export class LionTooltip extends ArrowMixin(OverlayMixin(LitElement)) { }); } + _hasDisabledInvoker() { + if (this._overlayCtrl && this._overlayCtrl.invoker) { + return ( + /** @type {HTMLElement & { disabled: boolean }} */ (this._overlayCtrl.invoker).disabled || + this._overlayCtrl.invoker.getAttribute('aria-disabled') === 'true' + ); + } + return false; + } + _setupOpenCloseListeners() { super._setupOpenCloseListeners(); this.__resetActive = this.__resetActive.bind(this); @@ -98,7 +108,9 @@ export class LionTooltip extends ArrowMixin(OverlayMixin(LitElement)) { _showMouse() { if (!this._keyActive) { this._mouseActive = true; - this.opened = true; + if (!this._hasDisabledInvoker()) { + this.opened = true; + } } } @@ -111,7 +123,9 @@ export class LionTooltip extends ArrowMixin(OverlayMixin(LitElement)) { _showKey() { if (!this._mouseActive) { this._keyActive = true; - this.opened = true; + if (!this._hasDisabledInvoker()) { + this.opened = true; + } } } diff --git a/packages/tooltip/test/lion-tooltip.test.js b/packages/tooltip/test/lion-tooltip.test.js index 802c8c76a..0e664791c 100644 --- a/packages/tooltip/test/lion-tooltip.test.js +++ b/packages/tooltip/test/lion-tooltip.test.js @@ -102,6 +102,50 @@ describe('lion-tooltip', () => { expect(el._overlayCtrl.isShown).to.equal(true); }); + it('stays hidden on disabled invoker', async () => { + const el = /** @type {LionTooltip} */ (await fixture(html` + +
Hey there
+ +
+ `)); + const invoker = /** @type {HTMLElement} */ (Array.from(el.children).find( + child => child.slot === 'invoker', + )); + const eventMouseEnter = new Event('mouseenter'); + el.dispatchEvent(eventMouseEnter); + await el.updateComplete; + // @ts-expect-error allow protected props in tests + expect(el._overlayCtrl.isShown).to.equal(false); + const eventFocusIn = new Event('focusin'); + invoker.dispatchEvent(eventFocusIn); + await el.updateComplete; + // @ts-expect-error allow protected props in tests + expect(el._overlayCtrl.isShown).to.equal(false); + }); + + it('stays hidden on aria-disabled invoker', async () => { + const el = /** @type {LionTooltip} */ (await fixture(html` + +
Hey there
+ +
+ `)); + const invoker = /** @type {HTMLElement} */ (Array.from(el.children).find( + child => child.slot === 'invoker', + )); + const eventMouseEnter = new Event('mouseenter'); + el.dispatchEvent(eventMouseEnter); + await el.updateComplete; + // @ts-expect-error allow protected props in tests + expect(el._overlayCtrl.isShown).to.equal(false); + const eventFocusIn = new Event('focusin'); + invoker.dispatchEvent(eventFocusIn); + await el.updateComplete; + // @ts-expect-error allow protected props in tests + expect(el._overlayCtrl.isShown).to.equal(false); + }); + it('contains html when specified in tooltip content body', async () => { const el = /** @type {LionTooltip} */ (await fixture(html`