UNPKG

@ulu/frontend

Version:

A framework-agnostic frontend toolkit providing a modular, tree-shakable library of accessible components and utilities. Designed for seamless integration, it features a highly configurable SCSS system for any environment and vanilla JavaScript modules op

78 lines (77 loc) 2.5 kB
import { ComponentInitializer as p } from "../core/component.js"; import { createFloatingUi as f } from "../utils/floating-ui.js"; import { Collapsible as u } from "./collapsible.js"; const r = new p({ type: "popover", baseAttribute: "data-ulu-popover" }), d = r.attributeSelector("trigger-anchor"), h = r.attributeSelector("arrow"), m = r.getAttribute("content"), b = r.attributeSelector("content"), c = /* @__PURE__ */ new WeakMap(), g = { clickOutsideCloses: !0, escapeCloses: !0 }; function I() { r.init({ key: "trigger", withData: !0, coreEvents: ["pageModified"], setup({ element: t, data: e, initialize: n }) { if (c.has(t)) return; const o = y(t, e); if (!o) { r.warn("Unable to resolve popover elements for trigger.", t); return; } const { elements: s, options: i, floatingOptions: a } = o; c.set(s, new S(s, i, a)), n(); } }); } function y(t, e) { const n = Object.assign({}, e), o = C(t), s = { trigger: t, content: o, anchor: t.querySelector(d) || t, contentArrow: o.querySelector(h) }, i = n.floating || {}; return delete n.floating, o ? { elements: s, options: n, floatingOptions: i } : (r.logError("Unable to make popover for", t), !1); } function C(t) { var o; let e; const n = t.getAttribute("aria-controls"); if (n) e = document.getElementById(n); else if ((o = t == null ? void 0 : t.nextElementSibling) != null && o.hasAttribute(m)) e = t.nextElementSibling; else { const s = Array.from(t.parentNode.children), i = s.findIndex((l) => l === t); e = s.slice(i).find((l) => l.matches(b)); } return e || r.logError("Unable to resolve 'content' element for popover", t), e; } class S extends u { constructor(e, n, o) { const s = Object.assign({}, g, n); super(e, s), this.floatingOptions = o || {}; } setState(e, n) { super.setState(e, n), this.destroyFloatingInstance(), e && this.createFloatingInstance(); } destroy() { super.destroy(), this.destroyFloatingInstance(); } createFloatingInstance() { const { content: e, anchor: n, contentArrow: o } = this.elements, s = { trigger: n, contentArrow: o, content: e }; this.floatingCleanup = f(s, this.floatingOptions); } destroyFloatingInstance() { this.floatingCleanup && (this.floatingCleanup(), this.floatingCleanup = null); } } export { S as Popover, C as getContentByTrigger, I as init, r as initializer, c as instances, y as resolve };