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