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
|
```js preview-story
|
||||||
export const main = () => html`
|
export const main = () => html`
|
||||||
<style>${tooltipDemoStyles}</style>
|
<style>
|
||||||
|
${tooltipDemoStyles}
|
||||||
|
</style>
|
||||||
<lion-tooltip>
|
<lion-tooltip>
|
||||||
<button slot="invoker" class="demo-tooltip-invoker">Hover me</button>
|
<button slot="invoker" class="demo-tooltip-invoker">Hover me</button>
|
||||||
<div slot="content" class="demo-tooltip-content">This is a tooltip<div>
|
<div slot="content" class="demo-tooltip-content">This is a tooltip</div>
|
||||||
</lion-tooltip>
|
</lion-tooltip>
|
||||||
`;
|
`;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Show content when hovering the invoker
|
- Show content when hovering the invoker
|
||||||
- Show content when the invoker is focused
|
- 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
|
- Uses Popper.js under the hood, to have the content pop up relative to the invoker
|
||||||
- Use `.config` to override the overlay configuration
|
- Use `.config` to override the overlay configuration
|
||||||
- Config has `popperConfig` property that has a one to one relation with Popper.js configuration API.
|
- 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() {
|
_setupOpenCloseListeners() {
|
||||||
super._setupOpenCloseListeners();
|
super._setupOpenCloseListeners();
|
||||||
this.__resetActive = this.__resetActive.bind(this);
|
this.__resetActive = this.__resetActive.bind(this);
|
||||||
|
|
@ -98,9 +108,11 @@ export class LionTooltip extends ArrowMixin(OverlayMixin(LitElement)) {
|
||||||
_showMouse() {
|
_showMouse() {
|
||||||
if (!this._keyActive) {
|
if (!this._keyActive) {
|
||||||
this._mouseActive = true;
|
this._mouseActive = true;
|
||||||
|
if (!this._hasDisabledInvoker()) {
|
||||||
this.opened = true;
|
this.opened = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_hideMouse() {
|
_hideMouse() {
|
||||||
if (!this._keyActive) {
|
if (!this._keyActive) {
|
||||||
|
|
@ -111,9 +123,11 @@ export class LionTooltip extends ArrowMixin(OverlayMixin(LitElement)) {
|
||||||
_showKey() {
|
_showKey() {
|
||||||
if (!this._mouseActive) {
|
if (!this._mouseActive) {
|
||||||
this._keyActive = true;
|
this._keyActive = true;
|
||||||
|
if (!this._hasDisabledInvoker()) {
|
||||||
this.opened = true;
|
this.opened = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_hideKey() {
|
_hideKey() {
|
||||||
if (!this._mouseActive) {
|
if (!this._mouseActive) {
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,50 @@ describe('lion-tooltip', () => {
|
||||||
expect(el._overlayCtrl.isShown).to.equal(true);
|
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 () => {
|
it('contains html when specified in tooltip content body', async () => {
|
||||||
const el = /** @type {LionTooltip} */ (await fixture(html`
|
const el = /** @type {LionTooltip} */ (await fixture(html`
|
||||||
<lion-tooltip>
|
<lion-tooltip>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue