@farris/ui-vue
Version:
Farris Vue, a Farris Design based Vue3 component library.
342 lines (341 loc) • 13.5 kB
JavaScript
import { ref as g, computed as w, 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 { getMaxZIndex as ft, useDelayedRef as ht } from "../common/index.esm.js";
const mt = {
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: g(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 },
beforeClose: { type: Function }
};
function gt(t) {
const n = t.host ? t.host : "body", a = w(() => n === "body" ? 0 : n ? n.getBoundingClientRect().top : 0), i = w(() => n === "body" ? window.innerHeight : n ? n.getBoundingClientRect().bottom : window.innerHeight), f = w(() => n === "body" ? 0 : n ? n.getBoundingClientRect().left : 0), v = w(() => n === "body" ? document.body.getBoundingClientRect().width : n ? n.getBoundingClientRect().width - (t.rightBoundary ? t.rightBoundary.getBoundingClientRect().width : 0) : document.body.getBoundingClientRect().width), T = w(() => n === "body" ? window.innerHeight : n ? n.getBoundingClientRect().height : window.innerHeight);
return { host: n, hostLeft: f, hostTop: a, hostWidth: v, hostHeight: T, hostBottom: i };
}
function wt(t, n, a, i) {
const f = g(t.offsetX || 0), v = g(-1), T = g(-1), m = g(-1), H = g(-1), b = g(t.placement), L = g(0), C = g(0), p = g(0), P = w(() => document.documentElement.scrollLeft), B = w(() => document.documentElement.scrollTop), { hostLeft: u, hostTop: h, hostWidth: S, hostHeight: W, hostBottom: x } = i;
at(() => t.offsetX, (e) => {
f.value = e;
});
const V = w(() => {
const e = {
left: `${C.value}px`,
top: `${p.value}px`,
transform: `translateX(${f.value}px)`
};
return t.zIndex !== -1 && (e["z-index"] = t.zIndex), t.fitContent ? t.keepWidthWithReference && a.value && v.value >= a.value.getBoundingClientRect().width && (e.width = `${v.value}px`) : v.value !== -1 && (e.width = `${v.value}px`), t.minWidth !== -1 && (e.minWidth = `${t.minWidth}px`), t.customStyles && Object.assign(e, t.customStyles), T.value > 0 && (e.maxHeight = T.value + "px"), e;
}), K = w(() => ({
left: `${L.value}px`,
transform: `translateX(${t.arrowOffsetX}px)`
}));
function X(e) {
if (e && t.keepWidthWithReference) {
const o = e.getBoundingClientRect();
v.value = Math.max(t.minWidth, o.width);
}
}
function d(e, o) {
const l = S.value - e.width - 4;
return l > 0 ? l : o;
}
function k(e, o) {
const l = W.value - e.height - 12;
return l > 0 ? l : o;
}
function A(e, o, l) {
const r = L.value, c = o.left - u.value + o.width / 2 + P.value, s = o.top - h.value - (e.height + l.height) + B.value;
return { popoverLeft: c, popoverTop: s, arrowLeft: r };
}
function M(e, o, l) {
const r = o.top - h.value + (o.height + l.height) + B.value, c = k(e, r);
return Math.min(r, c);
}
function j(e, o) {
const l = d(o, e), r = e <= l ? L.value : e - l;
return { popoverLeft: Math.min(e, l), arrowLeft: r, maxHeight: 0 };
}
function R(e, o) {
const l = d(o, e), r = e <= l ? L.value : e - l;
return { popoverLeft: e, arrowLeft: r, maxHeight: 0 };
}
function U(e, o, l) {
const r = o.left - u.value + P.value, { arrowLeft: c, popoverLeft: s } = R(r, e), { popoverTop: y } = A(e, o, l);
return { popoverLeft: s, popoverTop: y, arrowLeft: c, maxHeight: 0 };
}
function Y(e, o, l) {
const r = o.left - u.value + o.width / 2 - (l.width / 2 - (e.left - u.value)) + P.value, { arrowLeft: c, popoverLeft: s } = j(r, e), y = M(e, o, l);
return { popoverLeft: s, popoverTop: y, arrowLeft: c, maxHeight: 0 };
}
function $(e, o, l) {
const r = o.left - u.value + P.value, { arrowLeft: c, popoverLeft: s } = j(r, e), y = M(e, o, l);
return { popoverLeft: s, popoverTop: y, arrowLeft: c, maxHeight: 0 };
}
function tt(e, o, l) {
const r = o.left - u.value;
let c = 0, s = 0, y = 0, O = 0, E = "bottom-left";
window.innerWidth - r > e.width ? c = r + P.value : (c = o.right - e.width + P.value, y = e.width - l.width - 20);
let I = 0;
if (t.limitContentBySpace) {
const G = { topHeight: o.top - h.value - l.height - 8, bottomHeight: x.value - o.bottom - l.height - 8 };
I = Math.max(G.topHeight, G.bottomHeight), e.height > I && (O = I, a.value.classList.add("popover-limitmax"));
}
const D = O ? Math.floor(O) : e.height, F = o.top - h.value + (o.height + l.height);
return x.value - F > D ? s = F + B.value : (s = o.top - D - l.height + B.value, x.value - F > o.top ? (s = F + B.value, D > o.top && (s = x.value - D)) : (s = s < 0 ? 0 : s, E = "top")), a.value.classList.add("popover-" + E, "bs-popover-" + E), { popoverLeft: c < 0 ? 5 : c, popoverTop: s, arrowLeft: y, maxHeight: O };
}
function et(e, o, l) {
const r = o.left + o.width, c = Math.max(o.top - (e.height / 2 - o.height / 2), h.value);
let s = h.value + W.value - e.height;
s < 0 && (s = c);
const y = Math.min(c, s);
return { popoverLeft: r, popoverTop: y, arrowLeft: 0, maxHeight: 0 };
}
function ot(e, o, l) {
const r = o.left + o.width, c = Math.max(o.top - o.height, h.value);
let s = h.value + W.value - e.height;
s < 0 && (s = c);
const y = Math.min(c, s);
return { popoverLeft: r, popoverTop: y, arrowLeft: 0, maxHeight: 0 };
}
const nt = /* @__PURE__ */ new Map([
["top", A],
["top-left", U],
["bottom", Y],
["bottom-left", $],
["right", et],
["right-top", ot],
["auto", tt]
]);
function q(e) {
var s;
t.keepWidthWithReference && X(e);
const o = e.getBoundingClientRect();
m.value = o.top, H.value = o.left;
const l = n.value ? n.value.getBoundingClientRect() : { height: 4, width: 4 }, r = (s = a.value) == null ? void 0 : s.getBoundingClientRect();
v.value = r.width;
const c = nt.get(b.value);
if (c) {
const { arrowLeft: y, popoverLeft: O, popoverTop: E, maxHeight: I } = c(r, o, l);
L.value = y, C.value = O, p.value = E, T.value = I || -1;
}
}
function it(e) {
if (e) {
const o = e.getBoundingClientRect();
(o.left !== H.value || o.top !== m.value) && q(e);
}
}
function lt() {
b.value = t.placement, L.value = 0, C.value = 0, p.value = 0, v.value = -1;
}
return {
arrowStyle: K,
popoverStyle: V,
position: b,
popoverWidth: v,
fitToReference: X,
followToReferencePosition: it,
locateToReference: q,
resetPosition: lt
};
}
function yt(t, n, a, i, f, v, T) {
const m = g(t.visible), H = w(() => m.value), { fitToReference: b, locateToReference: L, resetPosition: C } = T;
let p;
async function P() {
m.value && (t.beforeClose && typeof t.beforeClose == "function" && !await t.beforeClose() || (m.value = !1, document.body.removeEventListener("click", p), document.body.removeEventListener("mousedown", p), document.body.removeEventListener("wheel", p, !0), document.removeEventListener("scroll", p), C(), n.emit("hidden")));
}
p = (u) => {
var W;
if (!f.value)
return;
const h = f.value.contains(u.target);
if (u.type === "scroll" || u.type === "wheel" && h) {
P();
return;
}
if (u.target.closest(".time-picker-panel"))
return;
const S = (W = u.target) == null ? void 0 : W.closest(".popover");
if (S && i.value && S === i.value) {
u.type !== "scroll" && u.type !== "wheel" && u.stopPropagation();
return;
}
if (!h && m.value) {
const x = f.value.closest(".popover");
x && x.removeEventListener("click", p), P();
}
};
async function B(u) {
if (i.value && (t.showArrow === !1 || t.showArrow && a.value) && u) {
m.value = !0, f.value = u, v.value && b(u), await st(), L(u), document.body.addEventListener("click", p), document.body.addEventListener("mousedown", p), document.body.addEventListener("wheel", p, !0), document.addEventListener("scroll", p), (top == null ? void 0 : top.document) !== document && (top == null || top.document.addEventListener("mousedown", p));
const h = u.closest(".popover");
h && h.addEventListener("click", p), n.emit("shown");
}
}
return n.expose({ hide: P, popoverRef: i, show: B, shown: H, isShow: m }), { showPopover: m, hidePopverOnClickBodyHandler: p };
}
function Lt(t, n, a, i, f, v) {
const { popoverWidth: T, fitToReference: m, followToReferencePosition: H } = f;
function b() {
var L;
if (v.value && ((L = v.value.style) == null ? void 0 : L.display) !== "none" && a.value) {
H(a.value);
const C = a.value.getBoundingClientRect();
i.value && C.width !== T.value && m(a.value);
}
}
return { onResize: b };
}
const Z = /* @__PURE__ */ ut({
name: "FPopover",
props: mt,
emits: ["shown", "hidden"],
setup(t, n) {
const a = g(), i = g(), f = g(t.reference), v = g(t.keepWidthWithReference), T = w(() => !!t.title), m = gt(t), {
host: H
} = m, b = wt(t, a, i, m), {
position: L,
arrowStyle: C,
popoverStyle: p,
fitToReference: P,
locateToReference: B
} = b, {
showPopover: u,
hidePopverOnClickBodyHandler: h
} = yt(t, n, a, i, f, v, b), {
onResize: S
} = Lt(t, n, f, v, b, i), W = w(() => {
let d = L.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 j = (t.class || "").split(" ");
return t.isSimpleTips && j.unshift("popover-tips"), j.reduce((R, U) => (R[U] = !0, R), M), M;
}), x = w(() => ({
"popover-content": !0,
"popover-body": !0
})), V = w(() => {
const d = {};
return d.opacity = u.value ? 1 : 0, d.visibility = u.value ? "visible" : "hidden", d.zIndex = ft() || 1060, d;
}), K = w(() => t.isSimpleTips ? !0 : t.showArrow), {
delayedValue: X
} = ht(V, 50);
return rt(() => {
var d;
v.value && P(f.value), t.reference && B(f.value), window.addEventListener("resize", S), (d = i.value) == null || d.focus();
}), ct(() => {
document.body.removeEventListener("click", h), window.removeEventListener("resize", S), u.value = !1;
}), () => z(vt, {
to: H
}, {
default: () => {
var d;
return [pt(z("div", {
tabindex: "-1",
ref: i,
class: W.value,
style: {
...p.value,
...X.value
},
onMousedown: (k) => {
k.stopPropagation();
},
onClick: (k) => {
k.stopPropagation();
}
}, [K.value && z("div", {
ref: a,
class: "popover-arrow arrow",
style: C.value
}, null), T.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]])];
}
});
}
}), N = "FarrisVue_PopoverInstancesKey";
typeof window < "u" && (window[N] = window[N] || /* @__PURE__ */ new WeakMap());
function _(t, n, a) {
t.stopPropagation();
const i = n.value;
i && i.value && !i.value.isShow && (i.value.show(a), window[N].set(a, i.value));
}
function Q(t, n, a) {
t.stopPropagation(), n.value.value.hide(), window[N].delete(a);
}
function Pt(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" ? Pt(t, n, a) : _(t, n, a);
}
const Tt = {
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) => {
}
};
Z.install = (t) => {
t.component(Z.name, Z), t.directive("popover", Tt);
};
export {
Z as Popover,
Tt as PopoverDirective,
Z as default,
mt as popoverProps
};