UNPKG

@farris/ui-vue

Version:

Farris Vue, a Farris Design based Vue3 component library.

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