@farris/ui-vue
Version:
Farris Vue, a Farris Design based Vue3 component library.
328 lines (327 loc) • 11.2 kB
JavaScript
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
};