UNPKG

@farris/ui-vue

Version:

Farris Vue, a Farris Design based Vue3 component library.

272 lines (271 loc) 10 kB
import { ref as p, computed as P, watch as Y, nextTick as Z, defineComponent as _, onMounted as tt, onUnmounted as ot, createVNode as j, Teleport as et, withDirectives as nt, vShow as it } from "vue"; const lt = { id: { type: String }, title: { type: String }, placement: { type: String, default: "bottom" }, reference: { type: Object }, host: { type: Object }, leftBoundary: { type: Object }, rightBoundary: { type: Object }, visible: { type: Boolean, default: !1 }, class: { type: String }, offsetX: { type: Object, default: p(0) }, arrowOffsetX: { type: Number, default: 0 }, zIndex: { type: Number, default: -1 }, keepWidthWithReference: { type: Boolean, default: !1 }, fitContent: { type: Boolean, default: !1 }, minWidth: { type: Number, default: -1 } }; function st(t) { const e = t.host ? t.host : "body", s = P(() => e === "body" ? 0 : e ? e.getBoundingClientRect().top : 0), i = P(() => e === "body" ? 0 : e ? e.getBoundingClientRect().left : 0), d = P(() => e === "body" ? document.body.getBoundingClientRect().width : e ? e.getBoundingClientRect().width - (t.rightBoundary ? t.rightBoundary.getBoundingClientRect().width : 0) : document.body.getBoundingClientRect().width), f = P(() => e === "body" ? document.body.getBoundingClientRect().height : e ? e.getBoundingClientRect().height : document.body.getBoundingClientRect().height); return { host: e, hostLeft: i, hostTop: s, hostWidth: d, hostHeight: f }; } function ut(t, e, s, i) { const d = p(t.offsetX || 0), f = p(-1), C = p(-1), h = p(-1), b = p(t.placement), w = p(0), k = p(0), r = p(0), m = p(document.documentElement.scrollLeft), T = p(document.documentElement.scrollTop), { hostLeft: u, hostTop: g, hostWidth: E, hostHeight: W } = i; Y(() => t.offsetX, (o) => { d.value = o; }); const S = P(() => { const o = { left: `${k.value}px`, top: `${r.value}px`, transform: `translateX(${d.value}px)` }; return t.zIndex !== -1 && (o["z-index"] = t.zIndex), f.value !== -1 && (o.width = `${f.value}px`), t.minWidth !== -1 && (o.minWidth = `${t.minWidth}px`), o; }), H = P(() => ({ left: `${w.value}px`, transform: `translateX(${t.arrowOffsetX}px)` })); function y(o) { if (o && t.keepWidthWithReference) { const n = o.getBoundingClientRect(); f.value = Math.max(t.minWidth, n.width); } } function B(o, n) { const l = E.value - o.width - 4; return l > 0 ? l : n; } function I(o, n) { const l = W.value - o.height - 4; return l > 0 ? l : n; } function O(o, n, l) { const a = w.value, v = n.left - u.value + n.width / 2 + m.value, c = n.top - g.value - (o.height + l.height) + T.value; return { popoverLeft: v, popoverTop: c, arrowLeft: a }; } function M(o, n, l) { const a = n.top - g.value + (n.height + l.height) + T.value, v = I(o, a); return Math.min(a, v); } function R(o, n) { const l = B(n, o), a = o <= l ? w.value : o - l; return { popoverLeft: Math.min(o, l), arrowLeft: a }; } function X(o, n) { const l = B(n, o), a = o <= l ? w.value : o - l; return { popoverLeft: o, arrowLeft: a }; } function U(o, n, l) { const a = n.left - u.value + m.value, { arrowLeft: v, popoverLeft: c } = X(a, o), { popoverTop: L } = O(o, n, l); return { popoverLeft: c, popoverTop: L, arrowLeft: v }; } function V(o, n, l) { const a = n.left - u.value + n.width / 2 - (l.width / 2 - (o.left - u.value)) + m.value, { arrowLeft: v, popoverLeft: c } = R(a, o), L = M(o, n, l); return { popoverLeft: c, popoverTop: L, arrowLeft: v }; } function q(o, n, l) { const a = n.left - u.value + m.value, { arrowLeft: v, popoverLeft: c } = R(a, o), L = M(o, n, l); return { popoverLeft: c, popoverTop: L, arrowLeft: v }; } function G(o, n, l) { const a = n.left - u.value; let v = 0, c = 0, L = 0, z = "bottom-left"; window.innerWidth - a > o.width ? v = a + m.value : (v = n.left + n.width - o.width + m.value, L = o.width - l.width - 20); const x = n.top - g.value + (n.height + l.height); return window.innerHeight - x > o.height ? c = x + T.value : (c = n.top - o.height - l.height + T.value, window.innerHeight - x > n.top ? (c = x + T.value, o.height > n.top && (c = window.innerHeight - o.height)) : (c = c < 0 ? 0 : c, z = "top")), s.value.classList.add("popover-" + z, "bs-popover-" + z), { popoverLeft: v, popoverTop: c, arrowLeft: L }; } const J = /* @__PURE__ */ new Map([ ["top", O], ["top-left", U], ["bottom", V], ["bottom-left", q], ["auto", G] ]); function D(o) { var c, L; const n = o.getBoundingClientRect(); C.value = n.top, h.value = n.left; const l = (c = e.value) == null ? void 0 : c.getBoundingClientRect(); t.fitContent && (s.value.style.width = "auto"); const a = (L = s.value) == null ? void 0 : L.getBoundingClientRect(); f.value = a.width; const v = J.get(b.value); if (v) { const { arrowLeft: z, popoverLeft: x, popoverTop: Q } = v(a, n, l); w.value = z, k.value = x, r.value = Q; } t.keepWidthWithReference && y(o); } function K(o) { if (o) { const n = o.getBoundingClientRect(); (n.left !== h.value || n.top !== C.value) && D(o); } } return { arrowStyle: H, popoverStyle: S, position: b, popoverWidth: f, fitToReference: y, followToReferencePosition: K, locateToReference: D }; } function at(t, e, s, i, d, f, C) { const h = p(t.visible), b = P(() => h.value), { fitToReference: w, locateToReference: k } = C; let r; function m() { h.value = !1, document.body.removeEventListener("click", r), document.body.removeEventListener("mousedown", r), document.body.removeEventListener("wheel", r, !0), document.removeEventListener("scroll", r), e.emit("hidden"); } r = (u) => { var W; if (!d.value) return; const g = d.value.contains(u.target); if (u.type === "scroll" || u.type === "wheel" && g) { m(); return; } const E = (W = u.target) == null ? void 0 : W.closest(".popover"); if (E && i.value && E === i.value) { u.stopPropagation(); return; } if (!g && h.value) { const S = d.value.closest(".popover"); S && S.removeEventListener("click", r), m(); } }; async function T(u) { if (i.value && s.value && u) { h.value = !0, d.value = u, f.value && w(u), await Z(), k(u), document.body.addEventListener("click", r), document.body.addEventListener("mousedown", r), document.body.addEventListener("wheel", r, !0), document.addEventListener("scroll", r), (top == null ? void 0 : top.document) !== document && (top == null || top.document.addEventListener("mousedown", r)); const g = u.closest(".popover"); g && g.addEventListener("click", r), e.emit("shown"); } } return e.expose({ hide: m, popoverRef: i, show: T, shown: b, isShow: h }), { showPopover: h, hidePopverOnClickBodyHandler: r }; } function ct(t, e, s, i, d) { const { popoverWidth: f, fitToReference: C, followToReferencePosition: h } = d; function b() { if (s.value) { h(s.value); const w = s.value.getBoundingClientRect(); i.value && w.width !== f.value && C(s.value); } } return { onResize: b }; } const N = /* @__PURE__ */ _({ name: "FPopover", props: lt, emits: ["shown", "hidden"], setup(t, e) { const s = p(), i = p(), d = p(t.reference), f = p(t.keepWidthWithReference), C = P(() => !!t.title), h = st(t), { host: b } = h, w = ut(t, s, i, h), { position: k, arrowStyle: r, popoverStyle: m, fitToReference: T, locateToReference: u } = w, { showPopover: g, hidePopverOnClickBodyHandler: E } = at(t, e, s, i, d, f, w), { onResize: W } = ct(t, e, d, f, w), S = P(() => { let y = k.value; y === "top-left" && (y = "top"); const B = `popover in popover-${y}`, I = `bs-popover-${y}`, O = { "popover-fitcontent": t.fitContent }; return O[B] = !0, O[I] = !0, (t.class || "").split(" ").reduce((R, X) => (R[X] = !0, R), O), O; }), H = P(() => ({ "popover-content": !0, "popover-body": !0 })); return tt(() => { t.reference && u(d.value), f.value && T(d.value), window.addEventListener("resize", W); }), ot(() => { document.body.removeEventListener("click", E), window.removeEventListener("resize", W); }), () => j(et, { to: b }, { default: () => { var y; return [nt(j("div", { ref: i, class: S.value, style: m.value, onMousedown: (B) => { B.stopPropagation(); }, onClick: (B) => { B.stopPropagation(); } }, [j("div", { ref: s, class: "popover-arrow arrow", style: r.value }, null), C.value && j("h3", { class: "popover-title popover-header" }, [t.title]), j("div", { class: H.value }, [e.slots.default && ((y = e.slots) == null ? void 0 : y.default())])]), [[it, g.value]])]; } }); } }); function A(t, e, s) { t.stopPropagation(); const i = e.value; i && i.value && i.value.show(s); } function $(t, e) { t.stopPropagation(), e.value.value.hide(); } function rt(t, e, s) { t.stopPropagation(); const i = e.value; i && i.value && (i.value.isShow ? $(t, e) : A(t, e, s)); } function F(t, e, s) { e.arg && e.arg === "toggle" ? rt(t, e, s) : A(t, e, s); } const vt = { mounted: (t, e, s) => { e.modifiers.hover ? (t.addEventListener("mouseenter", (i) => A(i, e, t)), t.addEventListener("mouseleave", (i) => $(i, e))) : e.modifiers.click ? t.addEventListener("click", (i) => F(i, e, t)) : t.addEventListener("click", (i) => F(i, e, t)); }, unMounted: (t, e, s) => { } }; N.install = (t) => { t.component(N.name, N), t.directive("popover", vt); }; export { N as Popover, vt as PopoverDirective, N as default, lt as popoverProps };