fix(ui): overlay fixes (responsive backdrop/select-rich/tooltip)
This commit is contained in:
parent
ab906fc13b
commit
7ac0a42224
6 changed files with 54 additions and 13 deletions
5
.changeset/fair-actors-decide.md
Normal file
5
.changeset/fair-actors-decide.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@lion/ui': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
[overlays] fixes (responsive backdrop/select-rich/tooltip)
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { EventTargetShim } from '@lion/ui/core.js';
|
|
||||||
import { adoptStyles } from 'lit';
|
import { adoptStyles } from 'lit';
|
||||||
import { overlays } from './singleton.js';
|
import { overlays } from './singleton.js';
|
||||||
import { containFocus } from './utils/contain-focus.js';
|
import { containFocus } from './utils/contain-focus.js';
|
||||||
|
|
@ -129,7 +128,7 @@ const supportsCSSTypedObject = window.CSS?.number && document.body.attributeStyl
|
||||||
* bottom/top/left/right sheets etc.
|
* bottom/top/left/right sheets etc.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export class OverlayController extends EventTargetShim {
|
export class OverlayController extends EventTarget {
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {OverlayConfig} config initial config. Will be remembered as shared config
|
* @param {OverlayConfig} config initial config. Will be remembered as shared config
|
||||||
|
|
@ -973,22 +972,24 @@ export class OverlayController extends EventTargetShim {
|
||||||
if (this.inheritsReferenceWidth) {
|
if (this.inheritsReferenceWidth) {
|
||||||
this._handleInheritsReferenceWidth();
|
this._handleInheritsReferenceWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.visibilityTriggerFunction) {
|
if (this.visibilityTriggerFunction) {
|
||||||
this._handleUserInteraction({ phase });
|
this._handleVisibilityTriggers({ phase });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {{ phase: OverlayPhase }} config
|
* @param {{ phase: OverlayPhase }} config
|
||||||
*/
|
*/
|
||||||
_handleUserInteraction({ phase }) {
|
_handleVisibilityTriggers({ phase }) {
|
||||||
if (typeof this.visibilityTriggerFunction === 'function') {
|
if (typeof this.visibilityTriggerFunction === 'function') {
|
||||||
if (phase === 'init') {
|
if (phase === 'init') {
|
||||||
this.__userInteractionHandler = this.visibilityTriggerFunction({ phase, controller: this });
|
this.__visibilityTriggerHandler = this.visibilityTriggerFunction({
|
||||||
|
phase,
|
||||||
|
controller: this,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (this.__userInteractionHandler[phase]) {
|
if (this.__visibilityTriggerHandler[phase]) {
|
||||||
this.__userInteractionHandler[phase]();
|
this.__visibilityTriggerHandler[phase]();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1053,10 +1054,14 @@ export class OverlayController extends EventTargetShim {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'show':
|
case 'show':
|
||||||
this.backdropNode.classList.add(`overlays__backdrop--visible`);
|
if (this.config.hasBackdrop) {
|
||||||
|
this.backdropNode.classList.add(`overlays__backdrop--visible`);
|
||||||
|
}
|
||||||
this.__hasActiveBackdrop = true;
|
this.__hasActiveBackdrop = true;
|
||||||
break;
|
break;
|
||||||
case 'hide':
|
case 'hide':
|
||||||
|
case 'teardown':
|
||||||
|
this.backdropNode.classList.remove(`overlays__backdrop--visible`);
|
||||||
this.__hasActiveBackdrop = false;
|
this.__hasActiveBackdrop = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1515,6 +1515,22 @@ describe('OverlayController', () => {
|
||||||
expect(ctrl.contentWrapperNode.classList.contains('overlays__overlay-container--top-right'));
|
expect(ctrl.contentWrapperNode.classList.contains('overlays__overlay-container--top-right'));
|
||||||
expect(ctrl.isShown).to.be.true;
|
expect(ctrl.isShown).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('disables backdrop when switching to hasBackrop "false"', async () => {
|
||||||
|
const ctrl = new OverlayController({
|
||||||
|
...withLocalTestConfig(),
|
||||||
|
contentNode: /** @type {HTMLElement} */ (await fixture(html`<div>content1</div>`)),
|
||||||
|
hasBackdrop: true,
|
||||||
|
});
|
||||||
|
await ctrl.show(); // Popper adds inline styles
|
||||||
|
expect(ctrl.backdropNode).not.to.be.undefined;
|
||||||
|
expect(Array.from(ctrl.backdropNode.classList)).to.include('overlays__backdrop--visible');
|
||||||
|
|
||||||
|
ctrl.updateConfig({
|
||||||
|
hasBackdrop: false,
|
||||||
|
});
|
||||||
|
expect(Array.from(ctrl.backdropNode.classList)).to.not.include('overlays__backdrop--visible');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Accessibility', () => {
|
describe('Accessibility', () => {
|
||||||
|
|
|
||||||
|
|
@ -336,6 +336,8 @@ export class LionSelectRich extends SlotMixin(ScopedElementsMixin(OverlayMixin(L
|
||||||
_defineOverlayConfig() {
|
_defineOverlayConfig() {
|
||||||
return {
|
return {
|
||||||
...withDropdownConfig(),
|
...withDropdownConfig(),
|
||||||
|
// Needs more advanced behavior (see `__invokerOnClick`)
|
||||||
|
visibilityTriggerFunction: undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,10 @@ export class LionTooltip extends ArrowMixin(OverlayMixin(LitElement)) {
|
||||||
:host([hidden]) {
|
:host([hidden]) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::slotted([slot='content']) {
|
||||||
|
width: max-content;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
@ -54,9 +58,19 @@ export class LionTooltip extends ArrowMixin(OverlayMixin(LitElement)) {
|
||||||
/** @protected */
|
/** @protected */
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
_defineOverlayConfig() {
|
_defineOverlayConfig() {
|
||||||
|
const superCfg = super._defineOverlayConfig();
|
||||||
|
const tooltipCfg = withTooltipConfig({ invokerRelation: this.invokerRelation });
|
||||||
return /** @type {OverlayConfig} */ ({
|
return /** @type {OverlayConfig} */ ({
|
||||||
...super._defineOverlayConfig(),
|
...superCfg,
|
||||||
...withTooltipConfig({ invokerRelation: this.invokerRelation }),
|
...tooltipCfg,
|
||||||
|
popperConfig: {
|
||||||
|
...(superCfg.popperConfig || {}),
|
||||||
|
...(tooltipCfg.popperConfig || {}),
|
||||||
|
modifiers: [
|
||||||
|
...(superCfg.popperConfig?.modifiers || []),
|
||||||
|
...(tooltipCfg.popperConfig?.modifiers || []),
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -227,8 +227,7 @@ describe('lion-tooltip', () => {
|
||||||
expect(el._arrowNode).to.be.displayed;
|
expect(el._arrowNode).to.be.displayed;
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: promise for dynamic import popper does not resolve?
|
it('makes sure positioning of the arrow is correct', async () => {
|
||||||
it.skip('makes sure positioning of the arrow is correct', async () => {
|
|
||||||
const el = /** @type {LionTooltip} */ (
|
const el = /** @type {LionTooltip} */ (
|
||||||
await fixture(html`
|
await fixture(html`
|
||||||
<lion-tooltip
|
<lion-tooltip
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue