UNPKG

@farris/ui-vue

Version:

Farris Vue, a Farris Design based Vue3 component library.

460 lines (459 loc) 15.4 kB
import { ref as m, isRef as rt, computed as x, watch as ct, nextTick as ft, defineComponent as pt, onMounted as dt, onUnmounted as vt, createVNode as V, Teleport as ht, withDirectives as mt, vShow as wt } from "vue"; import { getMaxZIndex as gt, useDelayedRef as yt } from "../common/index.esm.js"; const Lt = { /** * 组件标识 */ id: { type: String }, /** * 可选,箭头偏移量 * @default 0 */ arrowOffsetX: { type: Number, default: 0 }, /** * 可选,附加样式表 */ class: { type: String, default: "" }, /** * 可选,自定义样式 */ customStyles: { type: Object, default: null }, /** * popover应用场景有提示、展示其他内容,可能在界面呈现上会有区别。 如果做提示使用,需要特殊样式,通过此属性控制在没有自定义样式的情况下,指定特殊样式 */ isSimpleTips: { type: Boolean, default: !1 }, /** * 是否自适应内容 * @default false */ fitContent: { type: Boolean, default: !1 }, /** * 可选,指定要弹出的内容插入到哪个元素 */ host: { type: Object }, /** * 可选,指定要弹出的内容左边界不能超过哪个元素 */ leftBoundary: { type: Object }, /** * 可选,气泡宽度与参照元素宽度保持一致 * @default false */ keepWidthWithReference: { type: Boolean, default: !1 }, /** * 最小宽度 * @default -1 */ minWidth: { type: Number, default: -1 }, offsetX: { type: Object, default: m(0) }, offsetY: { type: Object, default: m(0) }, /** * 可选,气泡显示的位置 * @default 'bottom' */ placement: { type: String, default: "bottom" }, /** * 可选,参照元素 */ reference: { type: Object }, /** * 可选,指定要弹出的内容右边界不能超过哪个元素 */ rightBoundary: { type: Object }, /** * popover应用场景有提示、展示其他内容。 通常展示其他内容,不显示箭头。 提示通常展示箭头。 */ showArrow: { type: Boolean, default: !1 }, /** * 可选,气泡标题 */ title: { type: String }, /** * 可选,弹框的初始化弹出状态 * @default false */ visible: { type: Boolean, default: !1 }, /** * 可选,z-index 值,用于手动控制层高 * @default -1 */ zIndex: { type: Number, default: -1 }, /** * 可选,是否根据空间大小重新调整,原下拉面板内容指定的高度 * @default false */ limitContentBySpace: { type: Boolean, default: !1 }, beforeClose: { type: Function } }; function Pt(t) { const n = rt(t) ? t.value : t; return typeof n == "string" ? n === "body" || typeof document > "u" ? "body" : document.querySelector(n) || "body" : !!n && typeof n.getBoundingClientRect == "function" && typeof n.insertBefore == "function" ? n : "body"; } function Tt(t) { return typeof document > "u" ? null : t === "body" ? document.body : t; } function A(t, n) { const s = Tt(t); if (!s) { const g = typeof window < "u" ? window.innerHeight : 0; return { left: 0, top: 0, width: 0, height: g, bottom: g, scrollLeft: 0, scrollTop: 0 }; } const i = s.getBoundingClientRect(), p = t === "body" || s === document.body, w = typeof window < "u" ? window.innerHeight : i.height; let { width: d } = i; !p && n && (d -= n.getBoundingClientRect().width); const { top: h } = i; let { bottom: C, height: b } = i; if (p) { const g = Math.max(i.top, 0), y = Math.min(i.bottom, w); C = y, b = Math.max(y - g, 0) || w; } return { left: i.left, top: h, width: d, height: b, bottom: C, scrollLeft: s.scrollLeft || 0, scrollTop: s.scrollTop || 0 }; } function bt(t) { const n = Pt(t.host), s = x(() => A(n, t.rightBoundary).top), i = x(() => A(n, t.rightBoundary).left), p = x(() => A(n, t.rightBoundary).bottom), w = x(() => A(n, t.rightBoundary).width), d = x(() => A(n, t.rightBoundary).height); return { host: n, hostLeft: i, hostTop: s, hostWidth: w, hostHeight: d, hostBottom: p, measure: () => A(n, t.rightBoundary) }; } function xt(t, n, s, i) { const p = m(t.offsetX || 0), w = m(t.offsetY || 0), d = m(-1), h = m(-1), C = m(-1), b = m(-1), g = m(t.placement), y = m(0), v = m(0), O = m(0); let B = i.measure(); ct(() => t.offsetX, (o) => { p.value = o; }); const c = x(() => { const o = { left: `${v.value}px`, top: `${O.value}px`, transform: `translate(${p.value}px, ${w.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), h.value > 0 && (o.maxHeight = h.value + "px"), o; }), W = x(() => ({ left: `${y.value}px`, transform: `translateX(${t.arrowOffsetX}px)` })); function L() { return B.left; } function P() { return B.top; } function E() { return B.width; } function X() { return B.height; } function I() { return B.bottom; } function H() { return B.scrollLeft; } function a() { return B.scrollTop; } function S(o) { if (o && t.keepWidthWithReference) { const e = o.getBoundingClientRect(); d.value = Math.max(t.minWidth, e.width); } } function D(o, e) { const l = E() - o.width - 4; return l > 0 ? l : e; } function j(o, e) { const l = X() - o.height - 12; return l > 0 ? l : e; } function F(o, e, l) { const f = y.value, r = e.left - L() + e.width / 2 + H(), u = e.top - P() - (o.height + l.height) + a(); return { popoverLeft: r, popoverTop: u, arrowLeft: f }; } function N(o, e, l) { const f = e.top - P() + (e.height + l.height) + a(), r = j(o, f); return Math.min(f, r); } function Y(o, e) { const l = D(e, o), f = o <= l ? y.value : o - l; return { popoverLeft: Math.min(o, l), arrowLeft: f, maxHeight: 0 }; } function $(o, e) { const l = o <= D(e, o) ? y.value : o - D(e, o); return { popoverLeft: o, arrowLeft: l, maxHeight: 0 }; } function tt(o, e, l) { const f = e.left - L() + H(), { arrowLeft: r, popoverLeft: u } = $(f, o), { popoverTop: T } = F(o, e, l); return { popoverLeft: u, popoverTop: T, arrowLeft: r, maxHeight: 0 }; } function ot(o, e, l) { const f = e.left - L() + e.width / 2 - (l.width / 2 - (o.left - L())) + H(), { arrowLeft: r, popoverLeft: u } = Y(f, o), T = N(o, e, l); return { popoverLeft: u, popoverTop: T, arrowLeft: r, maxHeight: 0 }; } function et(o, e, l) { const f = e.left - L() + H(), { arrowLeft: r, popoverLeft: u } = Y(f, o), T = N(o, e, l); return { popoverLeft: u, popoverTop: T, arrowLeft: r, maxHeight: 0 }; } function nt(o, e, l) { const f = e.left - L(); let r = 0, u = 0, T = 0, M = 0, k = "bottom-left"; window.innerWidth - f > o.width ? r = f + H() : (r = e.right - o.width - L() + H(), T = o.width - l.width - 20); let z = 0; if (t.limitContentBySpace) { const J = { topHeight: e.top - P() - l.height - 8, bottomHeight: I() - e.bottom - l.height - 8 }; z = Math.max(J.topHeight, J.bottomHeight), o.height > z && (M = z, s.value.classList.add("popover-limitmax")); } const K = M ? Math.floor(M) : o.height, q = e.top - P() + (e.height + l.height); return I() - q > K ? u = q + a() : (u = e.top - P() - K - l.height + a(), I() - q > e.top - P() ? (u = q + a(), K > e.top - P() && (u = I() - P() - K + a())) : (u = u < 0 ? 0 : u, k = "top")), s.value.classList.add("popover-" + k, "bs-popover-" + k), { popoverLeft: r < 0 ? 5 : r, popoverTop: u, arrowLeft: T, maxHeight: M }; } function it(o, e, l) { const f = e.left - L() + e.width + H(), r = Math.max( e.top - P() - (o.height / 2 - e.height / 2) + a(), a() ); let u = X() - o.height + a(); u < 0 && (u = r); const T = Math.min(r, u); return { popoverLeft: f, popoverTop: T, arrowLeft: 0, maxHeight: 0 }; } function st(o, e, l) { const f = e.left - L() + e.width + H(), r = Math.max( e.top - P() - e.height + a(), a() ); let u = X() - o.height + a(); u < 0 && (u = r); const T = Math.min(r, u); return { popoverLeft: f, popoverTop: T, arrowLeft: 0, maxHeight: 0 }; } const lt = /* @__PURE__ */ new Map([ ["top", F], ["top-left", tt], ["bottom", ot], ["bottom-left", et], ["right", it], ["right-top", st], ["auto", nt] ]); function G(o) { var u; B = i.measure(), t.keepWidthWithReference && S(o); const e = o.getBoundingClientRect(); C.value = e.top, b.value = e.left; const l = n.value ? n.value.getBoundingClientRect() : { height: 4, width: 4 }, f = (u = s.value) == null ? void 0 : u.getBoundingClientRect(); d.value = f.width; const r = lt.get(g.value); if (r) { const { arrowLeft: T, popoverLeft: M, popoverTop: k, maxHeight: z } = r(f, e, l); y.value = T, v.value = M, O.value = k, h.value = z || -1; } } function at(o) { if (o) { const e = o.getBoundingClientRect(); (e.left !== b.value || e.top !== C.value) && G(o); } } function ut() { g.value = t.placement, y.value = 0, v.value = 0, O.value = 0, d.value = -1; } return { arrowStyle: W, popoverStyle: c, position: g, popoverWidth: d, fitToReference: S, followToReferencePosition: at, locateToReference: G, resetPosition: ut }; } function Bt(t, n, s, i, p, w, d) { const h = m(t.visible), C = x(() => h.value), { fitToReference: b, locateToReference: g, resetPosition: y } = d; let v; async function O() { h.value && (t.beforeClose && typeof t.beforeClose == "function" && !await t.beforeClose() || (h.value = !1, document.body.removeEventListener("click", v), document.body.removeEventListener("mousedown", v), document.body.removeEventListener("wheel", v, !0), document.removeEventListener("scroll", v), y(), n.emit("hidden"))); } v = (c) => { var P; if (!p.value) return; const W = p.value.contains(c.target); if (c.type === "scroll" || c.type === "wheel" && W) { O(); return; } if (c.target.closest(".time-picker-panel") || c.target.closest(".fv-grid")) return; const L = (P = c.target) == null ? void 0 : P.closest(".popover"); if (L && i.value && L === i.value) { c.type !== "scroll" && c.type !== "wheel" && c.stopPropagation(); return; } if (!W && h.value) { const E = p.value.closest(".popover"); E && E.removeEventListener("click", v), O(); } }; async function B(c) { if (i.value && (t.showArrow === !1 || t.showArrow && s.value) && c) { h.value = !0, p.value = c, w.value && b(c), await ft(), g(c), 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 = c.closest(".popover"); W && W.addEventListener("click", v), n.emit("shown"); } } return n.expose({ hide: O, popoverRef: i, show: B, shown: C, isShow: h }), { showPopover: h, hidePopverOnClickBodyHandler: v }; } function Ct(t, n, s, i, p, w) { const { popoverWidth: d, fitToReference: h, followToReferencePosition: C } = p; function b() { var g; if (w.value && ((g = w.value.style) == null ? void 0 : g.display) !== "none" && s.value) { C(s.value); const y = s.value.getBoundingClientRect(); i.value && y.width !== d.value && h(s.value); } } return { onResize: b }; } const Z = /* @__PURE__ */ pt({ name: "FPopover", props: Lt, emits: ["shown", "hidden"], setup(t, n) { const s = m(), i = m(), p = m(t.reference), w = m(t.keepWidthWithReference), d = x(() => !!t.title), h = bt(t), { host: C } = h, b = xt(t, s, i, h), { position: g, arrowStyle: y, popoverStyle: v, fitToReference: O, locateToReference: B } = b, { showPopover: c, hidePopverOnClickBodyHandler: W } = Bt(t, n, s, i, p, w, b), { onResize: L } = Ct(t, n, p, w, b, i), P = x(() => { let a = g.value; a === "top-left" && (a = "top"); const S = `popover in popover-${a}`, D = `bs-popover-${a}`, j = { "popover-fitcontent": t.fitContent, fade: !0 }; j[S] = !0, j[D] = !0; const F = (t.class || "").split(" "); return t.isSimpleTips && F.unshift("popover-tips"), F.reduce((N, Y) => (N[Y] = !0, N), j), j; }), E = x(() => ({ "popover-content": !0, "popover-body": !0 })), X = x(() => { const a = {}; return a.opacity = c.value ? 1 : 0, a.visibility = c.value ? "visible" : "hidden", a.zIndex = gt() || 1060, a; }), I = x(() => t.isSimpleTips ? !0 : t.showArrow), { delayedValue: H } = yt(X, 50); return dt(() => { var a; w.value && O(p.value), t.reference && B(p.value), window.addEventListener("resize", L), (a = i.value) == null || a.focus(); }), vt(() => { document.body.removeEventListener("click", W), window.removeEventListener("resize", L), c.value = !1; }), () => V(ht, { to: C }, { default: () => { var a; return [mt(V("div", { tabindex: "-1", ref: i, class: P.value, style: { ...v.value, ...H.value }, onMousedown: (S) => { S.stopPropagation(); }, onClick: (S) => { S.stopPropagation(); } }, [I.value && V("div", { ref: s, class: "popover-arrow arrow", style: y.value }, null), d.value && V("h3", { class: "popover-title popover-header" }, [t.title]), V("div", { class: E.value }, [n.slots.default && ((a = n.slots) == null ? void 0 : a.default())])]), [[wt, c.value]])]; } }); } }), U = "FarrisVue_PopoverInstancesKey"; typeof window < "u" && (window[U] = window[U] || /* @__PURE__ */ new WeakMap()); function _(t, n, s) { t.stopPropagation(); const i = n.value; i && i.value && !i.value.isShow && (i.value.show(s), window[U].set(s, i.value)); } function R(t, n, s) { t.stopPropagation(), n.value.value.hide(), window[U].delete(s); } function Ht(t, n, s) { t.stopPropagation(); const i = n.value; i && i.value && (i.value.isShow ? R(t, n, s) : _(t, n, s)); } function Q(t, n, s) { n.arg && n.arg === "toggle" ? Ht(t, n, s) : _(t, n, s); } const Ot = { mounted: (t, n, s) => { n.modifiers.hover ? (t.addEventListener("mouseenter", (i) => _(i, n, t)), t.addEventListener("mouseleave", (i) => R(i, n, t))) : n.modifiers.click ? t.addEventListener("click", (i) => Q(i, n, t)) : t.addEventListener("click", (i) => Q(i, n, t)), t.classList.add("v-popover"); }, unMounted: (t, n, s) => { } }; Z.install = (t) => { t.component(Z.name, Z), t.directive("popover", Ot); }; export { Z as Popover, Ot as PopoverDirective, Z as default, Lt as popoverProps };