UNPKG

@farris/ui-vue

Version:

Farris Vue, a Farris Design based Vue3 component library.

342 lines (341 loc) 13.5 kB
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 };