UNPKG

@farris/ui-vue

Version:

Farris Vue, a Farris Design based Vue3 component library.

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