127 lines
3.9 KiB
JavaScript
127 lines
3.9 KiB
JavaScript
import { expect, fixture } from '@open-wc/testing';
|
|
import { LitElement, html } from 'lit';
|
|
import { ArrowMixin, OverlayMixin } from '@lion/ui/overlays.js';
|
|
|
|
describe('ArrowMixin', () => {
|
|
class ArrowTest extends ArrowMixin(OverlayMixin(LitElement)) {
|
|
/**
|
|
* @overridable method `_defineOverlay`
|
|
* @desc Overrides arrow and keepTogether modifier to be enabled,
|
|
* and adds onCreate and onUpdate hooks to sync from popper state
|
|
* @returns {import('../types/OverlayConfig.js').OverlayConfig}
|
|
*/
|
|
_defineOverlayConfig() {
|
|
return {
|
|
...super._defineOverlayConfig(),
|
|
placementMode: 'local',
|
|
popperConfig: {
|
|
...super._defineOverlayConfig().popperConfig,
|
|
placement: 'bottom',
|
|
},
|
|
};
|
|
}
|
|
|
|
constructor() {
|
|
super();
|
|
this.__toggle = this.__toggle.bind(this);
|
|
}
|
|
|
|
__toggle() {
|
|
this.opened = !this.opened;
|
|
}
|
|
|
|
_setupOpenCloseListeners() {
|
|
super._setupOpenCloseListeners();
|
|
if (this._overlayInvokerNode) {
|
|
this._overlayInvokerNode.addEventListener('click', this.__toggle);
|
|
}
|
|
}
|
|
|
|
_teardownOpenCloseListeners() {
|
|
super._teardownOpenCloseListeners();
|
|
if (this._overlayInvokerNode) {
|
|
this._overlayInvokerNode.removeEventListener('click', this.__toggle);
|
|
}
|
|
}
|
|
}
|
|
before(() => {
|
|
customElements.define('arrow-test', ArrowTest);
|
|
});
|
|
|
|
it('shows by default', async () => {
|
|
const el = /** @type {ArrowTest} */ (
|
|
await fixture(html`
|
|
<arrow-test>
|
|
<div slot="content">This is a tooltip</div>
|
|
<button slot="invoker">Tooltip button</button>
|
|
</arrow-test>
|
|
`)
|
|
);
|
|
expect(el.hasAttribute('has-arrow')).to.be.true;
|
|
const arrowNode = /** @type {Element} */ (el._arrowNode);
|
|
expect(window.getComputedStyle(arrowNode).getPropertyValue('display')).to.equal('block');
|
|
});
|
|
|
|
it('hides for screen readers', async () => {
|
|
const el = /** @type {ArrowTest} */ (
|
|
await fixture(html`
|
|
<arrow-test>
|
|
<div slot="content">This is a tooltip</div>
|
|
<button slot="invoker">Tooltip button</button>
|
|
</arrow-test>
|
|
`)
|
|
);
|
|
|
|
const arrowNode = /** @type {Element} */ (el._arrowNode);
|
|
expect(arrowNode.getAttribute('aria-hidden')).to.equal('true');
|
|
});
|
|
|
|
it('hides the arrow when has-arrow is false', async () => {
|
|
const el = /** @type {ArrowTest} */ (
|
|
await fixture(html`
|
|
<arrow-test>
|
|
<div slot="content">This is a tooltip</div>
|
|
<button slot="invoker">Tooltip button</button>
|
|
</arrow-test>
|
|
`)
|
|
);
|
|
el.hasArrow = false;
|
|
await el.updateComplete;
|
|
expect(el.hasAttribute('has-arrow')).to.be.false;
|
|
const arrowNode = /** @type {Element} */ (el._arrowNode);
|
|
expect(window.getComputedStyle(arrowNode).getPropertyValue('display')).to.equal('none');
|
|
});
|
|
|
|
it('makes sure positioning of the arrow is correct', async () => {
|
|
const el = /** @type {ArrowTest} */ (
|
|
await fixture(html`
|
|
<arrow-test
|
|
.config="${
|
|
/** @type {import('../types/OverlayConfig.js').OverlayConfig} */ ({
|
|
popperConfig: {
|
|
placement: 'right',
|
|
},
|
|
})
|
|
}"
|
|
style="position: relative; top: 10px;"
|
|
>
|
|
<div slot="content" style="height: 30px; background-color: red;">Hey there</div>
|
|
<button slot="invoker" style="height: 30px;">Tooltip button</button>
|
|
</arrow-test>
|
|
`)
|
|
);
|
|
|
|
el.opened = true;
|
|
|
|
await el.repositionComplete;
|
|
expect(
|
|
getComputedStyle(/** @type {HTMLElement} */ (el._arrowNode)).getPropertyValue('left'),
|
|
).to.equal(
|
|
'-10px',
|
|
`
|
|
arrow height is 8px so this offset should be taken into account to align the arrow properly,
|
|
as well as half the difference between width and height ((12 - 8) / 2 = 2)
|
|
`,
|
|
);
|
|
});
|
|
});
|