UNPKG

@limetech/lime-elements

Version:
165 lines (158 loc) 6.36 kB
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