zero-tooltip 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/index.d.ts +2 -1
- package/dist/zero-tooltip.js +177 -160
- package/dist/zero-tooltip.umd.cjs +1 -1
- package/package.json +5 -1
- package/src/tooltip.ts +370 -307
- package/src/types/tooltipLocalConfig.ts +2 -1
package/README.md
CHANGED
|
@@ -101,7 +101,8 @@ const tooltipConfig: ZeroTooltipLocalConfig = {
|
|
|
101
101
|
arrowSize: ... ,
|
|
102
102
|
arrowClasses: ... ,
|
|
103
103
|
arrowMinOffsetFromTooltipCorner: ... ,
|
|
104
|
-
zIndex: ...
|
|
104
|
+
zIndex: ... ,
|
|
105
|
+
show: ...
|
|
105
106
|
}
|
|
106
107
|
</script>
|
|
107
108
|
```
|
|
@@ -128,6 +129,7 @@ Same as [ZeroTooltipConfig](#ZeroTooltipConfig) with following additions:
|
|
|
128
129
|
| Property | <div style="width:260px">Default value</div> | Type | Details |
|
|
129
130
|
|---|---|---|---|
|
|
130
131
|
| content | *undefined* | string | ***REQUIRED***. Tooltip text. Text is rendered as HTML, thus it's possible to give simple HTML structure, e.g., `<h1>Tooltip text</h1>` |
|
|
132
|
+
| show | *true* | boolean | Define whether to show or not to show tooltip |
|
|
131
133
|
|
|
132
134
|
## License
|
|
133
135
|
The license is MIT, so any extension, forking is welcome. `zero-tooltip` is designed as fully customizable, zero dependency, simple tooltip for Vue.js.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Directive } from 'vue';
|
|
2
2
|
|
|
3
|
-
declare const ZeroTooltip: (
|
|
3
|
+
declare const ZeroTooltip: (globalConfig?: ZeroTooltipConfig) => Directive;
|
|
4
4
|
export default ZeroTooltip;
|
|
5
5
|
|
|
6
6
|
export declare type ZeroTooltipConfig = {
|
|
@@ -21,6 +21,7 @@ export declare type ZeroTooltipConfig = {
|
|
|
21
21
|
|
|
22
22
|
export declare type ZeroTooltipLocalConfig = {
|
|
23
23
|
content: string;
|
|
24
|
+
show?: boolean;
|
|
24
25
|
} & ZeroTooltipConfig;
|
|
25
26
|
|
|
26
27
|
export declare type ZeroTooltipPosition = 'left' | 'top' | 'right' | 'bottom';
|
package/dist/zero-tooltip.js
CHANGED
|
@@ -1,179 +1,196 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { watch as st } from "vue";
|
|
2
|
+
function it() {
|
|
3
|
+
let e = [];
|
|
4
|
+
const t = (s, i) => {
|
|
5
|
+
if (r(s), e.length > 0)
|
|
6
|
+
for (const h of e)
|
|
7
|
+
h.addEventListener("scroll", i);
|
|
7
8
|
window.addEventListener("scroll", () => {
|
|
8
|
-
|
|
9
|
+
i(), d(i);
|
|
9
10
|
});
|
|
10
|
-
},
|
|
11
|
-
let
|
|
12
|
-
for (;
|
|
13
|
-
if (
|
|
14
|
-
const
|
|
15
|
-
(
|
|
11
|
+
}, r = (s) => {
|
|
12
|
+
let i = s;
|
|
13
|
+
for (; i !== null && i.tagName !== "HTML"; ) {
|
|
14
|
+
if (i.scrollHeight !== i.clientHeight) {
|
|
15
|
+
const h = window.getComputedStyle(i);
|
|
16
|
+
(h.overflow === "auto" || h.overflow === "scroll") && e.push(i);
|
|
16
17
|
}
|
|
17
|
-
|
|
18
|
+
i = i.parentElement;
|
|
18
19
|
}
|
|
19
|
-
},
|
|
20
|
-
if (
|
|
21
|
-
for (const
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
}, d = (s) => {
|
|
21
|
+
if (e.length > 0) {
|
|
22
|
+
for (const i of e)
|
|
23
|
+
i.removeEventListener("scroll", s);
|
|
24
|
+
e = [];
|
|
24
25
|
}
|
|
25
|
-
window.removeEventListener("scroll",
|
|
26
|
+
window.removeEventListener("scroll", s);
|
|
26
27
|
};
|
|
27
|
-
return { handleHideOnScroll:
|
|
28
|
-
}
|
|
29
|
-
function
|
|
30
|
-
let
|
|
31
|
-
return { handleHideOnResize: (
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
if (
|
|
35
|
-
|
|
28
|
+
return { handleHideOnScroll: t };
|
|
29
|
+
}
|
|
30
|
+
function dt() {
|
|
31
|
+
let e = null, t = null;
|
|
32
|
+
return { handleHideOnResize: (s, i) => {
|
|
33
|
+
e = new ResizeObserver((h) => {
|
|
34
|
+
const w = h[0].target;
|
|
35
|
+
if (t === null)
|
|
36
|
+
t = s.getBoundingClientRect();
|
|
36
37
|
else {
|
|
37
|
-
const
|
|
38
|
-
(
|
|
38
|
+
const m = w.getBoundingClientRect();
|
|
39
|
+
(m.left !== t.left || m.top !== t.top || m.width !== t.width || m.height !== t.height) && i();
|
|
39
40
|
}
|
|
40
|
-
}),
|
|
41
|
+
}), e.observe(s);
|
|
41
42
|
}, resetResizeReferences: () => {
|
|
42
|
-
|
|
43
|
+
e !== null && e.disconnect(), e = null, t = null;
|
|
43
44
|
} };
|
|
44
45
|
}
|
|
45
|
-
const { handleHideOnScroll:
|
|
46
|
+
const { handleHideOnScroll: pt } = it(), { handleHideOnResize: ot, resetResizeReferences: ht } = dt(), B = "zero-tooltip__container", N = "zero-tooltip__text", et = "zero-tooltip__arrow", z = {
|
|
46
47
|
left: ["left", "right", "top", "bottom"],
|
|
47
48
|
top: ["top", "bottom", "right", "left"],
|
|
48
49
|
right: ["right", "left", "top", "bottom"],
|
|
49
50
|
bottom: ["bottom", "top", "right", "left"]
|
|
50
|
-
};
|
|
51
|
-
let c =
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
function N(e) {
|
|
80
|
-
const i = Math.min(e.left - m - s, n), o = e.top >= s, p = window.innerHeight - e.bottom >= s;
|
|
81
|
-
if (i < w || !o || !p)
|
|
82
|
-
return !1;
|
|
83
|
-
d.style.maxWidth = `${i}px`;
|
|
84
|
-
const r = d.getBoundingClientRect();
|
|
85
|
-
let h = e.top + e.height / 2 - r.height / 2;
|
|
86
|
-
h < s ? h = s : h + r.height > window.innerHeight - s && (h = window.innerHeight - s - r.height);
|
|
87
|
-
const u = e.left - m - r.width;
|
|
88
|
-
return e.bottom < h + f * 2 || e.top > h + r.height - f * 2 ? !1 : (d.style.top = `${h}px`, d.style.left = `${u}px`, !0);
|
|
89
|
-
}
|
|
90
|
-
function Z(e) {
|
|
91
|
-
const i = Math.min(window.innerWidth - (e.right + m) - s, n), o = e.top >= s, p = window.innerHeight - e.bottom >= s;
|
|
92
|
-
if (i < w || !o || !p)
|
|
93
|
-
return !1;
|
|
94
|
-
d.style.maxWidth = `${i}px`;
|
|
95
|
-
const r = d.getBoundingClientRect();
|
|
96
|
-
let h = e.top + e.height / 2 - r.height / 2;
|
|
97
|
-
h < s ? h = s : h + r.height > window.innerHeight - s && (h = window.innerHeight - s - r.height);
|
|
98
|
-
const u = e.right + m;
|
|
99
|
-
return e.bottom < h + f * 2 || e.top > h + r.height - f * 2 ? !1 : (d.style.top = `${h}px`, d.style.left = `${u}px`, !0);
|
|
100
|
-
}
|
|
101
|
-
function D(e) {
|
|
102
|
-
const i = Math.min(window.innerWidth - s * 2, n);
|
|
103
|
-
d.style.maxWidth = `${i}px`;
|
|
104
|
-
const o = d.getBoundingClientRect();
|
|
105
|
-
let p = e.top - m - o.height;
|
|
106
|
-
if (p < s)
|
|
107
|
-
return !1;
|
|
108
|
-
let r = e.left + e.width / 2 - o.width / 2;
|
|
109
|
-
return r < s ? r = s : r + o.width > window.innerWidth - s && (r = window.innerWidth - s - o.width), e.left > r + o.width - f * 2 || e.right < r + f * 2 ? !1 : (d.style.top = `${p}px`, d.style.left = `${r}px`, !0);
|
|
110
|
-
}
|
|
111
|
-
function G(e) {
|
|
112
|
-
const i = Math.min(window.innerWidth - s * 2, n);
|
|
113
|
-
d.style.maxWidth = `${i}px`;
|
|
114
|
-
const o = d.getBoundingClientRect();
|
|
115
|
-
let p = e.bottom + m;
|
|
116
|
-
if (p + o.height > window.innerHeight - s)
|
|
117
|
-
return !1;
|
|
118
|
-
let r = e.left + e.width / 2 - o.width / 2;
|
|
119
|
-
return r < s ? r = s : r + o.width > window.innerWidth - s && (r = window.innerWidth - s - o.width), e.left > r + o.width - f * 2 || e.right < r + f * 2 ? !1 : (d.style.top = `${p}px`, d.style.left = `${r}px`, !0);
|
|
120
|
-
}
|
|
121
|
-
function J(e, i) {
|
|
122
|
-
var I;
|
|
123
|
-
const o = document.createElement("div"), p = d.getBoundingClientRect(), r = Math.sin(45 * (180 / Math.PI)) * x, h = 1;
|
|
124
|
-
let u = 0, z = 0, T = "";
|
|
125
|
-
switch (i) {
|
|
126
|
-
case "left":
|
|
127
|
-
T = "!zt-border-y-transparent !zt-border-r-transparent", u = e.top - p.top + e.height / 2 - r - l, z = p.width - l - h;
|
|
128
|
-
break;
|
|
129
|
-
case "top":
|
|
130
|
-
T = "!zt-border-x-transparent !zt-border-b-transparent", u = p.height - l - h, z = e.left - p.left + e.width / 2 - r - l;
|
|
131
|
-
break;
|
|
132
|
-
case "right":
|
|
133
|
-
T = "!zt-border-y-transparent !zt-border-l-transparent", u = e.top - p.top + e.height / 2 - r - l, z = -x * 2 - l + h;
|
|
134
|
-
break;
|
|
135
|
-
case "bottom":
|
|
136
|
-
T = "!zt-border-x-transparent !zt-border-t-transparent", u = -x * 2 - l + h, z = e.left - p.left + e.width / 2 - r - l;
|
|
137
|
-
break;
|
|
138
|
-
}
|
|
139
|
-
i === "left" || i === "right" ? _(i, p, u) || (u = k(i, p, u)) : _(i, p, z) || (z = k(i, p, z));
|
|
140
|
-
const K = q + " " + it + " " + T + " " + (t == null ? void 0 : t.arrowClasses);
|
|
141
|
-
o.classList.add(...K.split(" ")), o.style.top = `${u}px`, o.style.left = `${z}px`, o.style.borderWidth = `${x}px`, (I = document.querySelector(`.${H}`)) == null || I.appendChild(o);
|
|
142
|
-
}
|
|
143
|
-
function _(e, i, o) {
|
|
144
|
-
switch (e) {
|
|
145
|
-
case "left":
|
|
146
|
-
case "right":
|
|
147
|
-
return o > f - l && o < i.height + l - f - x * 2;
|
|
148
|
-
case "top":
|
|
149
|
-
case "bottom":
|
|
150
|
-
return o > f - l && o < i.width + l - f - x * 2;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
function k(e, i, o) {
|
|
154
|
-
switch (e) {
|
|
155
|
-
case "left":
|
|
156
|
-
case "right":
|
|
157
|
-
return o < f - l ? f - l : i.height - l - f - x * 2;
|
|
158
|
-
case "top":
|
|
159
|
-
case "bottom":
|
|
160
|
-
return o < f - l ? f - l : i.width - l - f - x * 2;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
};
|
|
166
|
-
function S() {
|
|
167
|
-
var a;
|
|
168
|
-
const t = document.querySelector(`.${H}`);
|
|
169
|
-
t && t instanceof HTMLElement && (E(), (a = t.querySelector(`.${q}`)) == null || a.remove(), t.style.left = "0", t.style.top = "0", t.remove());
|
|
170
|
-
}
|
|
171
|
-
function nt(t) {
|
|
172
|
-
let a = "";
|
|
173
|
-
if (typeof t == "string" ? a = t : a = t.content, !a)
|
|
51
|
+
}, Z = "top", D = 10, G = 20, J = 100, K = 250, Q = 0, U = "zt-fixed zt-opacity-0 zt-inline-block zt-w-fit zt-py-1.5 zt-px-2.5 zt-rounded-md zt-bg-[#495057] zt-shadow-[0_2px_12px_0_rgba(0,0,0,0.1)] zt-box-border", X = "zt-text-sm zt-text-white zt-whitespace-pre-wrap zt-break-words", Y = 5, nt = "zt-absolute zt-border-solid zt-border-[#495057]", R = 6, a = 1, l = !0;
|
|
52
|
+
let rt, W, S, v, p, M, T, n, O, H, c, f, u, F, $, x, A, o, k = !1;
|
|
53
|
+
const Wt = (e) => ({
|
|
54
|
+
mounted: (t, r) => {
|
|
55
|
+
E(r.value, e, r.arg), _(t), typeof r.value != "string" && st(r.value, (d) => {
|
|
56
|
+
E(d, e, r.arg), _(t);
|
|
57
|
+
});
|
|
58
|
+
},
|
|
59
|
+
updated: (t, r) => {
|
|
60
|
+
typeof r.value == "string" && (E(r.value, e, r.arg), _(t));
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
function E(e, t, r) {
|
|
64
|
+
var d, s, i, h, w, m, L, y, I, q, P, j;
|
|
65
|
+
rt = ut(e), typeof e != "string" && (W = r ?? e.defaultPosition ?? (t == null ? void 0 : t.defaultPosition) ?? Z, S = {
|
|
66
|
+
left: ((d = e.positions) == null ? void 0 : d.left) ?? ((s = t == null ? void 0 : t.positions) == null ? void 0 : s.left) ?? z.left,
|
|
67
|
+
top: ((i = e.positions) == null ? void 0 : i.top) ?? ((h = t == null ? void 0 : t.positions) == null ? void 0 : h.top) ?? z.top,
|
|
68
|
+
right: ((w = e.positions) == null ? void 0 : w.right) ?? ((m = t == null ? void 0 : t.positions) == null ? void 0 : m.right) ?? z.right,
|
|
69
|
+
bottom: ((L = e.positions) == null ? void 0 : L.bottom) ?? ((y = t == null ? void 0 : t.positions) == null ? void 0 : y.bottom) ?? z.bottom
|
|
70
|
+
}, v = e.offsetFromSource ?? (t == null ? void 0 : t.offsetFromSource) ?? D, p = e.offsetFromViewport ?? (t == null ? void 0 : t.offsetFromViewport) ?? G, M = e.minWidth ?? (t == null ? void 0 : t.minWidth) ?? J, T = e.maxWidth ?? (t == null ? void 0 : t.maxWidth) ?? K, n = e.tooltipBorderWidth ?? (t == null ? void 0 : t.tooltipBorderWidth) ?? Q, O = B + " " + U + " " + (e.tooltipClasses ?? (t == null ? void 0 : t.tooltipClasses) ?? ""), H = N + " " + X + " " + (e.textClasses ?? (t == null ? void 0 : t.textClasses) ?? ""), c = e.arrowSize ?? (t == null ? void 0 : t.arrowSize) ?? Y, f = e.arrowClasses ?? (t == null ? void 0 : t.arrowClasses) ?? "", u = e.arrowMinOffsetFromTooltipCorner ?? (t == null ? void 0 : t.arrowMinOffsetFromTooltipCorner) ?? R, F = e.zIndex ?? (t == null ? void 0 : t.zIndex) ?? a, $ = e.show ?? l), W === void 0 && (W = r ?? (t == null ? void 0 : t.defaultPosition) ?? Z), S === void 0 && (S = {
|
|
71
|
+
left: ((I = t == null ? void 0 : t.positions) == null ? void 0 : I.left) ?? z.left,
|
|
72
|
+
top: ((q = t == null ? void 0 : t.positions) == null ? void 0 : q.top) ?? z.top,
|
|
73
|
+
right: ((P = t == null ? void 0 : t.positions) == null ? void 0 : P.right) ?? z.right,
|
|
74
|
+
bottom: ((j = t == null ? void 0 : t.positions) == null ? void 0 : j.bottom) ?? z.bottom
|
|
75
|
+
}), v === void 0 && (v = (t == null ? void 0 : t.offsetFromSource) ?? D), p === void 0 && (p = (t == null ? void 0 : t.offsetFromViewport) ?? G), M === void 0 && (M = (t == null ? void 0 : t.minWidth) ?? J), T === void 0 && (T = (t == null ? void 0 : t.maxWidth) ?? K), n === void 0 && (n = (t == null ? void 0 : t.tooltipBorderWidth) ?? Q), O === void 0 && (O = B + " " + U + " " + (t == null ? void 0 : t.tooltipClasses)), H === void 0 && (H = N + " " + X + " " + (t == null ? void 0 : t.textClasses)), c === void 0 && (c = (t == null ? void 0 : t.arrowSize) ?? Y), f === void 0 && (f = (t == null ? void 0 : t.arrowClasses) ?? ""), u === void 0 && (u = (t == null ? void 0 : t.arrowMinOffsetFromTooltipCorner) ?? R), F === void 0 && (F = (t == null ? void 0 : t.zIndex) ?? a), $ === void 0 && ($ = l);
|
|
76
|
+
}
|
|
77
|
+
function ut(e) {
|
|
78
|
+
const t = typeof e == "string" ? e : e.content;
|
|
79
|
+
if (!t)
|
|
174
80
|
throw new Error("Please enter valid tooltip value");
|
|
175
|
-
return
|
|
81
|
+
return t;
|
|
82
|
+
}
|
|
83
|
+
function _(e) {
|
|
84
|
+
x = e, x.removeEventListener("mouseenter", b), x.removeEventListener("mouseleave", C), wt(), mt(), x.addEventListener("mouseenter", b), x.addEventListener("mouseleave", C), k && (x.dispatchEvent(new Event("mouseleave")), x.dispatchEvent(new Event("mouseenter")));
|
|
85
|
+
}
|
|
86
|
+
function wt() {
|
|
87
|
+
A = document.createElement("p"), A.classList.add(...H.trim().split(" ")), A.innerHTML = rt;
|
|
88
|
+
}
|
|
89
|
+
function mt() {
|
|
90
|
+
o = document.createElement("div"), o.classList.add(...O.trim().split(" ")), o.style.borderWidth = `${n}px`, o.appendChild(A);
|
|
91
|
+
}
|
|
92
|
+
function b() {
|
|
93
|
+
if (k = !0, !$)
|
|
94
|
+
return;
|
|
95
|
+
const e = x.getBoundingClientRect(), t = document.querySelector("body");
|
|
96
|
+
t == null || t.appendChild(o);
|
|
97
|
+
let r = !1, d = W;
|
|
98
|
+
for (let s = 0; s < 4 && (d = S[W][s], d === "left" ? r = ct(e) : d === "top" ? r = vt(e) : d === "right" ? r = xt(e) : d === "bottom" && (r = zt(e)), !r); s++)
|
|
99
|
+
;
|
|
100
|
+
r && (Tt(e, d), o.style.opacity = "1", o.style.zIndex = F.toString(), pt(x, () => V()), ot(x, () => V()));
|
|
101
|
+
}
|
|
102
|
+
function C() {
|
|
103
|
+
V();
|
|
104
|
+
}
|
|
105
|
+
function ct(e) {
|
|
106
|
+
const t = Math.min(e.left - v - p, T), r = e.top >= p, d = window.innerHeight - e.bottom >= p;
|
|
107
|
+
if (t < M || !r || !d)
|
|
108
|
+
return !1;
|
|
109
|
+
o.style.maxWidth = `${t}px`;
|
|
110
|
+
const s = o.getBoundingClientRect();
|
|
111
|
+
let i = e.top + e.height / 2 - s.height / 2;
|
|
112
|
+
i < p ? i = p : i + s.height > window.innerHeight - p && (i = window.innerHeight - p - s.height);
|
|
113
|
+
const h = e.left - v - s.width;
|
|
114
|
+
return e.bottom < i + u * 2 || e.top > i + s.height - u * 2 ? !1 : (o.style.top = `${i}px`, o.style.left = `${h}px`, !0);
|
|
115
|
+
}
|
|
116
|
+
function xt(e) {
|
|
117
|
+
const t = Math.min(window.innerWidth - (e.right + v) - p, T), r = e.top >= p, d = window.innerHeight - e.bottom >= p;
|
|
118
|
+
if (t < M || !r || !d)
|
|
119
|
+
return !1;
|
|
120
|
+
o.style.maxWidth = `${t}px`;
|
|
121
|
+
const s = o.getBoundingClientRect();
|
|
122
|
+
let i = e.top + e.height / 2 - s.height / 2;
|
|
123
|
+
i < p ? i = p : i + s.height > window.innerHeight - p && (i = window.innerHeight - p - s.height);
|
|
124
|
+
const h = e.right + v;
|
|
125
|
+
return e.bottom < i + u * 2 || e.top > i + s.height - u * 2 ? !1 : (o.style.top = `${i}px`, o.style.left = `${h}px`, !0);
|
|
126
|
+
}
|
|
127
|
+
function vt(e) {
|
|
128
|
+
const t = Math.min(window.innerWidth - p * 2, T);
|
|
129
|
+
o.style.maxWidth = `${t}px`;
|
|
130
|
+
const r = o.getBoundingClientRect();
|
|
131
|
+
let d = e.top - v - r.height;
|
|
132
|
+
if (d < p)
|
|
133
|
+
return !1;
|
|
134
|
+
let s = e.left + e.width / 2 - r.width / 2;
|
|
135
|
+
return s < p ? s = p : s + r.width > window.innerWidth - p && (s = window.innerWidth - p - r.width), e.left > s + r.width - u * 2 || e.right < s + u * 2 ? !1 : (o.style.top = `${d}px`, o.style.left = `${s}px`, !0);
|
|
136
|
+
}
|
|
137
|
+
function zt(e) {
|
|
138
|
+
const t = Math.min(window.innerWidth - p * 2, T);
|
|
139
|
+
o.style.maxWidth = `${t}px`;
|
|
140
|
+
const r = o.getBoundingClientRect();
|
|
141
|
+
let d = e.bottom + v;
|
|
142
|
+
if (d + r.height > window.innerHeight - p)
|
|
143
|
+
return !1;
|
|
144
|
+
let s = e.left + e.width / 2 - r.width / 2;
|
|
145
|
+
return s < p ? s = p : s + r.width > window.innerWidth - p && (s = window.innerWidth - p - r.width), e.left > s + r.width - u * 2 || e.right < s + u * 2 ? !1 : (o.style.top = `${d}px`, o.style.left = `${s}px`, !0);
|
|
146
|
+
}
|
|
147
|
+
function Tt(e, t) {
|
|
148
|
+
var y;
|
|
149
|
+
const r = document.createElement("div"), d = o.getBoundingClientRect(), s = Math.sin(45 * (180 / Math.PI)) * c, i = 1;
|
|
150
|
+
let h = 0, w = 0, m = "";
|
|
151
|
+
switch (t) {
|
|
152
|
+
case "left":
|
|
153
|
+
m = "!zt-border-y-transparent !zt-border-r-transparent", h = e.top - d.top + e.height / 2 - s - n, w = d.width - n - i;
|
|
154
|
+
break;
|
|
155
|
+
case "top":
|
|
156
|
+
m = "!zt-border-x-transparent !zt-border-b-transparent", h = d.height - n - i, w = e.left - d.left + e.width / 2 - s - n;
|
|
157
|
+
break;
|
|
158
|
+
case "right":
|
|
159
|
+
m = "!zt-border-y-transparent !zt-border-l-transparent", h = e.top - d.top + e.height / 2 - s - n, w = -c * 2 - n + i;
|
|
160
|
+
break;
|
|
161
|
+
case "bottom":
|
|
162
|
+
m = "!zt-border-x-transparent !zt-border-t-transparent", h = -c * 2 - n + i, w = e.left - d.left + e.width / 2 - s - n;
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
t === "left" || t === "right" ? g(t, d, h) || (h = tt(t, d, h)) : g(t, d, w) || (w = tt(t, d, w));
|
|
166
|
+
const L = et + " " + nt + " " + m + " " + f;
|
|
167
|
+
r.classList.add(...L.trim().split(" ")), r.style.top = `${h}px`, r.style.left = `${w}px`, r.style.borderWidth = `${c}px`, (y = document.querySelector(`.${B}`)) == null || y.appendChild(r);
|
|
168
|
+
}
|
|
169
|
+
function g(e, t, r) {
|
|
170
|
+
switch (e) {
|
|
171
|
+
case "left":
|
|
172
|
+
case "right":
|
|
173
|
+
return r > u - n && r < t.height + n - u - c * 2;
|
|
174
|
+
case "top":
|
|
175
|
+
case "bottom":
|
|
176
|
+
return r > u - n && r < t.width + n - u - c * 2;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function tt(e, t, r) {
|
|
180
|
+
switch (e) {
|
|
181
|
+
case "left":
|
|
182
|
+
case "right":
|
|
183
|
+
return r < u - n ? u - n : t.height - n - u - c * 2;
|
|
184
|
+
case "top":
|
|
185
|
+
case "bottom":
|
|
186
|
+
return r < u - n ? u - n : t.width - n - u - c * 2;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function V() {
|
|
190
|
+
var t;
|
|
191
|
+
const e = document.querySelector(`.${B}`);
|
|
192
|
+
e && e instanceof HTMLElement && (ht(), (t = e.querySelector(`.${et}`)) == null || t.remove(), e.style.left = "0", e.style.top = "0", e.remove()), k = !1;
|
|
176
193
|
}
|
|
177
194
|
export {
|
|
178
|
-
|
|
195
|
+
Wt as default
|
|
179
196
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(y,
|
|
1
|
+
(function(y,W){typeof exports=="object"&&typeof module<"u"?module.exports=W(require("vue")):typeof define=="function"&&define.amd?define(["vue"],W):(y=typeof globalThis<"u"?globalThis:y||self,y.ZeroTooltip=W(y.Vue))})(this,function(y){"use strict";function W(){let e=[];const t=(s,i)=>{if(r(s),e.length>0)for(const n of e)n.addEventListener("scroll",i);window.addEventListener("scroll",()=>{i(),d(i)})},r=s=>{let i=s;for(;i!==null&&i.tagName!=="HTML";){if(i.scrollHeight!==i.clientHeight){const n=window.getComputedStyle(i);(n.overflow==="auto"||n.overflow==="scroll")&&e.push(i)}i=i.parentElement}},d=s=>{if(e.length>0){for(const i of e)i.removeEventListener("scroll",s);e=[]}window.removeEventListener("scroll",s)};return{handleHideOnScroll:t}}function dt(){let e=null,t=null;return{handleHideOnResize:(s,i)=>{e=new ResizeObserver(n=>{const w=n[0].target;if(t===null)t=s.getBoundingClientRect();else{const m=w.getBoundingClientRect();(m.left!==t.left||m.top!==t.top||m.width!==t.width||m.height!==t.height)&&i()}}),e.observe(s)},resetResizeReferences:()=>{e!==null&&e.disconnect(),e=null,t=null}}}const{handleHideOnScroll:pt}=W(),{handleHideOnResize:ot,resetResizeReferences:ht}=dt(),S="zero-tooltip__container",j="zero-tooltip__text",P="zero-tooltip__arrow",z={left:["left","right","top","bottom"],top:["top","bottom","right","left"],right:["right","left","top","bottom"],bottom:["bottom","top","right","left"]},Z="top",N=10,D=20,G=100,J=250,K=0,Q="zt-fixed zt-opacity-0 zt-inline-block zt-w-fit zt-py-1.5 zt-px-2.5 zt-rounded-md zt-bg-[#495057] zt-shadow-[0_2px_12px_0_rgba(0,0,0,0.1)] zt-box-border",U="zt-text-sm zt-text-white zt-whitespace-pre-wrap zt-break-words",X=5,nt="zt-absolute zt-border-solid zt-border-[#495057]",Y=6,R=1,a=!0;let l,f,O,v,p,M,T,h,H,F,c,$,u,A,B,x,E,o,_=!1;const ut=e=>({mounted:(t,r)=>{k(r.value,e,r.arg),I(t),typeof r.value!="string"&&y.watch(r.value,d=>{k(d,e,r.arg),I(t)})},updated:(t,r)=>{typeof r.value=="string"&&(k(r.value,e,r.arg),I(t))}});function k(e,t,r){var d,s,i,n,w,m,V,L,et,rt,st,it;l=wt(e),typeof e!="string"&&(f=r??e.defaultPosition??(t==null?void 0:t.defaultPosition)??Z,O={left:((d=e.positions)==null?void 0:d.left)??((s=t==null?void 0:t.positions)==null?void 0:s.left)??z.left,top:((i=e.positions)==null?void 0:i.top)??((n=t==null?void 0:t.positions)==null?void 0:n.top)??z.top,right:((w=e.positions)==null?void 0:w.right)??((m=t==null?void 0:t.positions)==null?void 0:m.right)??z.right,bottom:((V=e.positions)==null?void 0:V.bottom)??((L=t==null?void 0:t.positions)==null?void 0:L.bottom)??z.bottom},v=e.offsetFromSource??(t==null?void 0:t.offsetFromSource)??N,p=e.offsetFromViewport??(t==null?void 0:t.offsetFromViewport)??D,M=e.minWidth??(t==null?void 0:t.minWidth)??G,T=e.maxWidth??(t==null?void 0:t.maxWidth)??J,h=e.tooltipBorderWidth??(t==null?void 0:t.tooltipBorderWidth)??K,H=S+" "+Q+" "+(e.tooltipClasses??(t==null?void 0:t.tooltipClasses)??""),F=j+" "+U+" "+(e.textClasses??(t==null?void 0:t.textClasses)??""),c=e.arrowSize??(t==null?void 0:t.arrowSize)??X,$=e.arrowClasses??(t==null?void 0:t.arrowClasses)??"",u=e.arrowMinOffsetFromTooltipCorner??(t==null?void 0:t.arrowMinOffsetFromTooltipCorner)??Y,A=e.zIndex??(t==null?void 0:t.zIndex)??R,B=e.show??a),f===void 0&&(f=r??(t==null?void 0:t.defaultPosition)??Z),O===void 0&&(O={left:((et=t==null?void 0:t.positions)==null?void 0:et.left)??z.left,top:((rt=t==null?void 0:t.positions)==null?void 0:rt.top)??z.top,right:((st=t==null?void 0:t.positions)==null?void 0:st.right)??z.right,bottom:((it=t==null?void 0:t.positions)==null?void 0:it.bottom)??z.bottom}),v===void 0&&(v=(t==null?void 0:t.offsetFromSource)??N),p===void 0&&(p=(t==null?void 0:t.offsetFromViewport)??D),M===void 0&&(M=(t==null?void 0:t.minWidth)??G),T===void 0&&(T=(t==null?void 0:t.maxWidth)??J),h===void 0&&(h=(t==null?void 0:t.tooltipBorderWidth)??K),H===void 0&&(H=S+" "+Q+" "+(t==null?void 0:t.tooltipClasses)),F===void 0&&(F=j+" "+U+" "+(t==null?void 0:t.textClasses)),c===void 0&&(c=(t==null?void 0:t.arrowSize)??X),$===void 0&&($=(t==null?void 0:t.arrowClasses)??""),u===void 0&&(u=(t==null?void 0:t.arrowMinOffsetFromTooltipCorner)??Y),A===void 0&&(A=(t==null?void 0:t.zIndex)??R),B===void 0&&(B=a)}function wt(e){const t=typeof e=="string"?e:e.content;if(!t)throw new Error("Please enter valid tooltip value");return t}function I(e){x=e,x.removeEventListener("mouseenter",b),x.removeEventListener("mouseleave",C),mt(),ct(),x.addEventListener("mouseenter",b),x.addEventListener("mouseleave",C),_&&(x.dispatchEvent(new Event("mouseleave")),x.dispatchEvent(new Event("mouseenter")))}function mt(){E=document.createElement("p"),E.classList.add(...F.trim().split(" ")),E.innerHTML=l}function ct(){o=document.createElement("div"),o.classList.add(...H.trim().split(" ")),o.style.borderWidth=`${h}px`,o.appendChild(E)}function b(){if(_=!0,!B)return;const e=x.getBoundingClientRect(),t=document.querySelector("body");t==null||t.appendChild(o);let r=!1,d=f;for(let s=0;s<4&&(d=O[f][s],d==="left"?r=xt(e):d==="top"?r=zt(e):d==="right"?r=vt(e):d==="bottom"&&(r=Tt(e)),!r);s++);r&&(yt(e,d),o.style.opacity="1",o.style.zIndex=A.toString(),pt(x,()=>q()),ot(x,()=>q()))}function C(){q()}function xt(e){const t=Math.min(e.left-v-p,T),r=e.top>=p,d=window.innerHeight-e.bottom>=p;if(t<M||!r||!d)return!1;o.style.maxWidth=`${t}px`;const s=o.getBoundingClientRect();let i=e.top+e.height/2-s.height/2;i<p?i=p:i+s.height>window.innerHeight-p&&(i=window.innerHeight-p-s.height);const n=e.left-v-s.width;return e.bottom<i+u*2||e.top>i+s.height-u*2?!1:(o.style.top=`${i}px`,o.style.left=`${n}px`,!0)}function vt(e){const t=Math.min(window.innerWidth-(e.right+v)-p,T),r=e.top>=p,d=window.innerHeight-e.bottom>=p;if(t<M||!r||!d)return!1;o.style.maxWidth=`${t}px`;const s=o.getBoundingClientRect();let i=e.top+e.height/2-s.height/2;i<p?i=p:i+s.height>window.innerHeight-p&&(i=window.innerHeight-p-s.height);const n=e.right+v;return e.bottom<i+u*2||e.top>i+s.height-u*2?!1:(o.style.top=`${i}px`,o.style.left=`${n}px`,!0)}function zt(e){const t=Math.min(window.innerWidth-p*2,T);o.style.maxWidth=`${t}px`;const r=o.getBoundingClientRect();let d=e.top-v-r.height;if(d<p)return!1;let s=e.left+e.width/2-r.width/2;return s<p?s=p:s+r.width>window.innerWidth-p&&(s=window.innerWidth-p-r.width),e.left>s+r.width-u*2||e.right<s+u*2?!1:(o.style.top=`${d}px`,o.style.left=`${s}px`,!0)}function Tt(e){const t=Math.min(window.innerWidth-p*2,T);o.style.maxWidth=`${t}px`;const r=o.getBoundingClientRect();let d=e.bottom+v;if(d+r.height>window.innerHeight-p)return!1;let s=e.left+e.width/2-r.width/2;return s<p?s=p:s+r.width>window.innerWidth-p&&(s=window.innerWidth-p-r.width),e.left>s+r.width-u*2||e.right<s+u*2?!1:(o.style.top=`${d}px`,o.style.left=`${s}px`,!0)}function yt(e,t){var L;const r=document.createElement("div"),d=o.getBoundingClientRect(),s=Math.sin(45*(180/Math.PI))*c,i=1;let n=0,w=0,m="";switch(t){case"left":m="!zt-border-y-transparent !zt-border-r-transparent",n=e.top-d.top+e.height/2-s-h,w=d.width-h-i;break;case"top":m="!zt-border-x-transparent !zt-border-b-transparent",n=d.height-h-i,w=e.left-d.left+e.width/2-s-h;break;case"right":m="!zt-border-y-transparent !zt-border-l-transparent",n=e.top-d.top+e.height/2-s-h,w=-c*2-h+i;break;case"bottom":m="!zt-border-x-transparent !zt-border-t-transparent",n=-c*2-h+i,w=e.left-d.left+e.width/2-s-h;break}t==="left"||t==="right"?g(t,d,n)||(n=tt(t,d,n)):g(t,d,w)||(w=tt(t,d,w));const V=P+" "+nt+" "+m+" "+$;r.classList.add(...V.trim().split(" ")),r.style.top=`${n}px`,r.style.left=`${w}px`,r.style.borderWidth=`${c}px`,(L=document.querySelector(`.${S}`))==null||L.appendChild(r)}function g(e,t,r){switch(e){case"left":case"right":return r>u-h&&r<t.height+h-u-c*2;case"top":case"bottom":return r>u-h&&r<t.width+h-u-c*2}}function tt(e,t,r){switch(e){case"left":case"right":return r<u-h?u-h:t.height-h-u-c*2;case"top":case"bottom":return r<u-h?u-h:t.width-h-u-c*2}}function q(){var t;const e=document.querySelector(`.${S}`);e&&e instanceof HTMLElement&&(ht(),(t=e.querySelector(`.${P}`))==null||t.remove(),e.style.left="0",e.style.top="0",e.remove()),_=!1}return ut});
|
package/package.json
CHANGED
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
"import": "./dist/zero-tooltip.js",
|
|
10
10
|
"require": "./dist/zero-tooltip.umd.cjs",
|
|
11
11
|
"types": "./dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./dist/styles.css": {
|
|
14
|
+
"import": "./dist/styles.css",
|
|
15
|
+
"require": "./dist/styles.css"
|
|
12
16
|
}
|
|
13
17
|
},
|
|
14
18
|
"./package.json": "./package.json",
|
|
@@ -16,7 +20,7 @@
|
|
|
16
20
|
"dist",
|
|
17
21
|
"src"
|
|
18
22
|
],
|
|
19
|
-
"version": "1.0.
|
|
23
|
+
"version": "1.0.5",
|
|
20
24
|
"type": "module",
|
|
21
25
|
"scripts": {
|
|
22
26
|
"dev": "vite",
|
package/src/tooltip.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Directive } from "vue"
|
|
1
|
+
import { Directive, watch } from "vue"
|
|
2
2
|
import TooltipConfig from "./types/tooltipConfig"
|
|
3
3
|
import TooltipPosition from "./types/tooltipPosition"
|
|
4
4
|
import TooltipPositions from "./types/tooltipPositions"
|
|
@@ -22,7 +22,7 @@ const defaultTooltipPositions: TooltipPositions = {
|
|
|
22
22
|
bottom: ['bottom', 'top', 'right', 'left'],
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
const defaultTooltipPosition: TooltipPosition = 'top'
|
|
26
26
|
const defaultTooltipOffsetFromSource = 10
|
|
27
27
|
const defaultTooltipOffsetFromViewport = 20
|
|
28
28
|
const defaultTooltipMinWidth = 100
|
|
@@ -34,339 +34,416 @@ const defaultArrowSize = 5
|
|
|
34
34
|
const defaultArrowClasses = 'zt-absolute zt-border-solid zt-border-[#495057]'
|
|
35
35
|
const defaultMinArrowOffsetFromTooltipCorner = 6
|
|
36
36
|
const defaultZIndex = 1
|
|
37
|
+
const defaultShouldShow = true
|
|
38
|
+
|
|
39
|
+
// Tooltip config
|
|
40
|
+
let tooltipText: string
|
|
41
|
+
let tooltipPosition: TooltipPosition
|
|
42
|
+
let tooltipPositions: TooltipPositions
|
|
43
|
+
let tooltipOffsetFromSource: number
|
|
44
|
+
let tooltipOffsetFromViewport: number
|
|
45
|
+
let tooltipMinWidth: number
|
|
46
|
+
let tooltipMaxWidth: number
|
|
47
|
+
let tooltipBorderWidth: number
|
|
48
|
+
let tooltipClasses: string
|
|
49
|
+
let textClasses: string
|
|
50
|
+
let arrowSize: number
|
|
51
|
+
let arrowClasses: string
|
|
52
|
+
let arrowMinOffsetFromTooltipCorner: number
|
|
53
|
+
let zIndex: number
|
|
54
|
+
let shouldShow: boolean
|
|
55
|
+
|
|
56
|
+
// Tooltip elements
|
|
57
|
+
let anchorElement: HTMLElement
|
|
58
|
+
let tooltipTextElement: HTMLElement
|
|
59
|
+
let tooltipElement: HTMLElement
|
|
60
|
+
|
|
61
|
+
let isHovered = false
|
|
62
|
+
|
|
63
|
+
const ZeroTooltip = (globalConfig?: TooltipConfig): Directive => {
|
|
64
|
+
return {
|
|
65
|
+
mounted: (targetElement: HTMLElement, binding) => {
|
|
66
|
+
setTooltipConfig(binding.value, globalConfig, binding.arg as TooltipPosition)
|
|
67
|
+
initTooltip(targetElement)
|
|
68
|
+
|
|
69
|
+
if (typeof(binding.value) !== 'string') {
|
|
70
|
+
watch(binding.value, (newBindingValue) => {
|
|
71
|
+
setTooltipConfig(newBindingValue as string | TooltipLocalConfig, globalConfig, binding.arg as TooltipPosition)
|
|
72
|
+
initTooltip(targetElement)
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
},
|
|
37
76
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
77
|
+
updated: (targetElement: HTMLElement, binding) => {
|
|
78
|
+
if (typeof(binding.value) === 'string') {
|
|
79
|
+
setTooltipConfig(binding.value, globalConfig, binding.arg as TooltipPosition)
|
|
80
|
+
initTooltip(targetElement)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
41
83
|
}
|
|
84
|
+
}
|
|
42
85
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
86
|
+
function setTooltipConfig(localConfig: string | TooltipLocalConfig, globalConfig?: TooltipConfig, position?: TooltipPosition) {
|
|
87
|
+
tooltipText = getTooltipText(localConfig)
|
|
88
|
+
|
|
89
|
+
if (typeof(localConfig) !== 'string') {
|
|
90
|
+
tooltipPosition = position ?? localConfig.defaultPosition ?? globalConfig?.defaultPosition ?? defaultTooltipPosition;
|
|
91
|
+
tooltipPositions = {
|
|
92
|
+
left: localConfig.positions?.left ?? globalConfig?.positions?.left ?? defaultTooltipPositions.left,
|
|
93
|
+
top: localConfig.positions?.top ?? globalConfig?.positions?.top ?? defaultTooltipPositions.top,
|
|
94
|
+
right: localConfig.positions?.right ?? globalConfig?.positions?.right ?? defaultTooltipPositions.right,
|
|
95
|
+
bottom: localConfig.positions?.bottom ?? globalConfig?.positions?.bottom ?? defaultTooltipPositions.bottom,
|
|
96
|
+
}
|
|
97
|
+
tooltipOffsetFromSource = localConfig.offsetFromSource ?? globalConfig?.offsetFromSource ?? defaultTooltipOffsetFromSource
|
|
98
|
+
tooltipOffsetFromViewport = localConfig.offsetFromViewport ?? globalConfig?.offsetFromViewport ?? defaultTooltipOffsetFromViewport
|
|
99
|
+
tooltipMinWidth = localConfig.minWidth ?? globalConfig?.minWidth ?? defaultTooltipMinWidth
|
|
100
|
+
tooltipMaxWidth = localConfig.maxWidth ?? globalConfig?.maxWidth ?? defaultTooltipMaxWidth
|
|
101
|
+
tooltipBorderWidth = localConfig.tooltipBorderWidth ?? globalConfig?.tooltipBorderWidth ?? defaultTooltipBorderWidth
|
|
102
|
+
tooltipClasses = tooltipElementClass + ' ' + defaultTooltipClasses + ' ' + (localConfig.tooltipClasses ?? globalConfig?.tooltipClasses ?? '')
|
|
103
|
+
textClasses = textElementClass + ' ' + defaultTextClasses + ' ' + (localConfig.textClasses ?? globalConfig?.textClasses ?? '')
|
|
104
|
+
arrowSize = localConfig.arrowSize ?? globalConfig?.arrowSize ?? defaultArrowSize
|
|
105
|
+
arrowClasses = localConfig.arrowClasses ?? globalConfig?.arrowClasses ?? ''
|
|
106
|
+
arrowMinOffsetFromTooltipCorner = localConfig.arrowMinOffsetFromTooltipCorner ?? globalConfig?.arrowMinOffsetFromTooltipCorner ?? defaultMinArrowOffsetFromTooltipCorner
|
|
107
|
+
zIndex = localConfig.zIndex ?? globalConfig?.zIndex ?? defaultZIndex
|
|
108
|
+
shouldShow = localConfig.show ?? defaultShouldShow
|
|
49
109
|
}
|
|
50
|
-
let tooltipOffsetFromSource = config?.offsetFromSource ?? defaultTooltipOffsetFromSource
|
|
51
|
-
let tooltipOffsetFromViewport = config?.offsetFromViewport ?? defaultTooltipOffsetFromViewport
|
|
52
|
-
let tooltipMinWidth = config?.minWidth ?? defaultTooltipMinWidth
|
|
53
|
-
let tooltipMaxWidth = config?.maxWidth ?? defaultTooltipMaxWidth
|
|
54
|
-
let tooltipBorderWidth = config?.tooltipBorderWidth ?? defaultTooltipBorderWidth
|
|
55
|
-
let tooltipClasses = tooltipElementClass + ' ' + defaultTooltipClasses + ' ' + config?.tooltipClasses ?? ''
|
|
56
|
-
let textClasses = textElementClass + ' ' + defaultTextClasses + ' ' + config?.textClasses ?? ''
|
|
57
|
-
let arrowSize = config?.arrowSize ?? defaultArrowSize
|
|
58
|
-
let arrowMinOffsetFromTooltipCorner = config?.arrowMinOffsetFromTooltipCorner ?? defaultMinArrowOffsetFromTooltipCorner
|
|
59
|
-
let zIndex = config?.zIndex ?? defaultZIndex
|
|
60
110
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
111
|
+
if (tooltipPosition === undefined) tooltipPosition = position ?? globalConfig?.defaultPosition ?? defaultTooltipPosition;
|
|
112
|
+
if (tooltipPositions === undefined) tooltipPositions = {
|
|
113
|
+
left: globalConfig?.positions?.left ?? defaultTooltipPositions.left,
|
|
114
|
+
top: globalConfig?.positions?.top ?? defaultTooltipPositions.top,
|
|
115
|
+
right: globalConfig?.positions?.right ?? defaultTooltipPositions.right,
|
|
116
|
+
bottom: globalConfig?.positions?.bottom ?? defaultTooltipPositions.bottom,
|
|
117
|
+
}
|
|
118
|
+
if (tooltipOffsetFromSource === undefined) tooltipOffsetFromSource = globalConfig?.offsetFromSource ?? defaultTooltipOffsetFromSource
|
|
119
|
+
if (tooltipOffsetFromViewport === undefined) tooltipOffsetFromViewport = globalConfig?.offsetFromViewport ?? defaultTooltipOffsetFromViewport
|
|
120
|
+
if (tooltipMinWidth === undefined) tooltipMinWidth = globalConfig?.minWidth ?? defaultTooltipMinWidth
|
|
121
|
+
if (tooltipMaxWidth === undefined) tooltipMaxWidth = globalConfig?.maxWidth ?? defaultTooltipMaxWidth
|
|
122
|
+
if (tooltipBorderWidth === undefined) tooltipBorderWidth = globalConfig?.tooltipBorderWidth ?? defaultTooltipBorderWidth
|
|
123
|
+
if (tooltipClasses === undefined) tooltipClasses = tooltipElementClass + ' ' + defaultTooltipClasses + ' ' + globalConfig?.tooltipClasses ?? ''
|
|
124
|
+
if (textClasses === undefined) textClasses = textElementClass + ' ' + defaultTextClasses + ' ' + globalConfig?.textClasses ?? ''
|
|
125
|
+
if (arrowSize === undefined) arrowSize = globalConfig?.arrowSize ?? defaultArrowSize
|
|
126
|
+
if (arrowClasses === undefined) arrowClasses = globalConfig?.arrowClasses ?? ''
|
|
127
|
+
if (arrowMinOffsetFromTooltipCorner === undefined) arrowMinOffsetFromTooltipCorner = globalConfig?.arrowMinOffsetFromTooltipCorner ?? defaultMinArrowOffsetFromTooltipCorner
|
|
128
|
+
if (zIndex === undefined) zIndex = globalConfig?.zIndex ?? defaultZIndex
|
|
129
|
+
if (shouldShow === undefined) shouldShow = defaultShouldShow
|
|
130
|
+
}
|
|
65
131
|
|
|
66
|
-
|
|
132
|
+
function getTooltipText(localConfig: string | TooltipLocalConfig) {
|
|
133
|
+
const tooltipText = typeof(localConfig) === 'string' ? localConfig : localConfig.content
|
|
67
134
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
135
|
+
if (!tooltipText) {
|
|
136
|
+
throw new Error("Please enter valid tooltip value");
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return tooltipText
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function initTooltip(targetElement: HTMLElement) {
|
|
143
|
+
anchorElement = targetElement
|
|
144
|
+
anchorElement.removeEventListener('mouseenter', onMouseEnter)
|
|
145
|
+
anchorElement.removeEventListener('mouseleave', onMouseLeave)
|
|
146
|
+
|
|
147
|
+
createTextElement()
|
|
148
|
+
createTooltipElement()
|
|
149
|
+
|
|
150
|
+
anchorElement.addEventListener('mouseenter', onMouseEnter)
|
|
151
|
+
anchorElement.addEventListener('mouseleave', onMouseLeave)
|
|
152
|
+
|
|
153
|
+
if (isHovered) {
|
|
154
|
+
anchorElement.dispatchEvent(new Event('mouseleave'))
|
|
155
|
+
anchorElement.dispatchEvent(new Event('mouseenter'))
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function createTextElement() {
|
|
160
|
+
tooltipTextElement = document.createElement('p')
|
|
161
|
+
tooltipTextElement.classList.add(...textClasses.trim().split(' '))
|
|
162
|
+
tooltipTextElement.innerHTML = tooltipText
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function createTooltipElement() {
|
|
166
|
+
tooltipElement = document.createElement('div')
|
|
167
|
+
tooltipElement.classList.add(...tooltipClasses.trim().split(' '))
|
|
168
|
+
tooltipElement.style.borderWidth = `${tooltipBorderWidth}px`
|
|
169
|
+
tooltipElement.appendChild(tooltipTextElement)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function onMouseEnter() {
|
|
173
|
+
isHovered = true
|
|
174
|
+
|
|
175
|
+
if (!shouldShow) return
|
|
176
|
+
|
|
177
|
+
const anchorElementRect = anchorElement.getBoundingClientRect()
|
|
178
|
+
|
|
179
|
+
// Mount Tooltip element to body
|
|
180
|
+
const body = document.querySelector('body')
|
|
181
|
+
body?.appendChild(tooltipElement)
|
|
182
|
+
|
|
183
|
+
// Find suitable Tooltip position
|
|
184
|
+
let hasNeededDisplaySpace = false
|
|
185
|
+
let currentTooltipPosition = tooltipPosition
|
|
186
|
+
for (let i = 0; i < 4; i++) {
|
|
187
|
+
currentTooltipPosition = tooltipPositions[tooltipPosition][i]
|
|
188
|
+
|
|
189
|
+
if (currentTooltipPosition === 'left') {
|
|
190
|
+
hasNeededDisplaySpace = tryMountTooltipOnLeft(anchorElementRect)
|
|
191
|
+
} else if (currentTooltipPosition === 'top') {
|
|
192
|
+
hasNeededDisplaySpace = tryMountTooltipOnTop(anchorElementRect)
|
|
193
|
+
} else if (currentTooltipPosition === 'right') {
|
|
194
|
+
hasNeededDisplaySpace = tryMountTooltipOnRight(anchorElementRect)
|
|
195
|
+
} else if (currentTooltipPosition === 'bottom') {
|
|
196
|
+
hasNeededDisplaySpace = tryMountTooltipOnBottom(anchorElementRect)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (hasNeededDisplaySpace) break
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (hasNeededDisplaySpace) {
|
|
203
|
+
drawArrow(anchorElementRect, currentTooltipPosition)
|
|
204
|
+
|
|
205
|
+
tooltipElement.style.opacity = '1'
|
|
206
|
+
tooltipElement.style.zIndex = zIndex.toString()
|
|
207
|
+
|
|
208
|
+
handleHideOnScroll(anchorElement, () => hideTooltip())
|
|
209
|
+
handleHideOnResize(anchorElement, () => hideTooltip())
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function onMouseLeave() {
|
|
214
|
+
hideTooltip()
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function tryMountTooltipOnLeft(anchorElementRect: DOMRect) {
|
|
218
|
+
// Check if Tooltip has enough available horizontal space, top and bottom offset from viewport
|
|
219
|
+
const tooltipAvailableMaxWidth = Math.min(anchorElementRect.left - tooltipOffsetFromSource - tooltipOffsetFromViewport, tooltipMaxWidth)
|
|
220
|
+
const isAnchorElementTopLowerThanOffsetFromViewport = anchorElementRect.top >= tooltipOffsetFromViewport
|
|
221
|
+
const isAnchorElementBottomHigherThanOffsetFromViewport = (window.innerHeight - anchorElementRect.bottom) >= tooltipOffsetFromViewport
|
|
222
|
+
|
|
223
|
+
if (tooltipAvailableMaxWidth < tooltipMinWidth || !isAnchorElementTopLowerThanOffsetFromViewport || !isAnchorElementBottomHigherThanOffsetFromViewport) return false
|
|
224
|
+
|
|
225
|
+
// Set Tooltip maxWidth
|
|
226
|
+
tooltipElement.style.maxWidth = `${tooltipAvailableMaxWidth}px`
|
|
227
|
+
|
|
228
|
+
// Calculate Tooltip position
|
|
229
|
+
const tooltipElementRect = tooltipElement.getBoundingClientRect()
|
|
230
|
+
let tooltipTop = anchorElementRect.top + (anchorElementRect.height / 2) - (tooltipElementRect.height / 2)
|
|
110
231
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
// Add listeners for hiding Tooltip element
|
|
120
|
-
anchorElement.addEventListener('mouseleave', () => hideTooltip())
|
|
121
|
-
|
|
122
|
-
// --- Helper functions (placed here because of variables scopes are local (don't wan to use a lot of parameters)) --- //
|
|
123
|
-
function adjustTooltipSettings(bindingValue: TooltipLocalConfig) {
|
|
124
|
-
if (bindingValue.defaultPosition) tooltipPosition = bindingValue.defaultPosition
|
|
125
|
-
if (bindingValue.positions) tooltipPositions = {...tooltipPositions, ...bindingValue.positions}
|
|
126
|
-
if (bindingValue.offsetFromSource) tooltipOffsetFromSource = bindingValue.offsetFromSource
|
|
127
|
-
if (bindingValue.offsetFromViewport) tooltipOffsetFromViewport = bindingValue.offsetFromViewport
|
|
128
|
-
if (bindingValue.minWidth) tooltipMinWidth = bindingValue.minWidth
|
|
129
|
-
if (bindingValue.maxWidth) tooltipMaxWidth = bindingValue.maxWidth
|
|
130
|
-
if (bindingValue.tooltipBorderWidth) tooltipBorderWidth = bindingValue.tooltipBorderWidth
|
|
131
|
-
if (bindingValue.tooltipClasses) tooltipClasses = bindingValue.tooltipClasses
|
|
132
|
-
if (bindingValue.textClasses) textClasses = bindingValue.textClasses
|
|
133
|
-
if (bindingValue.arrowSize) arrowSize = bindingValue.arrowSize
|
|
134
|
-
if (bindingValue.arrowMinOffsetFromTooltipCorner) arrowMinOffsetFromTooltipCorner = bindingValue.arrowMinOffsetFromTooltipCorner
|
|
135
|
-
if (bindingValue.zIndex) zIndex = bindingValue.zIndex
|
|
136
|
-
}
|
|
232
|
+
if (tooltipTop < tooltipOffsetFromViewport) {
|
|
233
|
+
tooltipTop = tooltipOffsetFromViewport
|
|
234
|
+
} else if (tooltipTop + tooltipElementRect.height > window.innerHeight - tooltipOffsetFromViewport) {
|
|
235
|
+
tooltipTop = window.innerHeight - tooltipOffsetFromViewport - tooltipElementRect.height
|
|
236
|
+
}
|
|
137
237
|
|
|
138
|
-
|
|
139
|
-
// Check if Tooltip has enough available horizontal space, top and bottom offset from viewport
|
|
140
|
-
const tooltipAvailableMaxWidth = Math.min(anchorElementRect.left - tooltipOffsetFromSource - tooltipOffsetFromViewport, tooltipMaxWidth)
|
|
141
|
-
const isAnchorElementTopLowerThanOffsetFromViewport = anchorElementRect.top >= tooltipOffsetFromViewport
|
|
142
|
-
const isAnchorElementBottomHigherThanOffsetFromViewport = (window.innerHeight - anchorElementRect.bottom) >= tooltipOffsetFromViewport
|
|
238
|
+
const tooltipLeft = anchorElementRect.left - tooltipOffsetFromSource - tooltipElementRect.width
|
|
143
239
|
|
|
144
|
-
|
|
240
|
+
// Check if anchor element is directly on right of Tooltip
|
|
241
|
+
if (anchorElementRect.bottom < tooltipTop + arrowMinOffsetFromTooltipCorner * 2
|
|
242
|
+
|| anchorElementRect.top > tooltipTop + tooltipElementRect.height - arrowMinOffsetFromTooltipCorner * 2) return false
|
|
145
243
|
|
|
146
|
-
|
|
147
|
-
|
|
244
|
+
// Set Tooltip position
|
|
245
|
+
tooltipElement.style.top = `${tooltipTop}px`
|
|
246
|
+
tooltipElement.style.left = `${tooltipLeft}px`
|
|
148
247
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
let tooltipTop = anchorElementRect.top + (anchorElementRect.height / 2) - (tooltipElementRect.height / 2)
|
|
152
|
-
|
|
153
|
-
if (tooltipTop < tooltipOffsetFromViewport) {
|
|
154
|
-
tooltipTop = tooltipOffsetFromViewport
|
|
155
|
-
} else if (tooltipTop + tooltipElementRect.height > window.innerHeight - tooltipOffsetFromViewport) {
|
|
156
|
-
tooltipTop = window.innerHeight - tooltipOffsetFromViewport - tooltipElementRect.height
|
|
157
|
-
}
|
|
248
|
+
return true
|
|
249
|
+
}
|
|
158
250
|
|
|
159
|
-
|
|
251
|
+
function tryMountTooltipOnRight(anchorElementRect: DOMRect) {
|
|
252
|
+
// Check if Tooltip has enough available horizontal space, top and bottom offset from viewport
|
|
253
|
+
const tooltipAvailableMaxWidth = Math.min(window.innerWidth - (anchorElementRect.right + tooltipOffsetFromSource) - tooltipOffsetFromViewport, tooltipMaxWidth)
|
|
254
|
+
const isAnchorElementTopLowerThanOffsetFromViewport = anchorElementRect.top >= tooltipOffsetFromViewport
|
|
255
|
+
const isAnchorElementBottomHigherThanOffsetFromViewport = (window.innerHeight - anchorElementRect.bottom) >= tooltipOffsetFromViewport
|
|
160
256
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
257
|
+
if (tooltipAvailableMaxWidth < tooltipMinWidth || !isAnchorElementTopLowerThanOffsetFromViewport || !isAnchorElementBottomHigherThanOffsetFromViewport) return false
|
|
258
|
+
|
|
259
|
+
// Set tooltip maxWidth
|
|
260
|
+
tooltipElement.style.maxWidth = `${tooltipAvailableMaxWidth}px`
|
|
164
261
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
tooltipElement.style.left = `${tooltipLeft}px`
|
|
262
|
+
// Calculate Tooltip position
|
|
263
|
+
const tooltipElementRect = tooltipElement.getBoundingClientRect()
|
|
168
264
|
|
|
169
|
-
|
|
170
|
-
|
|
265
|
+
let tooltipTop = anchorElementRect.top + (anchorElementRect.height / 2) - (tooltipElementRect.height / 2)
|
|
266
|
+
|
|
267
|
+
if (tooltipTop < tooltipOffsetFromViewport) {
|
|
268
|
+
tooltipTop = tooltipOffsetFromViewport
|
|
269
|
+
} else if (tooltipTop + tooltipElementRect.height > window.innerHeight - tooltipOffsetFromViewport) {
|
|
270
|
+
tooltipTop = window.innerHeight - tooltipOffsetFromViewport - tooltipElementRect.height
|
|
271
|
+
}
|
|
171
272
|
|
|
172
|
-
|
|
173
|
-
// Check if Tooltip has enough available horizontal space, top and bottom offset from viewport
|
|
174
|
-
const tooltipAvailableMaxWidth = Math.min(window.innerWidth - (anchorElementRect.right + tooltipOffsetFromSource) - tooltipOffsetFromViewport, tooltipMaxWidth)
|
|
175
|
-
const isAnchorElementTopLowerThanOffsetFromViewport = anchorElementRect.top >= tooltipOffsetFromViewport
|
|
176
|
-
const isAnchorElementBottomHigherThanOffsetFromViewport = (window.innerHeight - anchorElementRect.bottom) >= tooltipOffsetFromViewport
|
|
273
|
+
const tooltipLeft = anchorElementRect.right + tooltipOffsetFromSource
|
|
177
274
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
tooltipElement.style.maxWidth = `${tooltipAvailableMaxWidth}px`
|
|
275
|
+
// Check if anchor element is directly on left of Tooltip
|
|
276
|
+
if (anchorElementRect.bottom < tooltipTop + arrowMinOffsetFromTooltipCorner * 2
|
|
277
|
+
|| anchorElementRect.top > tooltipTop + tooltipElementRect.height - arrowMinOffsetFromTooltipCorner * 2) return false
|
|
182
278
|
|
|
183
|
-
|
|
184
|
-
|
|
279
|
+
// Set Tooltip position
|
|
280
|
+
tooltipElement.style.top = `${tooltipTop}px`
|
|
281
|
+
tooltipElement.style.left = `${tooltipLeft}px`
|
|
185
282
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (tooltipTop < tooltipOffsetFromViewport) {
|
|
189
|
-
tooltipTop = tooltipOffsetFromViewport
|
|
190
|
-
} else if (tooltipTop + tooltipElementRect.height > window.innerHeight - tooltipOffsetFromViewport) {
|
|
191
|
-
tooltipTop = window.innerHeight - tooltipOffsetFromViewport - tooltipElementRect.height
|
|
192
|
-
}
|
|
283
|
+
return true
|
|
284
|
+
}
|
|
193
285
|
|
|
194
|
-
|
|
286
|
+
function tryMountTooltipOnTop(anchorElementRect: DOMRect) {
|
|
287
|
+
// Calculate and set Tooltip width
|
|
288
|
+
const tooltipAvailableMaxWidth = Math.min(window.innerWidth - (tooltipOffsetFromViewport * 2), tooltipMaxWidth)
|
|
289
|
+
tooltipElement.style.maxWidth = `${tooltipAvailableMaxWidth}px`
|
|
195
290
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
291
|
+
// Calculate Tooltip top position
|
|
292
|
+
const tooltipElementRect = tooltipElement.getBoundingClientRect()
|
|
293
|
+
let tooltipTop = anchorElementRect.top - tooltipOffsetFromSource - tooltipElementRect.height
|
|
199
294
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
tooltipElement.style.left = `${tooltipLeft}px`
|
|
295
|
+
// Check if Tooltip has enough available on top
|
|
296
|
+
if (tooltipTop < tooltipOffsetFromViewport) return false
|
|
203
297
|
|
|
204
|
-
|
|
205
|
-
|
|
298
|
+
// Calculate Tooltip left position
|
|
299
|
+
let tooltipLeft = anchorElementRect.left + (anchorElementRect.width / 2) - (tooltipElementRect.width / 2)
|
|
206
300
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
301
|
+
if (tooltipLeft < tooltipOffsetFromViewport) {
|
|
302
|
+
tooltipLeft = tooltipOffsetFromViewport
|
|
303
|
+
} else if (tooltipLeft + tooltipElementRect.width > window.innerWidth - tooltipOffsetFromViewport) {
|
|
304
|
+
tooltipLeft = window.innerWidth - tooltipOffsetFromViewport - tooltipElementRect.width
|
|
305
|
+
}
|
|
211
306
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
307
|
+
// Check if anchor element is directly on below of Tooltip
|
|
308
|
+
if (anchorElementRect.left > tooltipLeft + tooltipElementRect.width - arrowMinOffsetFromTooltipCorner * 2
|
|
309
|
+
|| anchorElementRect.right < tooltipLeft + arrowMinOffsetFromTooltipCorner * 2) return false
|
|
215
310
|
|
|
216
|
-
|
|
217
|
-
|
|
311
|
+
// Set Tooltip position
|
|
312
|
+
tooltipElement.style.top = `${tooltipTop}px`
|
|
313
|
+
tooltipElement.style.left = `${tooltipLeft}px`
|
|
218
314
|
|
|
219
|
-
|
|
220
|
-
|
|
315
|
+
return true
|
|
316
|
+
}
|
|
221
317
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
318
|
+
function tryMountTooltipOnBottom(anchorElementRect: DOMRect) {
|
|
319
|
+
// Calculate and set Tooltip width
|
|
320
|
+
const tooltipAvailableMaxWidth = Math.min(window.innerWidth - (tooltipOffsetFromViewport * 2), tooltipMaxWidth)
|
|
321
|
+
tooltipElement.style.maxWidth = `${tooltipAvailableMaxWidth}px`
|
|
227
322
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
323
|
+
// Calculate Tooltip top position
|
|
324
|
+
const tooltipElementRect = tooltipElement.getBoundingClientRect()
|
|
325
|
+
let tooltipTop = anchorElementRect.bottom + tooltipOffsetFromSource
|
|
231
326
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
327
|
+
// Check if Tooltip has enough available on bottom
|
|
328
|
+
if (tooltipTop + tooltipElementRect.height > window.innerHeight - tooltipOffsetFromViewport) return false
|
|
329
|
+
|
|
330
|
+
// Calculate Tooltip left position
|
|
331
|
+
let tooltipLeft = anchorElementRect.left + (anchorElementRect.width / 2) - (tooltipElementRect.width / 2)
|
|
235
332
|
|
|
236
|
-
|
|
237
|
-
|
|
333
|
+
if (tooltipLeft < tooltipOffsetFromViewport) {
|
|
334
|
+
tooltipLeft = tooltipOffsetFromViewport
|
|
335
|
+
} else if (tooltipLeft + tooltipElementRect.width > window.innerWidth - tooltipOffsetFromViewport) {
|
|
336
|
+
tooltipLeft = window.innerWidth - tooltipOffsetFromViewport - tooltipElementRect.width
|
|
337
|
+
}
|
|
238
338
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
tooltipElement.style.maxWidth = `${tooltipAvailableMaxWidth}px`
|
|
339
|
+
// Check if anchor element is directly on top of Tooltip
|
|
340
|
+
if (anchorElementRect.left > tooltipLeft + tooltipElementRect.width - arrowMinOffsetFromTooltipCorner * 2
|
|
341
|
+
|| anchorElementRect.right < tooltipLeft + arrowMinOffsetFromTooltipCorner * 2) return false
|
|
243
342
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
343
|
+
// Set Tooltip position
|
|
344
|
+
tooltipElement.style.top = `${tooltipTop}px`
|
|
345
|
+
tooltipElement.style.left = `${tooltipLeft}px`
|
|
247
346
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
// Calculate Tooltip left position
|
|
252
|
-
let tooltipLeft = anchorElementRect.left + (anchorElementRect.width / 2) - (tooltipElementRect.width / 2)
|
|
347
|
+
return true
|
|
348
|
+
}
|
|
253
349
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
350
|
+
function drawArrow(anchorElementRect: DOMRect, currentTooltipPosition: TooltipPosition) {
|
|
351
|
+
// Create Arrow element
|
|
352
|
+
const arrowElement = document.createElement('div')
|
|
353
|
+
|
|
354
|
+
// Calculate Arrow element size, positions and style/angle classes
|
|
355
|
+
const tooltipElementRect = tooltipElement.getBoundingClientRect()
|
|
356
|
+
const arrowHalfLengthOfLongSide = Math.sin(45 * (180 / Math.PI)) * arrowSize
|
|
357
|
+
|
|
358
|
+
// Adjusts arrow position by `x` pixels to handle browsers sometimes not rendering border in it's full width, e.g., 4.8px instead of 5px
|
|
359
|
+
const arrowPositionAdjuster = 1;
|
|
360
|
+
|
|
361
|
+
// Arrow top/left 0 is Tooltip top/left 0
|
|
362
|
+
let arrowTop = 0
|
|
363
|
+
let arrowLeft = 0
|
|
364
|
+
|
|
365
|
+
let arrowClassForCorrectAngle = ''
|
|
366
|
+
|
|
367
|
+
switch (currentTooltipPosition) {
|
|
368
|
+
case "left":
|
|
369
|
+
arrowClassForCorrectAngle = '!zt-border-y-transparent !zt-border-r-transparent'
|
|
370
|
+
arrowTop = anchorElementRect.top - tooltipElementRect.top + (anchorElementRect.height / 2) - arrowHalfLengthOfLongSide - tooltipBorderWidth
|
|
371
|
+
arrowLeft = tooltipElementRect.width - tooltipBorderWidth - arrowPositionAdjuster
|
|
372
|
+
break;
|
|
373
|
+
case "top":
|
|
374
|
+
arrowClassForCorrectAngle = '!zt-border-x-transparent !zt-border-b-transparent'
|
|
375
|
+
arrowTop = tooltipElementRect.height - tooltipBorderWidth - arrowPositionAdjuster
|
|
376
|
+
arrowLeft = anchorElementRect.left - tooltipElementRect.left + (anchorElementRect.width / 2) - arrowHalfLengthOfLongSide - tooltipBorderWidth
|
|
377
|
+
break;
|
|
378
|
+
case "right":
|
|
379
|
+
arrowClassForCorrectAngle = '!zt-border-y-transparent !zt-border-l-transparent'
|
|
380
|
+
arrowTop = anchorElementRect.top - tooltipElementRect.top + (anchorElementRect.height / 2) - arrowHalfLengthOfLongSide - tooltipBorderWidth
|
|
381
|
+
arrowLeft = (-arrowSize * 2) - tooltipBorderWidth + arrowPositionAdjuster
|
|
382
|
+
break;
|
|
383
|
+
case "bottom":
|
|
384
|
+
arrowClassForCorrectAngle = '!zt-border-x-transparent !zt-border-t-transparent'
|
|
385
|
+
arrowTop = (-arrowSize * 2) - tooltipBorderWidth + arrowPositionAdjuster
|
|
386
|
+
arrowLeft = anchorElementRect.left - tooltipElementRect.left + (anchorElementRect.width / 2) - arrowHalfLengthOfLongSide - tooltipBorderWidth
|
|
387
|
+
break;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
if (currentTooltipPosition === 'left' || currentTooltipPosition === 'right') {
|
|
391
|
+
if (!isArrowPositionWithinLimits(currentTooltipPosition, tooltipElementRect, arrowTop)) {
|
|
392
|
+
arrowTop = getArrowPositionMinLimit(currentTooltipPosition, tooltipElementRect, arrowTop)
|
|
393
|
+
}
|
|
394
|
+
} else {
|
|
395
|
+
if (!isArrowPositionWithinLimits(currentTooltipPosition, tooltipElementRect, arrowLeft)) {
|
|
396
|
+
arrowLeft = getArrowPositionMinLimit(currentTooltipPosition, tooltipElementRect, arrowLeft)
|
|
397
|
+
}
|
|
398
|
+
}
|
|
259
399
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|| anchorElementRect.right < tooltipLeft + arrowMinOffsetFromTooltipCorner * 2) return false
|
|
400
|
+
// Set Arrow element id, styling/angle
|
|
401
|
+
const adjustedArrowClasses = arrowElementClass + ' ' + defaultArrowClasses + ' ' + arrowClassForCorrectAngle + ' ' + arrowClasses
|
|
263
402
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
403
|
+
arrowElement.classList.add(...adjustedArrowClasses.trim().split(' '))
|
|
404
|
+
|
|
405
|
+
// Set Arrow element size and position
|
|
406
|
+
arrowElement.style.top = `${arrowTop}px`
|
|
407
|
+
arrowElement.style.left = `${arrowLeft}px`
|
|
408
|
+
arrowElement.style.borderWidth = `${arrowSize}px`
|
|
267
409
|
|
|
268
|
-
|
|
269
|
-
|
|
410
|
+
// Mount Arrow element
|
|
411
|
+
document.querySelector(`.${tooltipElementClass}`)?.appendChild(arrowElement)
|
|
412
|
+
}
|
|
270
413
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
let arrowTop = 0
|
|
284
|
-
let arrowLeft = 0
|
|
285
|
-
|
|
286
|
-
let arrowClassForCorrectAngle = ''
|
|
287
|
-
|
|
288
|
-
switch (currentTooltipPosition) {
|
|
289
|
-
case "left":
|
|
290
|
-
arrowClassForCorrectAngle = '!zt-border-y-transparent !zt-border-r-transparent'
|
|
291
|
-
arrowTop = anchorElementRect.top - tooltipElementRect.top + (anchorElementRect.height / 2) - arrowHalfLengthOfLongSide - tooltipBorderWidth
|
|
292
|
-
arrowLeft = tooltipElementRect.width - tooltipBorderWidth - arrowPositionAdjuster
|
|
293
|
-
break;
|
|
294
|
-
case "top":
|
|
295
|
-
arrowClassForCorrectAngle = '!zt-border-x-transparent !zt-border-b-transparent'
|
|
296
|
-
arrowTop = tooltipElementRect.height - tooltipBorderWidth - arrowPositionAdjuster
|
|
297
|
-
arrowLeft = anchorElementRect.left - tooltipElementRect.left + (anchorElementRect.width / 2) - arrowHalfLengthOfLongSide - tooltipBorderWidth
|
|
298
|
-
break;
|
|
299
|
-
case "right":
|
|
300
|
-
arrowClassForCorrectAngle = '!zt-border-y-transparent !zt-border-l-transparent'
|
|
301
|
-
arrowTop = anchorElementRect.top - tooltipElementRect.top + (anchorElementRect.height / 2) - arrowHalfLengthOfLongSide - tooltipBorderWidth
|
|
302
|
-
arrowLeft = (-arrowSize * 2) - tooltipBorderWidth + arrowPositionAdjuster
|
|
303
|
-
break;
|
|
304
|
-
case "bottom":
|
|
305
|
-
arrowClassForCorrectAngle = '!zt-border-x-transparent !zt-border-t-transparent'
|
|
306
|
-
arrowTop = (-arrowSize * 2) - tooltipBorderWidth + arrowPositionAdjuster
|
|
307
|
-
arrowLeft = anchorElementRect.left - tooltipElementRect.left + (anchorElementRect.width / 2) - arrowHalfLengthOfLongSide - tooltipBorderWidth
|
|
308
|
-
break;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
if (currentTooltipPosition === 'left' || currentTooltipPosition === 'right') {
|
|
312
|
-
if (!isArrowPositionWithinLimits(currentTooltipPosition, tooltipElementRect, arrowTop)) {
|
|
313
|
-
arrowTop = getArrowPositionMinLimit(currentTooltipPosition, tooltipElementRect, arrowTop)
|
|
314
|
-
}
|
|
315
|
-
} else {
|
|
316
|
-
if (!isArrowPositionWithinLimits(currentTooltipPosition, tooltipElementRect, arrowLeft)) {
|
|
317
|
-
arrowLeft = getArrowPositionMinLimit(currentTooltipPosition, tooltipElementRect, arrowLeft)
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
// Set Arrow element id, styling/angle
|
|
322
|
-
const arrowClasses = arrowElementClass + ' ' + defaultArrowClasses + ' ' + arrowClassForCorrectAngle + ' ' + config?.arrowClasses ?? ''
|
|
323
|
-
arrowElement.classList.add(...arrowClasses.split(' '))
|
|
324
|
-
|
|
325
|
-
// Set Arrow element size and position
|
|
326
|
-
arrowElement.style.top = `${arrowTop}px`
|
|
327
|
-
arrowElement.style.left = `${arrowLeft}px`
|
|
328
|
-
arrowElement.style.borderWidth = `${arrowSize}px`
|
|
329
|
-
|
|
330
|
-
// Mount Arrow element
|
|
331
|
-
document.querySelector(`.${tooltipElementClass}`)?.appendChild(arrowElement)
|
|
332
|
-
}
|
|
414
|
+
function isArrowPositionWithinLimits(currentTooltipPosition: TooltipPosition, tooltipElementRect: DOMRect, arrowPosition: number) {
|
|
415
|
+
switch (currentTooltipPosition) {
|
|
416
|
+
case "left":
|
|
417
|
+
case "right":
|
|
418
|
+
return arrowPosition > arrowMinOffsetFromTooltipCorner - tooltipBorderWidth
|
|
419
|
+
&& arrowPosition < tooltipElementRect.height + tooltipBorderWidth - arrowMinOffsetFromTooltipCorner - (arrowSize * 2)
|
|
420
|
+
case "top":
|
|
421
|
+
case "bottom":
|
|
422
|
+
return arrowPosition > arrowMinOffsetFromTooltipCorner - tooltipBorderWidth
|
|
423
|
+
&& arrowPosition < tooltipElementRect.width + tooltipBorderWidth - arrowMinOffsetFromTooltipCorner - (arrowSize * 2)
|
|
424
|
+
}
|
|
425
|
+
}
|
|
333
426
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
}
|
|
427
|
+
function getArrowPositionMinLimit(currentTooltipPosition: TooltipPosition, tooltipElementRect: DOMRect, arrowPosition: number) {
|
|
428
|
+
switch (currentTooltipPosition) {
|
|
429
|
+
case "left":
|
|
430
|
+
case "right":
|
|
431
|
+
if (arrowPosition < arrowMinOffsetFromTooltipCorner - tooltipBorderWidth) {
|
|
432
|
+
// Arrow too close to viewport top
|
|
433
|
+
return arrowMinOffsetFromTooltipCorner - tooltipBorderWidth
|
|
434
|
+
} else {
|
|
435
|
+
// Arrow too close to viewport bottom
|
|
436
|
+
return tooltipElementRect.height - tooltipBorderWidth - arrowMinOffsetFromTooltipCorner - (arrowSize * 2)
|
|
345
437
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
} else {
|
|
355
|
-
// Arrow too close to viewport bottom
|
|
356
|
-
return tooltipElementRect.height - tooltipBorderWidth - arrowMinOffsetFromTooltipCorner - (arrowSize * 2)
|
|
357
|
-
}
|
|
358
|
-
case "top":
|
|
359
|
-
case "bottom":
|
|
360
|
-
if (arrowPosition < arrowMinOffsetFromTooltipCorner - tooltipBorderWidth) {
|
|
361
|
-
// Arrow too close to viewport left
|
|
362
|
-
return arrowMinOffsetFromTooltipCorner - tooltipBorderWidth
|
|
363
|
-
} else {
|
|
364
|
-
// Arrow too close to viewport right
|
|
365
|
-
return tooltipElementRect.width - tooltipBorderWidth - arrowMinOffsetFromTooltipCorner - (arrowSize * 2)
|
|
366
|
-
}
|
|
367
|
-
}
|
|
438
|
+
case "top":
|
|
439
|
+
case "bottom":
|
|
440
|
+
if (arrowPosition < arrowMinOffsetFromTooltipCorner - tooltipBorderWidth) {
|
|
441
|
+
// Arrow too close to viewport left
|
|
442
|
+
return arrowMinOffsetFromTooltipCorner - tooltipBorderWidth
|
|
443
|
+
} else {
|
|
444
|
+
// Arrow too close to viewport right
|
|
445
|
+
return tooltipElementRect.width - tooltipBorderWidth - arrowMinOffsetFromTooltipCorner - (arrowSize * 2)
|
|
368
446
|
}
|
|
369
|
-
},
|
|
370
447
|
}
|
|
371
448
|
}
|
|
372
449
|
|
|
@@ -385,22 +462,8 @@ function hideTooltip() {
|
|
|
385
462
|
|
|
386
463
|
tooltipElement.remove()
|
|
387
464
|
}
|
|
388
|
-
}
|
|
389
465
|
|
|
390
|
-
|
|
391
|
-
let tooltipText = ''
|
|
392
|
-
|
|
393
|
-
if (typeof(bindingValue) === 'string') {
|
|
394
|
-
tooltipText = bindingValue
|
|
395
|
-
} else {
|
|
396
|
-
tooltipText = bindingValue.content
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
if (!tooltipText) {
|
|
400
|
-
throw new Error("Please enter valid tooltip value");
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
return tooltipText
|
|
466
|
+
isHovered = false
|
|
404
467
|
}
|
|
405
468
|
|
|
406
469
|
export default ZeroTooltip
|