UNPKG

@farris/ui-vue

Version:

Farris Vue, a Farris Design based Vue3 component library.

328 lines (327 loc) 11.2 kB
import { ref as m, computed as b, defineComponent as G, onMounted as J, createVNode as y, Fragment as W, Teleport as X, nextTick as R, reactive as Y, createApp as q, onUnmounted as U, mergeProps as $ } from "vue"; const K = { /** 提示内容 */ content: { type: String, default: "" }, /** 模板提示内容 */ contentTemplate: { type: Object }, /** 提示框宽度,例如'200px' */ width: { type: String }, /** 提示框自定义样式,应用与提示框最外层 */ customClass: { type: String }, /** 提示方向 */ placement: { type: String, default: "top" }, /** 触发提示的时机 */ trigger: { type: String, default: "hover" }, // 此变量在指令中不对外 reference: { type: Object, require: !0 }, horizontalRelative: { type: String, default: "" }, verticalRelative: { type: String, default: "" }, clickToHide: { type: Boolean, default: !0 } }; function Q(e, i) { const c = /* @__PURE__ */ new Map([ ["top", "bottom"], ["bottom", "top"], ["left", "right"], ["right", "left"] ]), n = /* @__PURE__ */ new Map([ ["top", "height"], ["bottom", "height"], ["left", "width"], ["right", "width"] ]); function u(t, l) { const a = c.get(l) || l; return t.replace(l, a); } function s(t, l, a, o, d) { let v = t; const r = t.split("-")[0], p = n.get(r), g = o[p] + d[p]; return Math.abs(a[r] - l[r]) < g && (v = u(t, r)), v; } return { adjustPlacement: s }; } function Z(e, i) { function n(s, t, l) { let a = !1, o = l; return (t === "left" || t === "top") && l <= s[t] && (a = !0, o = s[t] + 6), (t === "right" || t === "bottom") && l >= s[t] && (a = !0, o = s[t] - 6), { overBound: a, fixedValue: o }; } function u(s, t, l, a, o, d, v) { let r = t.tooltip.left, p = t.tooltip.top, g = t.arrow.left, w = t.arrow.top; const T = s.split("-")[0]; if (["top", "bottom"].includes(T)) { const S = n(l, "left", t.tooltip.left), j = n(l, "right", t.tooltip.left + o.width); r = S.overBound ? S.fixedValue : j.overBound ? j.fixedValue - o.width : t.tooltip.left, g = S.overBound ? o.width - (r + o.width - a.right) - v.width : j.overBound ? a.left - r : t.arrow.left; } const P = n(l, "top", t.tooltip.top), x = n(l, "bottom", t.tooltip.top + o.height); return p = P.overBound ? P.fixedValue : x.overBound ? x.fixedValue - o.height : t.tooltip.top, w = P.overBound ? t.arrow.top : x.overBound ? o.height - (p + o.height - a.top) : t.arrow.top, { arrow: { left: g, top: w }, tooltip: { left: r, top: p } }; } return { adjustPosition: u }; } function _(e, i) { function n(t, l, a, o, d) { const v = t.split("-"), r = v[0], p = v[1] || "middle", g = ["top", "bottom"].includes(r) ? p === "middle" ? (o.width - d.width) / 2 : p === "right" ? o.width - d.width - 6 : 6 : 0, w = ["left", "right"].includes(r) ? p === "middle" ? (o.height - d.height) / 2 : p === "bottom" ? o.height - d.height - 6 : 6 : 0, k = r === "left" ? o.width + d.width : 0, T = r === "top" ? o.height + d.height : 0; return { left: k + g, top: T + w, right: 0 }; } function u(t, l, a, o, d) { const v = t.split("-"), r = v[0], p = v[1] || "middle", g = (a.width - o.width) / 2, w = (a.height - o.height) / 2, k = r === "right" ? l.right : l.left, T = r === "bottom" ? l.bottom : l.top, P = r === "top" ? 0 - w - o.height - d.height : r === "bottom" ? 0 - w + d.height : 0, x = ["left", "right"].includes(r) ? p === "middle" ? (l.height - o.height) / 2 : p === "bottom" ? l.height - o.height : 0 : 0, C = r === "left" ? 0 - g - o.width - d.width : r === "right" ? 0 - g + d.width : 0, E = ["top", "bottom"].includes(r) ? p === "middle" ? (l.width - o.width) / 2 : p === "right" ? l.width - o.width : 0 : 0, S = T + P + x; return { left: k + C + E, top: S }; } function s(t, l, a, o, d) { const v = u(t, l, a, o, d); return { arrow: n(t, l, a, o, d), tooltip: v }; } return { calculate: s }; } function B(e, i) { const c = m(e.horizontalRelative), n = m(e.verticalRelative); function u(t) { return typeof t == "string" ? document.querySelector(t) : t; } function s() { let t = document.documentElement.clientWidth, l = document.documentElement.clientHeight, a = 0, o = 0, d = 0, v = 0, r = l - a, p = t - o; return c.value && ({ left: o, right: t, x: d, width: p } = u(c.value).getBoundingClientRect()), n.value && ({ bottom: l, top: a, y: v, height: r } = u(n.value).getBoundingClientRect()), { top: a, left: o, right: t, bottom: l, height: r, width: p, x: d, y: v }; } return { getRelativeElementBound: s }; } function tt(e, i, c, n, u, s) { const t = m(e.placement), { getRelativeElementBound: l } = B(e), { calculate: a } = _(), { adjustPlacement: o } = Q(), { adjustPosition: d } = Z(), v = b(() => t.value.split("-")[0]), r = b(() => { const p = l(); t.value = o(t.value, p, c, n, s); const g = a(t.value, c, n, u, s); return d( t.value, g, p, c, n, u, s ); }); return { tooltipPlacement: v, tooltipPosition: r }; } function et(e) { const i = m(), c = m(!1), n = b(() => ({ display: c.value ? "block" : "none" })), u = b(() => { var t; const s = (t = e.customClass) == null ? void 0 : t.split(" "); return s == null ? void 0 : s.reduce((l, a) => (l[a] = !0, l), {}); }); return { showTooltip: c, tooltipDisplayStyle: n, tooltipCustomClass: u, tooltipContainerRef: i }; } const A = /* @__PURE__ */ G({ name: "FTooltip", props: K, emits: ["click"], setup(e, i) { const c = m(), n = m(), u = m(), s = m(), t = m(), l = m(e.placement.split("-")[0]), a = et(e), { showTooltip: o, tooltipDisplayStyle: d, tooltipCustomClass: v, tooltipContainerRef: r } = a, p = b(() => { let f = { tooltip: !0, show: !0 }; const h = `bs-tooltip-${l.value}`; return f[h] = !0, i.slots.default && (f = { ...f, ...v.value }), f; }), g = b(() => e.content && !e.contentTemplate), w = b(() => e.content), k = m("0px"), T = m("0px"), P = b(() => { const f = { left: k.value, top: T.value }; return i.slots.default, f; }), x = m(""), C = m(""), E = b(() => ({ left: x.value, top: C.value })), S = b(() => ({ "tooltip-inner": !0, "tooltip-inner-lg": s.value && s.value && s.value.scrollHeight > s.value.clientHeight })), j = b(() => { const f = {}; return e.width && Object.assign(f, { width: e.width, "max-width": "none" }), f; }), L = (f) => { if (n.value && u.value && s.value) { const { tooltipPlacement: h, tooltipPosition: O } = tt(e, i, f.getBoundingClientRect(), u.value.getBoundingClientRect(), s.value.getBoundingClientRect(), n.value.getBoundingClientRect()); k.value = `${O.value.tooltip.left + document.documentElement.scrollLeft}px`, T.value = `${O.value.tooltip.top + document.documentElement.scrollTop}px`, x.value = `${O.value.arrow.left}px`, C.value = `${O.value.arrow.top}px`, l.value = h.value; } }, D = (f) => { f.addEventListener("mouseenter", (h) => { h.stopPropagation(), o.value = !0, R(() => { L(f); }); }), f.addEventListener("mouseleave", (h) => { h.stopPropagation(), h.target !== t.value && (o.value = !1); }); }; function N(f) { f.addEventListener("click", (h) => { h.stopPropagation(), o.value = !0, R(() => { L(f); }); }), document.body.addEventListener("click", (h) => { h.stopPropagation(), h.target !== t.value && (o.value = !1); }); } J(() => { var h; const f = (h = c.value) == null ? void 0 : h.nextElementSibling; f && (e.trigger === "click" ? N(f) : D(f)), !g.value && e.contentTemplate && t.value && t.value.appendChild(e.contentTemplate), e.reference && L(e.reference); }); function H(f) { i.emit("click", f); } const F = () => y("div", { ref: u, class: p.value, style: P.value, onClick: H }, [y("div", { ref: n, class: "arrow", style: E.value }, null), y("div", { ref: s, class: S.value, style: j.value }, [y("div", { class: "tooltip-tmpl" }, [g.value && y("div", { class: "tooltip-text", innerHTML: w.value }, null), !g.value && y("div", { class: "tooltip-text", ref: t }, null)])])]), I = () => y("div", { ref: u, class: p.value, style: P.value, onClick: H }, [y("div", { ref: n, class: "arrow", style: E.value }, null), y("div", { ref: s, class: S.value, style: j.value }, [y("div", { class: "tooltip-tmpl" }, [y("div", { class: "tooltip-text", ref: t }, [i.slots.contentTemplate ? i.slots.contentTemplate() : e.content])])])]); return () => i.slots.default ? y(W, { ref: c }, [i.slots.default(), y(X, { to: "body" }, { default: () => [o.value && I()] })]) : F(); } }); function ot(e, i) { const c = document.createElement("div"); e.customClass && (c.className = e.customClass); const n = q({ setup() { function u() { e.clickToHide && n.unmount(); } return U(() => { document.body.removeChild(c); }), () => y(A, $(e, { onClick: u }), null); } }); return document.body.appendChild(c), n.mount(c), n; } function z(e) { const i = Y({ ...e }); return ot(i); } function lt(e, i) { let c; e.addEventListener("mouseenter", (n) => { if (n.stopPropagation(), !c) { const u = e.dataset.tooltip && JSON.parse(e.dataset.tooltip) || {}, s = Object.assign({ reference: e, contentTemplate: i.value.contentTemplate }, u); c = z(s); } }), e.addEventListener("mouseleave", (n) => { n.stopPropagation(), c && (c.unmount(), c = null); }); } function V(e, i) { e.stopPropagation(), i && (i.unmount(), i = null); } function nt(e, i) { let c; e.addEventListener("click", (n) => { if (n.stopPropagation(), !c) { const u = e.dataset.tooltip && JSON.parse(e.dataset.tooltip) || {}, s = Object.assign({ trigger: "hover", reference: e }, u); c = z(s); } }), document.body.addEventListener("click", (n) => { const u = n.target; c && !u.closest(".tooltip") && (V(n, c), c = null); }, !0); } function M(e, i) { if (!i.value) e.dataset.tooltip = ""; else { const { contentTemplate: c, ...n } = i.value; e.dataset.tooltip = JSON.stringify(n); } } const it = { mounted: (e, i, c) => { switch (M(e, i), i.value.trigger) { case "click": { nt(e); break; } default: lt(e, i); } }, unMounted: (e, i, c) => { i.value.trigger === "click" && document.body.removeEventListener("click", () => V); }, beforeUpdate: (e, i) => { M(e, i); } }; A.install = (e) => { e.component(A.name, A), e.directive("tooltip", it); }; export { A as FTooltip, it as FTooltipDirective, A as default, K as tooltipProps };