UNPKG

@farris/ui-vue

Version:

Farris Vue, a Farris Design based Vue3 component library.

377 lines (376 loc) 13 kB
import { ref as g, computed as T, defineComponent as tt, watch as et, onMounted as ot, createVNode as y, Fragment as lt, Teleport as nt, nextTick as W, reactive as it, createApp as rt, onUnmounted as st, mergeProps as ct } from "vue"; const at = { /** 提示内容 */ 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 }, // 是否启用 enable: { type: Boolean, default: !0 }, // 是否根据溢出自动显示提示 overflowShown: { type: Boolean, default: !1 } }; function ut(t, o) { const n = /* @__PURE__ */ new Map([ ["top", "bottom"], ["bottom", "top"], ["left", "right"], ["right", "left"] ]), s = /* @__PURE__ */ new Map([ ["top", "height"], ["bottom", "height"], ["left", "width"], ["right", "width"] ]); function p(e, r) { const u = n.get(r) || r; return e.replace(r, u); } function c(e, r, u, l, d) { let h = e; const a = e.split("-")[0], f = s.get(a), m = l[f] + d[f]; return Math.abs(u[a] - r[a]) < m && (h = p(e, a)), h; } return { adjustPlacement: c }; } function ft(t, o) { function s(c, e, r) { let u = !1, l = r; return (e === "left" || e === "top") && r <= c[e] && (u = !0, l = c[e] + 6), (e === "right" || e === "bottom") && r >= c[e] && (u = !0, l = c[e] - 6), { overBound: u, fixedValue: l }; } function p(c, e, r, u, l, d, h) { let a = e.tooltip.left, f = e.tooltip.top, m = e.arrow.left, w = e.arrow.top; const L = c.split("-")[0]; if (["top", "bottom"].includes(L)) { const k = s(r, "left", e.tooltip.left), j = s(r, "right", e.tooltip.left + l.width); a = k.overBound ? k.fixedValue : j.overBound ? j.fixedValue - l.width : e.tooltip.left, m = k.overBound ? l.width - (a + l.width - u.right) - h.width : j.overBound ? u.left - a : e.arrow.left; } const E = s(r, "top", e.tooltip.top), x = s(r, "bottom", e.tooltip.top + l.height); return f = E.overBound ? E.fixedValue : x.overBound ? x.fixedValue - l.height : e.tooltip.top, w = E.overBound ? e.arrow.top : x.overBound ? l.height - (f + l.height - u.top) : e.arrow.top, { arrow: { left: m, top: w }, tooltip: { left: a, top: f } }; } return { adjustPosition: p }; } function pt(t, o) { function s(e, r, u, l, d) { const h = e.split("-"), a = h[0], f = h[1] || "middle", m = ["top", "bottom"].includes(a) ? f === "middle" ? (l.width - d.width) / 2 : f === "right" ? l.width - d.width - 6 : 6 : 0, w = ["left", "right"].includes(a) ? f === "middle" ? (l.height - d.height) / 2 : f === "bottom" ? l.height - d.height - 6 : 6 : 0, S = a === "left" ? l.width + d.width : 0, L = a === "top" ? l.height + d.height : 0; return { left: S + m, top: L + w, right: 0 }; } function p(e, r, u, l, d) { const h = e.split("-"), a = h[0], f = h[1] || "middle", m = (u.width - l.width) / 2, w = (u.height - l.height) / 2, S = a === "right" ? r.right : r.left, L = a === "bottom" ? r.bottom : r.top, E = a === "top" ? 0 - w - l.height - d.height : a === "bottom" ? 0 - w + d.height : 0, x = ["left", "right"].includes(a) ? f === "middle" ? (r.height - l.height) / 2 : f === "bottom" ? r.height - l.height : 0 : 0, C = a === "left" ? 0 - m - l.width - d.width : a === "right" ? 0 - m + d.width : 0, O = ["top", "bottom"].includes(a) ? f === "middle" ? (r.width - l.width) / 2 : f === "right" ? r.width - l.width : 0 : 0, k = L + E + x; return { left: S + C + O, top: k }; } function c(e, r, u, l, d) { const h = p(e, r, u, l, d); return { arrow: s(e, r, u, l, d), tooltip: h }; } return { calculate: c }; } function dt(t, o) { const n = g(t.horizontalRelative), s = g(t.verticalRelative); function p(e) { return typeof e == "string" ? document.querySelector(e) : e; } function c() { let e = document.documentElement.clientWidth, r = document.documentElement.clientHeight, u = 0, l = 0, d = 0, h = 0, a = r - u, f = e - l; return n.value && ({ left: l, right: e, x: d, width: f } = p(n.value).getBoundingClientRect()), s.value && ({ bottom: r, top: u, y: h, height: a } = p(s.value).getBoundingClientRect()), { top: u, left: l, right: e, bottom: r, height: a, width: f, x: d, y: h }; } return { getRelativeElementBound: c }; } function vt(t, o, n, s, p, c) { const e = g(t.placement), { getRelativeElementBound: r } = dt(t), { calculate: u } = pt(), { adjustPlacement: l } = ut(), { adjustPosition: d } = ft(), h = T(() => e.value.split("-")[0]), a = T(() => { const f = r(); e.value = l(e.value, f, n, s, c); const m = u(e.value, n, s, p, c); return d( e.value, m, f, n, s, p, c ); }); return { tooltipPlacement: h, tooltipPosition: a }; } function ht(t) { const o = g(), n = g(!1), s = T(() => ({ display: n.value ? "block" : "none" })), p = T(() => { var e; const c = (e = t.customClass) == null ? void 0 : e.split(" "); return c == null ? void 0 : c.reduce((r, u) => (r[u] = !0, r), {}); }); return { showTooltip: n, tooltipDisplayStyle: s, tooltipCustomClass: p, tooltipContainerRef: o }; } const H = /* @__PURE__ */ tt({ name: "FTooltip", props: at, emits: ["click"], setup(t, o) { const n = g(), s = g(), p = g(), c = g(), e = g(), r = g(t.placement.split("-")[0]), u = ht(t), { showTooltip: l, tooltipDisplayStyle: d, tooltipCustomClass: h, tooltipContainerRef: a } = u, f = g(!1), m = T(() => { let i = { "fv-tooltip": !0, tooltip: !0, show: !0 }; const v = `bs-tooltip-${r.value}`; return i[v] = !0, o.slots.default && (i = { ...i, ...h.value }), i; }), w = (i) => { i.stopPropagation(), i.target !== e.value && (l.value = !1); }, S = T(() => t.content && !t.contentTemplate), L = T(() => t.content), E = g("0px"), x = g("0px"), C = T(() => { const i = { left: E.value, top: x.value }; return o.slots.default, i; }), O = g(""), k = g(""), j = T(() => ({ left: O.value, top: k.value })), R = T(() => ({ "tooltip-inner": !0, "tooltip-inner-lg": c.value && c.value && c.value.scrollHeight > c.value.clientHeight })), V = T(() => { const i = {}; return t.width && Object.assign(i, { width: t.width, "max-width": "none" }), i; }), N = (i) => { s.value && p.value && c.value && (R.value, W(() => { const { tooltipPlacement: v, tooltipPosition: b } = vt(t, o, i.getBoundingClientRect(), p.value.getBoundingClientRect(), c.value.getBoundingClientRect(), s.value.getBoundingClientRect()); E.value = `${b.value.tooltip.left + document.documentElement.scrollLeft}px`, x.value = `${b.value.tooltip.top + document.documentElement.scrollTop}px`, O.value = `${b.value.arrow.left}px`, k.value = `${b.value.arrow.top}px`, r.value = v.value; })); }, A = (i) => { var b; const v = (b = n.value) == null ? void 0 : b.nextElementSibling; v && (t.overflowShown && v.scrollWidth === v.clientWidth || (i.stopPropagation(), l.value = !0, W(() => { N(v); }))); }, F = (i, v = !0) => { i.removeEventListener("mouseenter", A), i.removeEventListener("mouseleave", w), v && (i.addEventListener("mouseenter", A), i.addEventListener("mouseleave", w)); }; function I(i, v = !0) { i.removeEventListener("mouseenter", A), i.removeEventListener("mouseleave", w), v && (i.addEventListener("click", A), document.body.addEventListener("click", w)); } function M() { var v; if (!t.enable) return; const i = (v = n.value) == null ? void 0 : v.nextElementSibling; i && (t.trigger === "click" && I(i), t.trigger === "hover" && F(i)); } function _() { var v; const i = (v = n.value) == null ? void 0 : v.nextElementSibling; i && (t.trigger === "click" && I(i, !1), t.trigger === "hover" && F(i, !1)); } et(() => t.enable, (i) => { i ? M() : _(); }); function B() { n.value && n.value.nodeName === "#text" && !n.value.nextElementSibling && (f.value = !0, W(() => { M(); })); } ot(() => { B(), M(), !S.value && t.contentTemplate && e.value && e.value.appendChild(t.contentTemplate), t.reference && N(t.reference); }); function $(i) { o.emit("click", i); } const K = () => y("div", { ref: p, class: m.value, style: C.value, onClick: $ }, [y("div", { ref: s, class: "arrow", style: j.value }, null), y("div", { ref: c, class: R.value, style: V.value }, [y("div", { class: "tooltip-tmpl" }, [S.value && y("div", { class: "tooltip-text", innerHTML: L.value }, null), !S.value && y("div", { class: "tooltip-text", ref: e }, null)])])]), Q = () => y("div", { ref: p, class: m.value, style: C.value, onClick: $ }, [y("div", { ref: s, class: "arrow", style: j.value }, null), y("div", { ref: c, class: R.value, style: V.value }, [y("div", { class: "tooltip-tmpl" }, [y("div", { class: "tooltip-text", ref: e }, [o.slots.contentTemplate ? o.slots.contentTemplate() : t.content])])])]); function Z() { var i, v, b, q; return f.value ? y("span", null, [(v = (i = o.slots).default) == null ? void 0 : v.call(i)]) : (q = (b = o.slots).default) == null ? void 0 : q.call(b); } return () => o.slots.default ? y(lt, { ref: n }, [Z(), y(nt, { to: "body" }, { default: () => [l.value && Q()] })]) : K(); } }); function mt(t, o) { const n = document.createElement("div"); t.customClass && (n.className = t.customClass); const s = rt({ setup() { function p() { t.clickToHide && s.unmount(); } return st(() => { document.body.removeChild(n); }), () => y(H, ct(t, { onClick: p }), null); } }); return document.body.appendChild(n), s.mount(n), s; } function U(t) { const o = it({ ...t }); return mt(o); } const P = /* @__PURE__ */ new WeakMap(); function X(t) { if (!t) return; const o = P.get(t); o && (o.unmount(), P.delete(t)); } function gt(t, o) { let n; t.addEventListener("mouseenter", (s) => { if (o.value.enable !== !1 && !(o.value.overflowShown && t.scrollWidth === t.clientWidth) && (s.stopPropagation(), !n)) { const p = t.dataset.tooltip && JSON.parse(t.dataset.tooltip) || {}, c = Object.assign({ reference: t, contentTemplate: o.value.contentTemplate }, p); n = U(c), P.set(t, n); } }), t.addEventListener("mouseleave", (s) => { s.stopPropagation(), n && (P.delete(t), n.unmount(), n = null); }); } let Y = null; const z = "_farris-tooltip-directive_"; function D() { document.querySelectorAll(`.${z}`).forEach((t) => { X(t); }); } function yt(t, o) { t.addEventListener("click", (n) => { if (o.value.enable === !1 || o.value.overflowShown === !0 && t.scrollWidth === t.clientWidth) return; n.stopPropagation(); let s = P.get(t); if (s) s.unmount(), P.delete(t); else { D(); const p = t.dataset.tooltip && JSON.parse(t.dataset.tooltip) || {}, c = Object.assign({ trigger: "hover", reference: t }, p); s = U(c), P.set(t, s); } }); } function G(t, o) { if (!o.value) t.dataset.tooltip = ""; else { const { contentTemplate: n, ...s } = o.value; t.dataset.tooltip = JSON.stringify(s); } } function J(t, o) { o.value.trigger === "click" || X(t); } const wt = { mounted: (t, o, n) => { switch (t.classList.add(z), G(t, o), o.value.trigger) { case "click": { yt(t, o); break; } default: gt(t, o); } }, beforeUnmount: (t, o, n) => { J(t, o); }, unmounted: (t, o, n) => { J(t, o); }, beforeUpdate: (t, o) => { G(t, o); } }; window.clearAllTooltips = D; document.body.removeEventListener("click", Y, !0); document.body.addEventListener("click", Y = (t) => { const o = t.target, n = o.closest(`.${z}`); n && P.has(n) || o.closest(".tooltip") || D(); }, !0); H.install = (t) => { t.component(H.name, H), t.directive("tooltip", wt); }; export { H as FTooltip, wt as FTooltipDirective, H as default, at as tooltipProps };