UNPKG

ranui

Version:

A framework-agnostic Web Components UI library built on native custom elements, with TypeScript types, light/dark theming, SSR and PWA support.

199 lines (198 loc) 7.92 kB
import { T as u, _ as f, i as l, p as w } from "./factory-WDxu11V0.js"; import { t as y } from "./events-Cqz3ramM.js"; import "./builder-EH76YCFS.js"; import { a as b, i as s, n as p, o as C, t as D } from "./utils-U-9uH7EX.js"; import { a as P, n as I } from "./ssr-BzykYefm.js"; import { n as k } from "./a11y-ZSlIUH9B.js"; import "./dropdown-B6i_Wh9a.js"; import { t as T } from "./floating-C16PP_Xu.js"; import "./content-CaSimA6g.js"; import { debounce as r, isMobile as d } from "ranuts/utils"; var _ = ":host{display:var(--ran-popover-host-display, block)}.ran-popover{box-sizing:var(--ran-popover-box-sizing, border-box);position:var(--ran-popover-position, relative);display:var(--ran-popover-display, block);margin:var(--ran-popover-margin, 0);padding:var(--ran-popover-padding, 0)}.ran-popover-block{display:var(--ran-popover-block-display, block)}", x = 8, R = 300, n = 16, z = /* @__PURE__ */ (function(e) { return e.TOP = "top", e.BOTTOM = "bottom", e.LEFT = "left", e.RIGHT = "right", e; })({}), c = { top: "bottom", bottom: "top", left: "right", right: "left" }, A = class extends I { _events = new y(); _slot; popoverBlock; popoverContent; popoverInner; popoverInnerBlock; _shadowDom; removeTimeId; _repositionBound = !1; _floating = new T({ host: this, panel: () => this.popoverContent, anchor: () => Array.from(this.children).find((e) => e.tagName !== "R-CONTENT") ?? this, placement: () => this.placement, offset: x, containerId: () => this.getPopupContainerId, afterPosition: (e, t) => { const { anchorRect: o, panelRect: i, side: v } = e, h = c[v]; h && t.setAttribute("arrow", h), t.style.setProperty("--ran-dropdown-arrow-anchor-width", `${o.width}px`), t.style.setProperty("--ran-dropdown-arrow-anchor-height", `${o.height}px`), t.style.setProperty("--ran-dropdown-min-width", `${i.width}px`), t.style.setProperty("--ran-dropdown-min-height", `${i.height}px`); const a = t.getBoundingClientRect(), m = o.left + o.width / 2, g = a.left + a.width / 2; t.style.setProperty("--ran-dropdown-arrow-anchor-offset", `${m - g}px`), t.style.setProperty("--ran-dropdown-arrow-anchor-offset-y", `${o.top - a.top}px`); } }); static get observedAttributes() { return [ "open", "placement", "trigger", "sheet" ]; } closePopover = () => { this.setDropdownDisplayNone(); }; constructor() { super(), this._shadowDom = D(this, _); const e = u(), t = l().class("ran-popover-block").role("tooltip").children(w().class("slot").ref(e)).build(); this._shadowDom.appendChild(t), this.popoverBlock = t, this._slot = b(e, "slot"); } get placement() { return p(this, "placement", "top"); } set placement(e) { s(this, "placement", e); } get placementSide() { return this.placement.split("-")[0]; } get open() { return this.hasAttribute("open"); } set open(e) { e ? this.setAttribute("open", "") : this.removeAttribute("open"); } _applyOpen = () => { this._floating.apply(this.open); }; show = () => { this.open = !0; }; hide = () => { this.open = !1; }; toggle = () => { this.open = !this.open; }; get trigger() { return p(this, "trigger", "hover"); } set trigger(e) { s(this, "trigger", e); } get getPopupContainerId() { return p(this, "getPopupContainerId"); } set getPopupContainerId(e) { s(this, "getPopupContainerId", e); } get sheet() { return p(this, "sheet"); } set sheet(e) { s(this, "sheet", e); } handlerExternalCss = () => { C(this, this._shadowDom, "sheet", null, this.sheet); }; initAria = () => { this.hasAttribute("tabindex") || (this.tabIndex = 0), this.setAttribute("aria-haspopup", "dialog"), this.setAttribute("aria-expanded", "false"); }; updateAriaExpanded = (e) => { this.setAttribute("aria-expanded", e ? "true" : "false"); }; stopPropagation = (e) => { e.stopPropagation(); }; createContent = (e) => { if (e) { if (!this.popoverContent) { const t = getComputedStyle(this).getPropertyValue("--ran-popover-content-padding").trim() || "12px"; this.popoverContent = f("r-dropdown").class("ran-popover-dropdown").style("display", "none").style("position", "absolute").cssVar("ran-dropdown-padding", t).build(), this.popoverContent?.addEventListener("click", this.stopPropagation); const o = l().children(this.popoverContent).build(); this.popoverInner = o, this.trigger.includes("hover") && !d() && (this.popoverContent?.addEventListener("mouseleave", this.blur), this.popoverContent?.addEventListener("mouseenter", this.removeDropDownTimeId)); const i = this.getRootNode(); ((i.getElementById ? i.getElementById(this.getPopupContainerId) : null) || document.getElementById(this.getPopupContainerId) || document.body).appendChild(o); } if (this.popoverContent && e.length > 0) { this.popoverContent.innerHTML = ""; const t = document.createDocumentFragment(); for (const o of e) t.appendChild(o); this.popoverContent.appendChild(t); } } }; watchContent = (e) => { const { value: t } = e.detail; this.createContent(t.content); }; blur = r(() => { this.removeTimeId && this.removeDropDownTimeId(), this.removeTimeId = setTimeout(() => { this.removeDropDownTimeId(), this.setDropdownDisplayNone(); }, R); }, n); removeDropDownTimeId = r(() => { this.trigger.includes("hover") && !d() && (clearTimeout(this.removeTimeId), this.removeTimeId = void 0); }, n); setDropdownDisplayBlock = r(() => { this.open = !0; }, n); setDropdownDisplayNone = r(() => { this.open = !1; }, n); placementPosition = () => { this._floating.position(); }; hoverPopover = (e) => { e.stopPropagation(), e.preventDefault(), this.setDropdownDisplayBlock(); }; clickContent = (e) => { e.stopPropagation(); }; clickPopover = (e) => { e.stopPropagation(), e.preventDefault(), this.toggle(); }; keydownPopover = (e) => { k(e) && (e.preventDefault(), this.setDropdownDisplayBlock()), e.key === "Escape" && (e.preventDefault(), this.setDropdownDisplayNone()); }; clickRemovePopover = (e) => { this.hoverRemovePopover(e); }; popoverTrigger = () => { this._events.abort(); for (const e of this.children) e.tagName === "R-CONTENT" && this._events.on(e, "change", this.watchContent); this.trigger.includes("hover") && (this._events.on(this, "mouseenter", this.hoverPopover), this._events.on(this, "mouseleave", this.blur)), this._events.on(this, "click", this.clickPopover).on(this, "keydown", this.keydownPopover).on(document, "click", this.clickRemovePopover); }; hoverRemovePopover = (e) => { e.stopPropagation(), this.setDropdownDisplayNone(); }; changePlacement = r(() => { if (!this.getPopupContainerId && this.open) return; const e = c[this.placementSide]; e && this.popoverContent?.setAttribute("arrow", e); }, n); connectedCallback() { this.initAria(), this.handlerExternalCss(); for (const e of this.children) e.tagName === "R-CONTENT" && this.createContent(e.children); this.popoverTrigger(), this.changePlacement(); } disconnectedCallback() { this._events.abort(), this.setDropdownDisplayBlock.cancel(), this.setDropdownDisplayNone.cancel(), this.blur.cancel(), this.removeDropDownTimeId.cancel(), this._floating.destroy(), clearTimeout(this.removeTimeId), this.removeTimeId = void 0, this.popoverInner?.remove(), this.popoverInner = void 0, this.popoverContent = void 0; } attributeChangedCallback(e, t, o) { t !== o && (e === "trigger" && this.popoverTrigger(), e === "placement" && this.changePlacement(), e === "sheet" && this.handlerExternalCss(), e === "open" && this._applyOpen()); } }; P("r-popover", A); export { A as n, z as t };