UNPKG

@farris/ui-vue

Version:

Farris Vue, a Farris Design based Vue3 component library.

338 lines (337 loc) 13.1 kB
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 };