vue-data-ui
Version:
A user-empowering data visualization Vue 3 components library for eloquent data storytelling
206 lines (205 loc) • 5.66 kB
JavaScript
import { ref as c, onMounted as C, onUnmounted as k, watch as g, nextTick as T, computed as y, createBlock as w, openBlock as S, Teleport as N, createElementBlock as $, createCommentVNode as M, normalizeStyle as Y, normalizeClass as z, renderSlot as h, createElementVNode as A } from "vue";
import { s as E } from "./lib-BwysEpWI.js";
function R({ tooltip: a, chart: r, clientPosition: e, positionPreference: p = "center", defaultOffsetY: m = 24, blockShiftY: v = !1 }) {
const t = c(0), l = c(m);
if (a && r) {
const { width: n, height: i } = a.getBoundingClientRect(), { right: s, left: d, bottom: f } = r.getBoundingClientRect();
p === "center" && (e.x + n / 2 > s ? t.value = -n + (s - e.x) : e.x - n / 2 < d ? t.value = -n + (n - (e.x - d)) : t.value = -n / 2), p === "right" && (e.x + n > s ? t.value = -n + (s - e.x) : t.value = 0), p === "left" && (e.x < d + n ? t.value = -n + (n - (e.x - d)) : t.value = -n), e.y + i > f && !v && (l.value = -i - m);
}
return {
top: e.y + l.value,
left: e.x + t.value
};
}
function L(a, r, e) {
C(() => a.addEventListener(r, e)), k(() => a.removeEventListener(r, e));
}
function O() {
const a = c(0), r = c(0);
return L(window, "mousemove", (e) => {
a.value = e.clientX, r.value = e.clientY;
}), { x: a, y: r };
}
const W = ["aria-hidden"], j = ["innerHTML"], I = {
__name: "Tooltip",
props: {
backgroundColor: {
type: String,
default: "#FFFFFF"
},
color: {
type: String,
default: "#000000"
},
content: String,
maxWidth: {
type: String,
default: "300px"
},
parent: {
type: Object
},
show: {
type: Boolean,
default: !1
},
isCustom: {
type: Boolean,
default: !1
},
fontSize: {
type: [Number, String],
default: 14
},
borderRadius: {
type: Number,
default: 4
},
borderColor: {
type: String,
default: "#e1e5e8"
},
borderWidth: {
type: Number,
default: 1
},
backgroundOpacity: {
type: Number,
default: 100
},
position: {
type: String,
default: "center"
},
offsetY: {
type: Number,
default: 24
},
blockShiftY: {
type: Boolean,
default: !1
},
isFullscreen: {
type: Boolean,
default: !1
},
smooth: {
type: Boolean,
default: !0
},
backdropFilter: {
type: Boolean,
default: !0
},
smoothForce: {
type: Number,
default: 0.18
},
smoothSnapThreshold: {
type: Number,
default: 0.25
}
},
setup(a, { expose: r }) {
const e = a, p = c(null), { x: m, y: v } = O(e.parent), t = c({ x: 0, y: 0 }), l = c({ x: 0, y: 0 });
function n({ x: o, y: u }) {
m.value = o, v.value = u;
}
let i = null;
function s() {
if (!e.show) {
f();
return;
}
if (!e.smooth) {
l.value.x = t.value.x, l.value.y = t.value.y, f();
return;
}
const o = t.value.x - l.value.x, u = t.value.y - l.value.y;
if (Math.abs(o) <= e.smoothSnapThreshold && Math.abs(u) <= e.smoothSnapThreshold) {
l.value.x = t.value.x, l.value.y = t.value.y, f();
return;
}
l.value.x += o * e.smoothForce, l.value.y += u * e.smoothForce, i = requestAnimationFrame(s);
}
function d() {
i == null && e.show && e.smooth && (i = requestAnimationFrame(s));
}
function f() {
i != null && (cancelAnimationFrame(i), i = null);
}
g([m, v], ([o, u]) => {
t.value.x = o, t.value.y = u, e.smooth ? d() : (l.value.x = o, l.value.y = u);
}), g(
() => e.show,
async (o) => {
if (o) {
const u = m.value, b = v.value;
t.value.x = u, t.value.y = b, l.value.x = u, l.value.y = b, await T(), d();
} else
f();
}
), k(() => {
f();
});
const x = y(() => {
const o = R({
tooltip: p.value,
chart: e.parent,
clientPosition: l.value,
positionPreference: e.position,
defaultOffsetY: e.offsetY,
blockShiftY: e.blockShiftY
});
return {
top: Math.round(o.top),
left: Math.round(o.left)
};
}), F = y(() => E(e.backgroundColor, e.backgroundOpacity)), B = y(() => {
const o = {
pointerEvents: "none",
position: "fixed",
top: "0px",
left: "0px",
transform: `translate3d(${x.value.left}px, ${x.value.top}px, 0)`,
borderRadius: `${e.borderRadius}px`,
border: `${e.borderWidth}px solid ${e.borderColor}`,
zIndex: 2147483647
};
return e.isCustom || Object.assign(o, {
background: F.value,
color: e.color,
maxWidth: e.maxWidth,
fontSize: `${e.fontSize}px`
}), o;
});
return r({
placeTooltip: n
}), (o, u) => (S(), w(N, {
to: a.isFullscreen ? a.parent : "body"
}, [
a.show ? (S(), $("div", {
key: 0,
ref_key: "tooltip",
ref: p,
role: "tooltip",
"aria-hidden": !a.show,
"aria-live": "polite",
class: z({
"vue-data-ui-custom-tooltip": a.isCustom,
"vue-data-ui-tooltip": !a.isCustom,
"vue-data-ui-tooltip-backdrop": a.backdropFilter
}),
style: Y(B.value)
}, [
h(o.$slots, "tooltip-before"),
h(o.$slots, "default"),
A("div", { innerHTML: a.content }, null, 8, j),
h(o.$slots, "tooltip-after")
], 14, W)) : M("", !0)
], 8, ["to"]));
}
};
export {
I as default
};