fix(tooltip): keeps tooltip closed when invoker is disabled
This commit is contained in:
parent
2dc85b14d3
commit
baeedeeea6
4 changed files with 74 additions and 8 deletions
5
.changeset/hip-peaches-shake.md
Normal file
5
.changeset/hip-peaches-shake.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@lion/tooltip': patch
|
||||
---
|
||||
|
||||
Keep tooltip closed when invoker is disabled
|
||||
|
|
@ -47,18 +47,21 @@ const tooltipDemoStyles = css`
|
|||
|
||||
```js preview-story
|
||||
export const main = () => html`
|
||||
<style>${tooltipDemoStyles}</style>
|
||||
<lion-tooltip>
|
||||
<button slot="invoker" class="demo-tooltip-invoker">Hover me</button>
|
||||
<div slot="content" class="demo-tooltip-content">This is a tooltip<div>
|
||||
</lion-tooltip>
|
||||
`;
|
||||
<style>
|
||||
${tooltipDemoStyles}
|
||||
</style>
|
||||
<lion-tooltip>
|
||||
<button slot="invoker" class="demo-tooltip-invoker">Hover me</button>
|
||||
<div slot="content" class="demo-tooltip-content">This is a tooltip</div>
|
||||
</lion-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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
<lion-tooltip>
|
||||
<div slot="content">Hey there</div>
|
||||
<button slot="invoker" disabled>Tooltip button</button>
|
||||
</lion-tooltip>
|
||||
`));
|
||||
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`
|
||||
<lion-tooltip>
|
||||
<div slot="content">Hey there</div>
|
||||
<button slot="invoker" aria-disabled="true">Tooltip button</button>
|
||||
</lion-tooltip>
|
||||
`));
|
||||
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`
|
||||
<lion-tooltip>
|
||||
|
|
|
|||
Loading…
Reference in a new issue