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