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