UNPKG

flexipop

Version:
208 lines (207 loc) 8.26 kB
var X = Object.defineProperty; var Y = (n, e, t) => e in n ? X(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t; var o = (n, e, t) => Y(n, typeof e != "symbol" ? e + "" : e, t); const k = "bottom"; const z = ({ reference: n, popper: e }) => { if (!n || !e) throw new Error("Reference or popper element is null or undefined"); const t = /* @__PURE__ */ new WeakMap(), s = (c) => (t.has(c) || t.set(c, c.getBoundingClientRect()), t.get(c)), a = s(e), i = s(n); return { popperHeight: a.height, popperWidth: a.width, refHeight: i.height, refWidth: i.width, refLeft: i.left, refTop: i.top, refRight: i.right }; }, B = (n, e, t, s) => { const a = t, i = s - (t + e); return a >= (n - e) / 2 && i >= (n - e) / 2; }, C = (n, e, t, s) => (n - e) / 2 <= t && t + n / 2 + e / 2 <= s, U = (n, e, t, s, a) => t > a - s ? e() ? window.innerHeight - a : t - a : n() ? 0 : t + s, L = (n, e, t, s) => n <= s && t - n <= e, V = (n, e, t, s) => t <= s && -n <= e, N = (n, e, t, s, a, i) => { const c = a - t - i, r = t - s, d = t + i - s + (a - t - i), l = c >= 0 ? a - s : r >= 0 ? t - s : t; return n() ? 0 : e() ? d : l; }, _ = (n, e, t, s) => n <= t && e - n - s >= n, $ = (n, e) => n >= e, f = ({ placement: n, refWidth: e, refTop: t, refLeft: s, refHeight: a, popperWidth: i, popperHeight: c, windowHeight: r, windowWidth: d, offsetDistance: l }) => { const h = d - s - e, u = s, x = r - t - a, F = t, y = () => U( () => V(t, a, c, r), () => L(t, a, c, r), t, a, c ), P = () => N( () => _(s, d, i, e), () => $(s, i), s, i, d, e ), A = () => B(i, e, s, d) ? s + e / 2 - i / 2 : P(), T = () => C(c, a, t, r) ? t + a / 2 - c / 2 : y(), D = () => s + i <= d ? s : P(), I = () => s + e - i >= 0 ? s + e - i : P(), j = () => t + c <= r ? t : y(), g = () => t + a - c >= 0 ? t + a - c : y(); let m = 0, E = 0; const R = t - c - l, b = t + a + l, v = s - i - l, w = s + e + l, O = F >= c + l, S = x >= c + l, p = u >= i + l, M = h >= i + l; switch (n.startsWith("top") ? E = O ? R : S ? b : Math.max(R, b) : n.startsWith("bottom") ? E = S ? b : O ? R : Math.max(b) : n.startsWith("left") ? m = p ? v : M ? w : Math.max(v, w) : n.startsWith("right") && (m = M ? w : p ? v : Math.max(w, v)), n) { case "bottom": case "bottom-middle": case "top": case "top-middle": m = A(); break; case "left": case "left-middle": case "right": case "right-middle": E = T(); break; case "bottom-start": case "top-start": m = D(); break; case "bottom-end": case "top-end": m = I(); break; case "left-start": case "right-start": E = j(); break; case "left-end": case "right-end": E = g(); break; } return { x: m, y: E }; }; class G { /** * Flexilla Popper * @param reference * @param popper * @param options */ /** * Creates an instance of CreatePopper * @param {HTMLElement} reference - The reference element to position against * @param {HTMLElement} popper - The element to be positioned * @param {PopperOptions} [options] - Configuration options * @param {number} [options.offsetDistance] - Distance between popper and reference element * @param {Placement} [options.placement] - Preferred placement of the popper * @param {Object} [options.eventEffect] - Event handling configuration * @param {boolean} [options.eventEffect.disableOnResize] - Disable position updates on window resize * @param {boolean} [options.eventEffect.disableOnScroll] - Disable position updates on scroll * @param {Function} [options.onUpdate] - Callback function when position updates */ constructor(e, t, s = {}) { o(this, "reference"); o(this, "popper"); o(this, "offsetDistance"); o(this, "placement"); o(this, "disableOnResize"); o(this, "disableOnScroll"); o(this, "onUpdate"); o(this, "isWindowEventsRegistered"); /** * Validate Elements, check if reference and popper are valid HtmlELment */ o(this, "validateElements", () => { if (!(this.reference instanceof HTMLElement)) throw new Error("Invalid HTMLElement for Reference Element"); if (!(this.popper instanceof HTMLElement)) throw new Error("Invalid HTMLElement for Popper"); if (typeof this.offsetDistance != "number") throw new Error("OffsetDistance must be a number"); }); /** * Set Style Property */ o(this, "setPopperStyleProperty", (e, t) => { this.popper.style.setProperty("--fx-popper-placement-x", `${e}px`), this.popper.style.setProperty("--fx-popper-placement-y", `${t}px`); }); o(this, "setInitialStyles", () => { this.popper.style.setProperty("--fx-popper-placement-x", ""), this.popper.style.setProperty("--fx-popper-placement-y", ""); }); o(this, "initPlacement", () => { var u; this.validateElements(), this.setInitialStyles(); const e = window.innerWidth, t = window.innerHeight, { popperHeight: s, popperWidth: a, refHeight: i, refWidth: c, refLeft: r, refTop: d } = z({ reference: this.reference, popper: this.popper }), { x: l, y: h } = f( { placement: this.placement, refWidth: c, refTop: d, refLeft: r, popperWidth: a, refHeight: i, popperHeight: s, windowHeight: t, windowWidth: e, offsetDistance: this.offsetDistance } ); this.setPopperStyleProperty(l, h), (u = this.onUpdate) == null || u.call(this, { x: l, y: h, placement: this.placement }); }); o(this, "removeWindowEvents", () => { this.isWindowEventsRegistered && (!this.disableOnResize && window.removeEventListener("resize", this.updatePosition), !this.disableOnScroll && window.removeEventListener("scroll", this.updatePosition), this.isWindowEventsRegistered = !1); }); /** * Add event Listeners : window resize and scroll * These events depend on if it's disable or not */ o(this, "attachWindowEvent", () => { this.isWindowEventsRegistered && this.removeWindowEvents(), this.disableOnResize || window.addEventListener("resize", this.updatePosition), this.disableOnScroll || window.addEventListener("scroll", this.updatePosition), this.isWindowEventsRegistered = !0; }); /** * Resets the popper position by clearing positioning styles * @public */ o(this, "resetPosition", () => { this.setInitialStyles(); }); /** * Updates the popper position based on current reference element position * @public */ o(this, "updatePosition", () => { this.initPlacement(), this.attachWindowEvent(); }); /** * Remove event listerners in case they are no longer needed */ /** * Removes all event listeners and cleans up positioning styles * @public */ o(this, "cleanupEvents", () => { this.setInitialStyles(), this.removeWindowEvents(); }); const { offsetDistance: a = 10, placement: i = k, eventEffect: c = {}, onUpdate: r } = s; if (!(e instanceof HTMLElement)) throw new Error("Invalid HTMLElement for Reference Element"); if (!(t instanceof HTMLElement)) throw new Error("Invalid HTMLElement for Popper"); if (s.offsetDistance && typeof s.offsetDistance != "number") throw new Error("OffsetDistance must be a number"); const { disableOnResize: d, disableOnScroll: l } = c; this.isWindowEventsRegistered = !1, this.reference = e, this.popper = t, this.offsetDistance = a, this.placement = i, this.disableOnResize = d || !1, this.disableOnScroll = l || !1, this.onUpdate = r; } /** * Updates popper configuration and recalculates position * @public * @param {Object} options - New configuration options * @param {Placement} options.placement - New placement value * @param {number} [options.offsetDistance] - New offset distance */ setOptions({ placement: e, offsetDistance: t }) { this.placement = e, this.offsetDistance = t || this.offsetDistance, this.initPlacement(), this.attachWindowEvent(); } } export { G as CreatePopper };