UNPKG

@farris/ui-vue

Version:

Farris Vue, a Farris Design based Vue3 component library.

412 lines (411 loc) 14.1 kB
import { ref as y, onMounted as U, computed as b, defineComponent as ot, watch as nt, createVNode as g, Fragment as lt, Teleport as it, nextTick as R, mergeProps as X, reactive as rt, createApp as ct, onUnmounted as st } from "vue"; const at = { /** * 提示内容,可以是字符串,可以是带 HTML 标签的字符串 */ content: { type: Object, default: "" }, /** * 模板提示内 */ contentTemplate: { type: Object }, /** * 给提示框设置固定的宽度,比如'200px'。<br>设置的值可以解除最大宽度的限制,只按照设置的值显示提示。 */ width: { type: String }, /** * 提示框自定义样式,应用与提示框最外层 */ customClass: { type: String }, /** * 控制提示的朝向。目前支持的类型:<br>'top-left'朝上-偏左 \ * @default top */ placement: { type: String, default: "top" }, /** * 提示框的触发方式,'hover'鼠标滑过 \ */ 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() { const t = y(!1); return U(() => { t.value = !0; }), t; } function ft(t, o) { const i = /* @__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 = i.get(r) || r; return e.replace(r, u); } function s(e, r, u, l, v) { let h = e; const a = e.split("-")[0], f = c.get(a), m = l[f] + v[f]; return Math.abs(u[a] - r[a]) < m && (h = d(e, a)), h; } return { adjustPlacement: s }; } function dt(t, o) { function c(s, e, r) { let u = !1, l = r; return (e === "left" || e === "top") && r <= s[e] && (u = !0, l = s[e] + 6), (e === "right" || e === "bottom") && r >= s[e] && (u = !0, l = s[e] - 6), { overBound: u, fixedValue: l }; } function d(s, e, r, u, l, v, h) { let a = e.tooltip.left, f = e.tooltip.top, m = e.arrow.left, w = e.arrow.top; const E = s.split("-")[0]; if (["top", "bottom"].includes(E)) { const k = c(r, "left", e.tooltip.left), L = c(r, "right", e.tooltip.left + l.width); a = k.overBound ? k.fixedValue : L.overBound ? L.fixedValue - l.width : e.tooltip.left, m = k.overBound ? l.width - (a + l.width - u.right) - h.width : L.overBound ? u.left - a : e.arrow.left; } const S = c(r, "top", e.tooltip.top), x = c(r, "bottom", e.tooltip.top + l.height); return f = S.overBound ? S.fixedValue : x.overBound ? x.fixedValue - l.height : e.tooltip.top, w = S.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: d }; } function vt(t, o) { function c(e, r, u, l, v) { const h = e.split("-"), a = h[0], f = h[1] || "middle", m = ["top", "bottom"].includes(a) ? f === "middle" ? (l.width - v.width) / 2 : f === "right" ? l.width - v.width - 6 : 6 : 0, w = ["left", "right"].includes(a) ? f === "middle" ? (l.height - v.height) / 2 : f === "bottom" ? l.height - v.height - 6 : 6 : 0, j = a === "left" ? l.width + v.width : 0, E = a === "top" ? l.height + v.height : 0; return { left: j + m, top: E + w, right: 0 }; } function d(e, r, u, l, v) { const h = e.split("-"), a = h[0], f = h[1] || "middle", m = (u.width - l.width) / 2, w = (u.height - l.height) / 2, j = a === "right" ? r.right : r.left, E = a === "bottom" ? r.bottom : r.top, S = a === "top" ? 0 - w - l.height - v.height : a === "bottom" ? 0 - w + v.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 - v.width : a === "right" ? 0 - m + v.width : 0, O = ["top", "bottom"].includes(a) ? f === "middle" ? (r.width - l.width) / 2 : f === "right" ? r.width - l.width : 0 : 0, k = E + S + x; return { left: j + C + O, top: k }; } function s(e, r, u, l, v) { const h = d(e, r, u, l, v); return { arrow: c(e, r, u, l, v), tooltip: h }; } return { calculate: s }; } function pt(t, o) { const i = y(t.horizontalRelative), c = y(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, l = 0, v = 0, h = 0, a = r - u, f = e - l; return i.value && ({ left: l, right: e, x: v, width: f } = d(i.value).getBoundingClientRect()), c.value && ({ bottom: r, top: u, y: h, height: a } = d(c.value).getBoundingClientRect()), { top: u, left: l, right: e, bottom: r, height: a, width: f, x: v, y: h }; } return { getRelativeElementBound: s }; } function ht(t, o, i, c, d, s) { const e = y(t.placement), { getRelativeElementBound: r } = pt(t), { calculate: u } = vt(), { adjustPlacement: l } = ft(), { adjustPosition: v } = dt(), h = b(() => e.value.split("-")[0]), a = b(() => { const f = r(); e.value = l(e.value, f, i, c, s); const m = u(e.value, i, c, d, s); return v( e.value, m, f, i, c, d, s ); }); return { tooltipPlacement: h, tooltipPosition: a }; } function mt(t) { const o = y(), i = y(!1), c = b(() => ({ display: i.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: i, tooltipDisplayStyle: c, tooltipCustomClass: d, tooltipContainerRef: o }; } const H = /* @__PURE__ */ ot({ name: "FTooltip", props: at, emits: ["click"], setup(t, o) { const i = y(), c = y(), d = y(), s = y(), e = y(), r = y(t.placement.split("-")[0]), u = mt(t), { showTooltip: l, tooltipCustomClass: v } = u, h = y(!1), a = ut(), f = b(() => { let n = { "fv-tooltip": !0, tooltip: !0, show: !0 }; const p = `bs-tooltip-${r.value}`; return n[p] = !0, o.slots.default && (n = { ...n, ...v.value }), n; }), m = (n) => { n.target !== e.value && (n.stopPropagation(), document.body.removeEventListener("click", m), l.value = !1); }, w = b(() => t.content && !t.contentTemplate), j = b(() => t.content), E = y("0px"), S = y("0px"), x = b(() => { const n = { left: E.value, top: S.value }; return o.slots.default, n; }), C = y(""), O = y(""), k = b(() => ({ left: C.value, top: O.value })), L = b(() => ({ "tooltip-inner": !0, "tooltip-inner-lg": s.value && s.value && s.value.scrollHeight > s.value.clientHeight })), V = b(() => { const n = {}; return t.width && Object.assign(n, { width: t.width, "max-width": "none" }), n; }), D = (n) => { c.value && d.value && s.value && (L.value, R(() => { const { tooltipPlacement: p, tooltipPosition: T } = ht(t, o, n.getBoundingClientRect(), d.value.getBoundingClientRect(), s.value.getBoundingClientRect(), c.value.getBoundingClientRect()); E.value = `${T.value.tooltip.left + document.documentElement.scrollLeft}px`, S.value = `${T.value.tooltip.top + document.documentElement.scrollTop}px`, C.value = `${T.value.arrow.left}px`, O.value = `${T.value.arrow.top}px`, r.value = p.value; })); }, A = (n) => { var T; const p = (T = i.value) == null ? void 0 : T.nextElementSibling; p && (t.overflowShown && p.scrollWidth === p.clientWidth || (n.stopPropagation(), l.value = !0, R(() => { D(p); }), t.trigger === "click" && document.body.addEventListener("click", m))); }, N = (n, p = !0) => { n.removeEventListener("mouseenter", A), n.removeEventListener("mouseleave", m), p && (n.addEventListener("mouseenter", A), n.addEventListener("mouseleave", m)); }; function F(n, p = !0) { n.removeEventListener("mouseenter", A), n.removeEventListener("mouseleave", m), p && n.addEventListener("click", A); } function M() { var p; if (!t.enable) return; const n = (p = i.value) == null ? void 0 : p.nextElementSibling; n && (t.trigger === "click" && F(n), t.trigger === "hover" && N(n)); } function B() { var p; const n = (p = i.value) == null ? void 0 : p.nextElementSibling; n && (t.trigger === "click" && F(n, !1), t.trigger === "hover" && N(n, !1)); } nt(() => t.enable, (n) => { n ? M() : B(); }); function K() { i.value && i.value.nodeName === "#text" && !i.value.nextElementSibling && (h.value = !0, R(() => { M(); })); } U(() => { K(), M(), !w.value && t.contentTemplate && e.value && e.value.appendChild(t.contentTemplate), t.reference && D(t.reference); }); function I(n) { o.emit("click", n); } const Q = () => g("div", { ref: d, class: f.value, style: x.value, onClick: I }, [g("div", { ref: c, class: "arrow", style: k.value }, null), g("div", { ref: s, class: L.value, style: V.value }, [g("div", { class: "tooltip-tmpl" }, [w.value && g("div", { class: "tooltip-text", innerHTML: j.value }, null), !w.value && g("div", { class: "tooltip-text", ref: e }, null)])])]); function Z() { const n = { class: "tooltip-text", ref: e }; if (o.slots.contentTemplate) return g("div", n, [o.slots.contentTemplate()]); if (t.content) { let p = t.content; return typeof t.content == "function" && (p = t.content()), g("div", X(n, { innerHTML: p }), null); } return g("div", n, null); } const tt = () => g("div", { ref: d, class: f.value, style: x.value, onClick: I }, [g("div", { ref: c, class: "arrow", style: k.value }, null), g("div", { ref: s, class: L.value, style: V.value }, [g("div", { class: "tooltip-tmpl" }, [Z()])])]); function et() { var n, p, T, $; return h.value ? g("span", null, [(p = (n = o.slots).default) == null ? void 0 : p.call(n)]) : ($ = (T = o.slots).default) == null ? void 0 : $.call(T); } return () => o.slots.default ? g(lt, { ref: i }, [et(), a.value && g(it, { to: "body" }, { default: () => [l.value && tt()] })]) : Q(); } }); function gt(t, o) { const i = document.createElement("div"); t.customClass && (i.className = t.customClass); const c = ct({ setup() { function d() { t.clickToHide && c.unmount(); } return st(() => { document.body.removeChild(i); }), () => g(H, X(t, { onClick: d }), null); } }); return document.body.appendChild(i), c.mount(i), c; } function Y(t) { const o = rt({ ...t }); return gt(o); } const P = /* @__PURE__ */ new WeakMap(); function _(t) { if (!t) return; const o = P.get(t); o && (o.unmount(), P.delete(t)); } function yt(t, o) { let i; t.addEventListener("mouseenter", (c) => { if (o.value.enable !== !1 && !(o.value.overflowShown && t.scrollWidth === t.clientWidth) && (c.stopPropagation(), !i)) { const d = t.dataset.tooltip && JSON.parse(t.dataset.tooltip) || {}, s = Object.assign({ reference: t, contentTemplate: o.value.contentTemplate }, d); i = Y(s), P.set(t, i); } }), t.addEventListener("mouseleave", (c) => { c.stopPropagation(), i && (P.delete(t), i.unmount(), i = null); }); } let q = null; const W = "_farris-tooltip-directive_"; function z() { document.querySelectorAll(`.${W}`).forEach((t) => { _(t); }); } function wt(t, o) { t.addEventListener("click", (i) => { if (o.value.enable === !1 || o.value.overflowShown === !0 && t.scrollWidth === t.clientWidth) return; i.stopPropagation(); let c = P.get(t); if (c) c.unmount(), P.delete(t); else { z(); const d = t.dataset.tooltip && JSON.parse(t.dataset.tooltip) || {}, s = Object.assign({ trigger: "hover", reference: t }, d); c = Y(s), P.set(t, c); } }); } function G(t, o) { if (!o.value) t.dataset.tooltip = ""; else { const { contentTemplate: i, ...c } = o.value; t.dataset.tooltip = JSON.stringify(c); } } function J(t, o) { o.value.trigger === "click" || _(t); } const bt = { mounted: (t, o, i) => { switch (t.classList.add(W), G(t, o), o.value.trigger) { case "click": { wt(t, o); break; } default: yt(t, o); } }, beforeUnmount: (t, o, i) => { J(t, o); }, unmounted: (t, o, i) => { J(t, o); }, beforeUpdate: (t, o) => { G(t, o); } }; typeof window < "u" && (window.clearAllTooltips = z); typeof document < "u" && document.body && (document.body.removeEventListener("click", q, !0), document.body.addEventListener("click", q = (t) => { const o = t.target, i = o.closest(`.${W}`); i && P.has(i) || o.closest(".tooltip") || z(); }, !0)); H.install = (t) => { t.component(H.name, H), t.directive("tooltip", bt); }; export { H as FTooltip, bt as FTooltipDirective, H as default, at as tooltipProps };