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