@farris/ui-vue
Version:
Farris Vue, a Farris Design based Vue3 component library.
338 lines (337 loc) • 13.1 kB
JavaScript
import { ref as m, computed as g, watch as at, nextTick as st, defineComponent as ut, onMounted as rt, onUnmounted as ct, createVNode as z, Teleport as vt, withDirectives as pt, vShow as dt } from "vue";
import { useDelayedRef as ht } from "../common/index.esm.js";
const ft = {
id: { type: String },
arrowOffsetX: { type: Number, default: 0 },
class: { type: String, default: "" },
customStyles: { type: Object, default: null },
/**
* popover应用场景有提示、展示其他内容,可能在界面呈现上会有区别。
* 如果做提示使用,需要特殊样式,通过此属性控制在没有自定义样式的情况下,指定特殊样式
*/
isSimpleTips: { type: Boolean, default: !1 },
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
},
/**
* popover应用场景有提示、展示其他内容。
* 通常展示其他内容,不显示箭头。
* 提示通常展示箭头。
*/
showArrow: { type: Boolean, default: !1 },
title: { type: String },
visible: { type: Boolean, default: !1 },
zIndex: { type: Number, default: -1 },
/**
* 根据空间大小重新调整,原下拉面板内容指定的高度
*/
limitContentBySpace: { type: Boolean, default: !1 }
};
function mt(t) {
const n = t.host ? t.host : "body", a = g(() => n === "body" ? 0 : n ? n.getBoundingClientRect().top : 0), i = g(() => n === "body" ? window.innerHeight : n ? n.getBoundingClientRect().bottom : window.innerHeight), h = g(() => n === "body" ? 0 : n ? n.getBoundingClientRect().left : 0), p = g(() => n === "body" ? document.body.getBoundingClientRect().width : n ? n.getBoundingClientRect().width - (t.rightBoundary ? t.rightBoundary.getBoundingClientRect().width : 0) : document.body.getBoundingClientRect().width), P = g(() => n === "body" ? window.innerHeight : n ? n.getBoundingClientRect().height : window.innerHeight);
return { host: n, hostLeft: h, hostTop: a, hostWidth: p, hostHeight: P, hostBottom: i };
}
function gt(t, n, a, i) {
const h = m(t.offsetX || 0), p = m(-1), P = m(-1), w = m(-1), C = m(-1), T = m(t.placement), b = m(0), O = m(0), v = m(0), y = g(() => document.documentElement.scrollLeft), B = g(() => document.documentElement.scrollTop), { hostLeft: u, hostTop: f, hostWidth: S, hostHeight: H, hostBottom: x } = i;
at(() => t.offsetX, (o) => {
h.value = o;
});
const V = g(() => {
const o = {
left: `${O.value}px`,
top: `${v.value}px`,
transform: `translateX(${h.value}px)`
};
return t.zIndex !== -1 && (o["z-index"] = t.zIndex), t.fitContent ? t.keepWidthWithReference && a.value && p.value >= a.value.getBoundingClientRect().width && (o.width = `${p.value}px`) : p.value !== -1 && (o.width = `${p.value}px`), t.minWidth !== -1 && (o.minWidth = `${t.minWidth}px`), t.customStyles && Object.assign(o, t.customStyles), P.value > 0 && (o.maxHeight = P.value + "px"), o;
}), K = g(() => ({
left: `${b.value}px`,
transform: `translateX(${t.arrowOffsetX}px)`
}));
function X(o) {
if (o && t.keepWidthWithReference) {
const e = o.getBoundingClientRect();
p.value = Math.max(t.minWidth, e.width);
}
}
function d(o, e) {
const l = S.value - o.width - 4;
return l > 0 ? l : e;
}
function k(o, e) {
const l = H.value - o.height - 4;
return l > 0 ? l : e;
}
function A(o, e, l) {
const r = b.value, c = e.left - u.value + e.width / 2 + y.value, s = e.top - f.value - (o.height + l.height) + B.value;
return { popoverLeft: c, popoverTop: s, arrowLeft: r };
}
function M(o, e, l) {
const r = e.top - f.value + (e.height + l.height) + B.value, c = k(o, r);
return Math.min(r, c);
}
function I(o, e) {
const l = d(e, o), r = o <= l ? b.value : o - l;
return { popoverLeft: Math.min(o, l), arrowLeft: r, maxHeight: 0 };
}
function R(o, e) {
const l = d(e, o), r = o <= l ? b.value : o - l;
return { popoverLeft: o, arrowLeft: r, maxHeight: 0 };
}
function U(o, e, l) {
const r = e.left - u.value + y.value, { arrowLeft: c, popoverLeft: s } = R(r, o), { popoverTop: L } = A(o, e, l);
return { popoverLeft: s, popoverTop: L, arrowLeft: c, maxHeight: 0 };
}
function Y(o, e, l) {
const r = e.left - u.value + e.width / 2 - (l.width / 2 - (o.left - u.value)) + y.value, { arrowLeft: c, popoverLeft: s } = I(r, o), L = M(o, e, l);
return { popoverLeft: s, popoverTop: L, arrowLeft: c, maxHeight: 0 };
}
function Z(o, e, l) {
const r = e.left - u.value + y.value, { arrowLeft: c, popoverLeft: s } = I(r, o), L = M(o, e, l);
return { popoverLeft: s, popoverTop: L, arrowLeft: c, maxHeight: 0 };
}
function tt(o, e, l) {
const r = e.left - u.value;
let c = 0, s = 0, L = 0, W = 0, E = "bottom-left";
window.innerWidth - r > o.width ? c = r + y.value : (c = e.right - o.width + y.value, L = o.width - l.width - 20);
let j = 0;
if (t.limitContentBySpace) {
const G = { topHeight: e.top - f.value - l.height - 8, bottomHeight: x.value - e.bottom - l.height - 8 };
j = Math.max(G.topHeight, G.bottomHeight), o.height > j && (W = j, a.value.classList.add("popover-limitmax"));
}
const D = W ? Math.floor(W) : o.height, N = e.top - f.value + (e.height + l.height);
return x.value - N > D ? s = N + B.value : (s = e.top - D - l.height + B.value, x.value - N > e.top ? (s = N + B.value, D > e.top && (s = x.value - D)) : (s = s < 0 ? 0 : s, E = "top")), a.value.classList.add("popover-" + E, "bs-popover-" + E), { popoverLeft: c, popoverTop: s, arrowLeft: L, maxHeight: W };
}
function ot(o, e, l) {
const r = e.left + e.width, c = Math.max(e.top - (o.height / 2 - e.height / 2), f.value);
let s = f.value + H.value - o.height;
s < 0 && (s = c);
const L = Math.min(c, s);
return { popoverLeft: r, popoverTop: L, arrowLeft: 0, maxHeight: 0 };
}
function et(o, e, l) {
const r = e.left + e.width, c = Math.max(e.top - e.height, f.value);
let s = f.value + H.value - o.height;
s < 0 && (s = c);
const L = Math.min(c, s);
return { popoverLeft: r, popoverTop: L, arrowLeft: 0, maxHeight: 0 };
}
const nt = /* @__PURE__ */ new Map([
["top", A],
["top-left", U],
["bottom", Y],
["bottom-left", Z],
["right", ot],
["right-top", et],
["auto", tt]
]);
function q(o) {
var s;
t.keepWidthWithReference && X(o);
const e = o.getBoundingClientRect();
w.value = e.top, C.value = e.left;
const l = n.value ? n.value.getBoundingClientRect() : { height: 4, width: 4 }, r = (s = a.value) == null ? void 0 : s.getBoundingClientRect();
p.value = r.width;
const c = nt.get(T.value);
if (c) {
const { arrowLeft: L, popoverLeft: W, popoverTop: E, maxHeight: j } = c(r, e, l);
b.value = L, O.value = W, v.value = E, P.value = j || -1;
}
}
function it(o) {
if (o) {
const e = o.getBoundingClientRect();
(e.left !== C.value || e.top !== w.value) && q(o);
}
}
function lt() {
T.value = t.placement, b.value = 0, O.value = 0, v.value = 0, p.value = -1;
}
return {
arrowStyle: K,
popoverStyle: V,
position: T,
popoverWidth: p,
fitToReference: X,
followToReferencePosition: it,
locateToReference: q,
resetPosition: lt
};
}
function wt(t, n, a, i, h, p, P) {
const w = m(t.visible), C = g(() => w.value), { fitToReference: T, locateToReference: b, resetPosition: O } = P;
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), O(), n.emit("hidden");
}
v = (u) => {
var H;
if (!h.value)
return;
const f = h.value.contains(u.target);
if (u.type === "scroll" || u.type === "wheel" && f) {
y();
return;
}
const S = (H = u.target) == null ? void 0 : H.closest(".popover");
if (S && i.value && S === i.value) {
u.type !== "scroll" && u.type !== "wheel" && u.stopPropagation();
return;
}
if (!f && w.value) {
const x = h.value.closest(".popover");
x && x.removeEventListener("click", v), y();
}
};
async function B(u) {
if (i.value && (t.showArrow === !1 || t.showArrow && a.value) && u) {
w.value = !0, h.value = u, p.value && T(u), await st(), b(u), 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 f = u.closest(".popover");
f && f.addEventListener("click", v), n.emit("shown");
}
}
return n.expose({ hide: y, popoverRef: i, show: B, shown: C, isShow: w }), { showPopover: w, hidePopverOnClickBodyHandler: v };
}
function Lt(t, n, a, i, h) {
const { popoverWidth: p, fitToReference: P, followToReferencePosition: w } = h;
function C() {
if (a.value) {
w(a.value);
const T = a.value.getBoundingClientRect();
i.value && T.width !== p.value && P(a.value);
}
}
return { onResize: C };
}
const _ = /* @__PURE__ */ ut({
name: "FPopover",
props: ft,
emits: ["shown", "hidden"],
setup(t, n) {
const a = m(), i = m(), h = m(t.reference), p = m(t.keepWidthWithReference), P = g(() => !!t.title), w = mt(t), {
host: C
} = w, T = gt(t, a, i, w), {
position: b,
arrowStyle: O,
popoverStyle: v,
fitToReference: y,
locateToReference: B
} = T, {
showPopover: u,
hidePopverOnClickBodyHandler: f
} = wt(t, n, a, i, h, p, T), {
onResize: S
} = Lt(t, n, h, p, T), H = g(() => {
let d = b.value;
d === "top-left" && (d = "top");
const k = `popover in popover-${d}`, A = `bs-popover-${d}`, M = {
"popover-fitcontent": t.fitContent,
fade: !0
};
M[k] = !0, M[A] = !0;
const I = (t.class || "").split(" ");
return t.isSimpleTips && I.unshift("popover-tips"), I.reduce((R, U) => (R[U] = !0, R), M), M;
}), x = g(() => ({
"popover-content": !0,
"popover-body": !0
})), V = g(() => {
const d = {};
return d.opacity = u.value ? 1 : 0, d.visibility = u.value ? "visible" : "hidden", d;
}), K = g(() => t.isSimpleTips ? !0 : t.showArrow), {
delayedValue: X
} = ht(V, 50);
return rt(() => {
var d;
p.value && y(h.value), t.reference && B(h.value), window.addEventListener("resize", S), (d = i.value) == null || d.focus();
}), ct(() => {
document.body.removeEventListener("click", f), window.removeEventListener("resize", S);
}), () => z(vt, {
to: C
}, {
default: () => {
var d;
return [pt(z("div", {
tabindex: "-1",
ref: i,
class: H.value,
style: {
...v.value,
...X.value
},
onMousedown: (k) => {
k.stopPropagation();
},
onClick: (k) => {
k.stopPropagation();
}
}, [K.value && z("div", {
ref: a,
class: "popover-arrow arrow",
style: O.value
}, null), P.value && z("h3", {
class: "popover-title popover-header"
}, [t.title]), z("div", {
class: x.value
}, [n.slots.default && ((d = n.slots) == null ? void 0 : d.default())])]), [[dt, u.value]])];
}
});
}
}), F = "FarrisVue_PopoverInstancesKey";
window[F] = window[F] || /* @__PURE__ */ new WeakMap();
function $(t, n, a) {
t.stopPropagation();
const i = n.value;
i && i.value && !i.value.isShow && (i.value.show(a), window[F].set(a, i.value));
}
function Q(t, n, a) {
t.stopPropagation(), n.value.value.hide(), window[F].delete(a);
}
function yt(t, n, a) {
t.stopPropagation();
const i = n.value;
i && i.value && (i.value.isShow ? Q(t, n, a) : $(t, n, a));
}
function J(t, n, a) {
n.arg && n.arg === "toggle" ? yt(t, n, a) : $(t, n, a);
}
const Pt = {
mounted: (t, n, a) => {
n.modifiers.hover ? (t.addEventListener("mouseenter", (i) => $(i, n, t)), t.addEventListener("mouseleave", (i) => Q(i, n, t))) : n.modifiers.click ? t.addEventListener("click", (i) => J(i, n, t)) : t.addEventListener("click", (i) => J(i, n, t)), t.classList.add("v-popover");
},
unMounted: (t, n, a) => {
}
};
_.install = (t) => {
t.component(_.name, _), t.directive("popover", Pt);
};
export {
_ as Popover,
Pt as PopoverDirective,
_ as default,
ft as popoverProps
};