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