@limetech/lime-elements
Version:
165 lines (158 loc) • 6.36 kB
JavaScript
import { r as registerInstance, c as createEvent, h, g as getElement } from './index-2714248e.js';
import { c as createRandomString } from './random-string-355331d3.js';
import { E as ESCAPE } from './keycodes-e2e44b7e.js';
import { z as zipObject } from './zipObject-2d9177d5.js';
import './_assignValue-71d5b293.js';
import './_baseAssignValue-812d8833.js';
import './_defineProperty-f4721394.js';
import './_getNative-4a92ccb2.js';
import './isFunction-2461489d.js';
import './isObject-c74e273c.js';
import './eq-8014c26f.js';
/**
* Check if an element is a descendant of another
*
* If the child element is a descendant of a limel-portal, this function will
* go back through the portal and check the original tree recursively
*
* @param element - the parent element
* @param child - the child element to check
* @returns `true` if child is a descendant of element, taking
* portals into account
*/
function portalContains(element, child) {
var _a;
if (element.contains(child) || ((_a = element.shadowRoot) === null || _a === void 0 ? void 0 : _a.contains(child))) {
return true;
}
const parent = findParent(child);
if (!parent) {
return false;
}
return portalContains(element, parent);
}
function findParent(element) {
const portal = element.closest('.limel-portal--container');
if (portal) {
return portal.portalSource;
}
const rootNode = element.getRootNode();
return rootNode.host;
}
const popoverCss = ".trigger-anchor{display:inline-block;position:relative}";
const Popover = class {
constructor(hostRef) {
registerInstance(this, hostRef);
this.close = createEvent(this, "close", 7);
this.handleGlobalKeyPress = (event) => {
if (event.key !== ESCAPE) {
return;
}
event.stopPropagation();
event.preventDefault();
this.close.emit();
};
this.setTriggerAttributes = (element) => {
const attributes = {
'aria-haspopup': true,
'aria-expanded': this.open,
'aria-controls': this.portalId,
role: 'button',
};
for (const [key, value] of Object.entries(attributes)) {
if (value) {
element.setAttribute(key, String(value));
}
else {
element.removeAttribute(key);
}
}
};
this.open = false;
this.openDirection = undefined;
this.portalId = createRandomString();
this.globalClickListener = this.globalClickListener.bind(this);
}
watchOpen() {
this.setupGlobalHandlers();
}
componentWillLoad() {
this.setupGlobalHandlers();
}
componentDidRender() {
const slotElement = this.host.shadowRoot.querySelector('slot');
// eslint-disable-next-line unicorn/no-array-for-each
slotElement.assignedElements().forEach(this.setTriggerAttributes);
}
setupGlobalHandlers() {
if (this.open) {
document.addEventListener('click', this.globalClickListener, {
capture: true,
});
document.addEventListener('keyup', this.handleGlobalKeyPress);
}
else {
document.removeEventListener('click', this.globalClickListener);
document.removeEventListener('keyup', this.handleGlobalKeyPress);
}
}
render() {
const cssProperties = this.getCssProperties();
const popoverZIndex = getComputedStyle(this.host).getPropertyValue('--popover-z-index');
return (h("div", { class: "trigger-anchor" }, h("slot", { name: "trigger" }), h("limel-portal", { visible: this.open, containerId: this.portalId, containerStyle: { 'z-index': popoverZIndex }, openDirection: this.openDirection }, h("limel-popover-surface", { contentCollection: this.host.children, style: cssProperties }))));
}
globalClickListener(event) {
const element = event.target;
const clickedInside = portalContains(this.host, element);
if (this.open && !clickedInside) {
event.stopPropagation();
event.preventDefault();
this.close.emit();
}
}
getCssProperties() {
const propertyNames = [
'--popover-surface-width',
'--popover-body-background-color',
'--popover-border-radius',
'--popover-box-shadow',
];
const style = getComputedStyle(this.host);
const values = propertyNames.map((property) => {
return style.getPropertyValue(property);
});
return zipObject(propertyNames, values);
}
get host() { return getElement(this); }
static get watchers() { return {
"open": ["watchOpen"]
}; }
};
Popover.style = popoverCss;
const popoverSurfaceCss = "@charset \"UTF-8\";:host(limel-popover-surface){isolation:isolate;position:relative;display:flex;width:var(--popover-surface-width, auto);max-height:inherit;max-width:calc(100vw - 2rem);margin:0 0.25rem}.limel-popover-surface{flex:1;min-width:0;min-height:0;border-radius:var(--popover-border-radius, 0.75rem);box-shadow:var(--popover-box-shadow, var(--shadow-depth-16));backdrop-filter:blur(0.3125rem);-webkit-backdrop-filter:blur(0.3125rem)}.limel-popover-surface:after{transition:opacity 0.4s ease;pointer-events:none;content:\"\";position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;opacity:0.95;border-radius:var(--popover-border-radius, 0.75rem);background-color:var(--popover-body-background-color, var(--lime-elevated-surface-background-color))}.limel-popover-surface:focus{outline:none}.limel-popover-surface:focus-visible{outline:none;box-shadow:var(--shadow-depth-8-focused)}.limel-popover-surface:focus:after,.limel-popover-surface:focus-within:after{opacity:1}.limel-popover-surface>*{box-sizing:border-box}";
const PopoverSurface = class {
constructor(hostRef) {
registerInstance(this, hostRef);
this.contentCollection = undefined;
}
componentDidLoad() {
this.appendElement();
}
render() {
return h("div", { class: "limel-popover-surface", tabindex: "0" });
}
appendElement() {
const portalContainer = this.host.shadowRoot.querySelector('.limel-popover-surface');
const childElementsCopy = [...this.contentCollection];
for (const child of childElementsCopy) {
if (child.slot === 'trigger') {
continue;
}
portalContainer.append(child);
}
}
get host() { return getElement(this); }
};
PopoverSurface.style = popoverSurfaceCss;
export { Popover as limel_popover, PopoverSurface as limel_popover_surface };
//# sourceMappingURL=limel-popover_2.entry.js.map