@farris/ui-vue
Version:
Farris Vue, a Farris Design based Vue3 component library.
272 lines (271 loc) • 10 kB
JavaScript
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
};