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 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: (config?: ZeroTooltipConfig) => Directive;
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';
@@ -1,179 +1,196 @@
1
- function Q() {
2
- let t = [];
3
- const a = (w, n) => {
4
- if (m(w), t.length > 0)
5
- for (const l of t)
6
- l.addEventListener("scroll", n);
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
- n(), s(n);
9
+ i(), d(i);
9
10
  });
10
- }, m = (w) => {
11
- let n = w;
12
- for (; n !== null && n.tagName !== "HTML"; ) {
13
- if (n.scrollHeight !== n.clientHeight) {
14
- const l = window.getComputedStyle(n);
15
- (l.overflow === "auto" || l.overflow === "scroll") && t.push(n);
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
- n = n.parentElement;
18
+ i = i.parentElement;
18
19
  }
19
- }, s = (w) => {
20
- if (t.length > 0) {
21
- for (const n of t)
22
- n.removeEventListener("scroll", w);
23
- t = [];
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", w);
26
+ window.removeEventListener("scroll", s);
26
27
  };
27
- return { handleHideOnScroll: a };
28
- }
29
- function U() {
30
- let t = null, a = null;
31
- return { handleHideOnResize: (w, n) => {
32
- t = new ResizeObserver((l) => {
33
- const W = l[0].target;
34
- if (a === null)
35
- a = w.getBoundingClientRect();
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 C = W.getBoundingClientRect();
38
- (C.left !== a.left || C.top !== a.top || C.width !== a.width || C.height !== a.height) && n();
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
- }), t.observe(w);
41
+ }), e.observe(s);
41
42
  }, resetResizeReferences: () => {
42
- t !== null && t.disconnect(), t = null, a = null;
43
+ e !== null && e.disconnect(), e = null, t = null;
43
44
  } };
44
45
  }
45
- const { handleHideOnScroll: X } = Q(), { handleHideOnResize: Y, resetResizeReferences: E } = U(), H = "zero-tooltip__container", R = "zero-tooltip__text", q = "zero-tooltip__arrow", v = {
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 = "top";
52
- const V = 10, g = 20, tt = 100, et = 250, ot = 0, rt = "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", st = "zt-text-sm zt-text-white zt-whitespace-pre-wrap zt-break-words", lt = 5, it = "zt-absolute zt-border-solid zt-border-[#495057]", pt = 6, dt = 1, at = (t) => {
53
- var F, $, A, B;
54
- t != null && t.defaultPosition && (c = t.defaultPosition);
55
- let a = {
56
- left: ((F = t == null ? void 0 : t.positions) == null ? void 0 : F.left) ?? v.left,
57
- top: (($ = t == null ? void 0 : t.positions) == null ? void 0 : $.top) ?? v.top,
58
- right: ((A = t == null ? void 0 : t.positions) == null ? void 0 : A.right) ?? v.right,
59
- bottom: ((B = t == null ? void 0 : t.positions) == null ? void 0 : B.bottom) ?? v.bottom
60
- }, m = (t == null ? void 0 : t.offsetFromSource) ?? V, s = (t == null ? void 0 : t.offsetFromViewport) ?? g, w = (t == null ? void 0 : t.minWidth) ?? tt, n = (t == null ? void 0 : t.maxWidth) ?? et, l = (t == null ? void 0 : t.tooltipBorderWidth) ?? ot, W = H + " " + rt + " " + (t == null ? void 0 : t.tooltipClasses), C = R + " " + st + " " + (t == null ? void 0 : t.textClasses), x = (t == null ? void 0 : t.arrowSize) ?? lt, f = (t == null ? void 0 : t.arrowMinOffsetFromTooltipCorner) ?? pt, b = (t == null ? void 0 : t.zIndex) ?? dt;
61
- return {
62
- mounted: (y, M) => {
63
- let L = M.arg ?? c;
64
- typeof M.value != "string" && j(M.value);
65
- const P = nt(M.value), O = document.createElement("p");
66
- O.classList.add(...C.split(" ")), O.innerHTML = P;
67
- const d = document.createElement("div");
68
- d.classList.add(...W.split(" ")), d.style.borderWidth = `${l}px`, d.appendChild(O), y.addEventListener("mouseenter", () => {
69
- const e = y.getBoundingClientRect(), i = document.querySelector("body");
70
- i == null || i.appendChild(d);
71
- let o = !1, p = L;
72
- for (let r = 0; r < 4 && (p = a[L][r], p === "left" ? o = N(e) : p === "top" ? o = D(e) : p === "right" ? o = Z(e) : p === "bottom" && (o = G(e)), !o); r++)
73
- ;
74
- o && (J(e, p), d.style.opacity = "1", d.style.zIndex = b.toString(), X(y, () => S()), Y(y, () => S()));
75
- }), y.addEventListener("mouseleave", () => S());
76
- function j(e) {
77
- e.defaultPosition && (L = e.defaultPosition), e.positions && (a = { ...a, ...e.positions }), e.offsetFromSource && (m = e.offsetFromSource), e.offsetFromViewport && (s = e.offsetFromViewport), e.minWidth && (w = e.minWidth), e.maxWidth && (n = e.maxWidth), e.tooltipBorderWidth && (l = e.tooltipBorderWidth), e.tooltipClasses && (W = e.tooltipClasses), e.textClasses && (C = e.textClasses), e.arrowSize && (x = e.arrowSize), e.arrowMinOffsetFromTooltipCorner && (f = e.arrowMinOffsetFromTooltipCorner), e.zIndex && (b = e.zIndex);
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 a;
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
- at as default
195
+ Wt as default
179
196
  };
@@ -1 +1 @@
1
- (function(y,T){typeof exports=="object"&&typeof module<"u"?module.exports=T():typeof define=="function"&&define.amd?define(T):(y=typeof globalThis<"u"?globalThis:y||self,y.ZeroTooltip=T())})(this,function(){"use strict";function y(){let t=[];const h=(w,n)=>{if(m(w),t.length>0)for(const i of t)i.addEventListener("scroll",n);window.addEventListener("scroll",()=>{n(),r(n)})},m=w=>{let n=w;for(;n!==null&&n.tagName!=="HTML";){if(n.scrollHeight!==n.clientHeight){const i=window.getComputedStyle(n);(i.overflow==="auto"||i.overflow==="scroll")&&t.push(n)}n=n.parentElement}},r=w=>{if(t.length>0){for(const n of t)n.removeEventListener("scroll",w);t=[]}window.removeEventListener("scroll",w)};return{handleHideOnScroll:h}}function T(){let t=null,h=null;return{handleHideOnResize:(w,n)=>{t=new ResizeObserver(i=>{const L=i[0].target;if(h===null)h=w.getBoundingClientRect();else{const C=L.getBoundingClientRect();(C.left!==h.left||C.top!==h.top||C.width!==h.width||C.height!==h.height)&&n()}}),t.observe(w)},resetResizeReferences:()=>{t!==null&&t.disconnect(),t=null,h=null}}}const{handleHideOnScroll:Z}=y(),{handleHideOnResize:N,resetResizeReferences:D}=T(),S="zero-tooltip__container",G="zero-tooltip__text",$="zero-tooltip__arrow",v={left:["left","right","top","bottom"],top:["top","bottom","right","left"],right:["right","left","top","bottom"],bottom:["bottom","top","right","left"]};let A="top";const J=10,K=20,Q=100,U=250,X=0,Y="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",E="zt-text-sm zt-text-white zt-whitespace-pre-wrap zt-break-words",R=5,V="zt-absolute zt-border-solid zt-border-[#495057]",g=6,tt=1,et=t=>{var _,c,k,I;t!=null&&t.defaultPosition&&(A=t.defaultPosition);let h={left:((_=t==null?void 0:t.positions)==null?void 0:_.left)??v.left,top:((c=t==null?void 0:t.positions)==null?void 0:c.top)??v.top,right:((k=t==null?void 0:t.positions)==null?void 0:k.right)??v.right,bottom:((I=t==null?void 0:t.positions)==null?void 0:I.bottom)??v.bottom},m=(t==null?void 0:t.offsetFromSource)??J,r=(t==null?void 0:t.offsetFromViewport)??K,w=(t==null?void 0:t.minWidth)??Q,n=(t==null?void 0:t.maxWidth)??U,i=(t==null?void 0:t.tooltipBorderWidth)??X,L=S+" "+Y+" "+(t==null?void 0:t.tooltipClasses),C=G+" "+E+" "+(t==null?void 0:t.textClasses),x=(t==null?void 0:t.arrowSize)??R,f=(t==null?void 0:t.arrowMinOffsetFromTooltipCorner)??g,B=(t==null?void 0:t.zIndex)??tt;return{mounted:(W,O)=>{let b=O.arg??A;typeof O.value!="string"&&rt(O.value);const st=ot(O.value),F=document.createElement("p");F.classList.add(...C.split(" ")),F.innerHTML=st;const d=document.createElement("div");d.classList.add(...L.split(" ")),d.style.borderWidth=`${i}px`,d.appendChild(F),W.addEventListener("mouseenter",()=>{const e=W.getBoundingClientRect(),l=document.querySelector("body");l==null||l.appendChild(d);let o=!1,p=b;for(let s=0;s<4&&(p=h[b][s],p==="left"?o=it(e):p==="top"?o=pt(e):p==="right"?o=lt(e):p==="bottom"&&(o=dt(e)),!o);s++);o&&(nt(e,p),d.style.opacity="1",d.style.zIndex=B.toString(),Z(W,()=>H()),N(W,()=>H()))}),W.addEventListener("mouseleave",()=>H());function rt(e){e.defaultPosition&&(b=e.defaultPosition),e.positions&&(h={...h,...e.positions}),e.offsetFromSource&&(m=e.offsetFromSource),e.offsetFromViewport&&(r=e.offsetFromViewport),e.minWidth&&(w=e.minWidth),e.maxWidth&&(n=e.maxWidth),e.tooltipBorderWidth&&(i=e.tooltipBorderWidth),e.tooltipClasses&&(L=e.tooltipClasses),e.textClasses&&(C=e.textClasses),e.arrowSize&&(x=e.arrowSize),e.arrowMinOffsetFromTooltipCorner&&(f=e.arrowMinOffsetFromTooltipCorner),e.zIndex&&(B=e.zIndex)}function it(e){const l=Math.min(e.left-m-r,n),o=e.top>=r,p=window.innerHeight-e.bottom>=r;if(l<w||!o||!p)return!1;d.style.maxWidth=`${l}px`;const s=d.getBoundingClientRect();let a=e.top+e.height/2-s.height/2;a<r?a=r:a+s.height>window.innerHeight-r&&(a=window.innerHeight-r-s.height);const u=e.left-m-s.width;return e.bottom<a+f*2||e.top>a+s.height-f*2?!1:(d.style.top=`${a}px`,d.style.left=`${u}px`,!0)}function lt(e){const l=Math.min(window.innerWidth-(e.right+m)-r,n),o=e.top>=r,p=window.innerHeight-e.bottom>=r;if(l<w||!o||!p)return!1;d.style.maxWidth=`${l}px`;const s=d.getBoundingClientRect();let a=e.top+e.height/2-s.height/2;a<r?a=r:a+s.height>window.innerHeight-r&&(a=window.innerHeight-r-s.height);const u=e.right+m;return e.bottom<a+f*2||e.top>a+s.height-f*2?!1:(d.style.top=`${a}px`,d.style.left=`${u}px`,!0)}function pt(e){const l=Math.min(window.innerWidth-r*2,n);d.style.maxWidth=`${l}px`;const o=d.getBoundingClientRect();let p=e.top-m-o.height;if(p<r)return!1;let s=e.left+e.width/2-o.width/2;return s<r?s=r:s+o.width>window.innerWidth-r&&(s=window.innerWidth-r-o.width),e.left>s+o.width-f*2||e.right<s+f*2?!1:(d.style.top=`${p}px`,d.style.left=`${s}px`,!0)}function dt(e){const l=Math.min(window.innerWidth-r*2,n);d.style.maxWidth=`${l}px`;const o=d.getBoundingClientRect();let p=e.bottom+m;if(p+o.height>window.innerHeight-r)return!1;let s=e.left+e.width/2-o.width/2;return s<r?s=r:s+o.width>window.innerWidth-r&&(s=window.innerWidth-r-o.width),e.left>s+o.width-f*2||e.right<s+f*2?!1:(d.style.top=`${p}px`,d.style.left=`${s}px`,!0)}function nt(e,l){var j;const o=document.createElement("div"),p=d.getBoundingClientRect(),s=Math.sin(45*(180/Math.PI))*x,a=1;let u=0,z=0,M="";switch(l){case"left":M="!zt-border-y-transparent !zt-border-r-transparent",u=e.top-p.top+e.height/2-s-i,z=p.width-i-a;break;case"top":M="!zt-border-x-transparent !zt-border-b-transparent",u=p.height-i-a,z=e.left-p.left+e.width/2-s-i;break;case"right":M="!zt-border-y-transparent !zt-border-l-transparent",u=e.top-p.top+e.height/2-s-i,z=-x*2-i+a;break;case"bottom":M="!zt-border-x-transparent !zt-border-t-transparent",u=-x*2-i+a,z=e.left-p.left+e.width/2-s-i;break}l==="left"||l==="right"?q(l,p,u)||(u=P(l,p,u)):q(l,p,z)||(z=P(l,p,z));const ht=$+" "+V+" "+M+" "+(t==null?void 0:t.arrowClasses);o.classList.add(...ht.split(" ")),o.style.top=`${u}px`,o.style.left=`${z}px`,o.style.borderWidth=`${x}px`,(j=document.querySelector(`.${S}`))==null||j.appendChild(o)}function q(e,l,o){switch(e){case"left":case"right":return o>f-i&&o<l.height+i-f-x*2;case"top":case"bottom":return o>f-i&&o<l.width+i-f-x*2}}function P(e,l,o){switch(e){case"left":case"right":return o<f-i?f-i:l.height-i-f-x*2;case"top":case"bottom":return o<f-i?f-i:l.width-i-f-x*2}}}}};function H(){var h;const t=document.querySelector(`.${S}`);t&&t instanceof HTMLElement&&(D(),(h=t.querySelector(`.${$}`))==null||h.remove(),t.style.left="0",t.style.top="0",t.remove())}function ot(t){let h="";if(typeof t=="string"?h=t:h=t.content,!h)throw new Error("Please enter valid tooltip value");return h}return et});
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.3",
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
- let defaultTooltipPosition: TooltipPosition = 'top'
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
- const ZeroTooltip = (config?: TooltipConfig): Directive => {
39
- if (config?.defaultPosition) {
40
- defaultTooltipPosition = config.defaultPosition
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
- // Get Tooltip config
44
- let tooltipPositions: TooltipPositions = {
45
- left: config?.positions?.left ?? defaultTooltipPositions.left,
46
- top: config?.positions?.top ?? defaultTooltipPositions.top,
47
- right: config?.positions?.right ?? defaultTooltipPositions.right,
48
- bottom: config?.positions?.bottom ?? defaultTooltipPositions.bottom,
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
- return {
62
- mounted: (anchorElement: HTMLElement, binding) => {
63
- // Get Tooltip position and text
64
- let tooltipPosition: TooltipPosition = (binding.arg ?? defaultTooltipPosition) as TooltipPosition
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
- if (typeof(binding.value) !== 'string') adjustTooltipSettings(binding.value)
132
+ function getTooltipText(localConfig: string | TooltipLocalConfig) {
133
+ const tooltipText = typeof(localConfig) === 'string' ? localConfig : localConfig.content
67
134
 
68
- const text: string = getTooltipText(binding.value)
69
-
70
- // Create Text element
71
- const textElement = document.createElement('p')
72
- textElement.classList.add(...textClasses.split(' '))
73
- textElement.innerHTML = text
74
-
75
- // Create Tooltip element
76
- const tooltipElement = document.createElement('div')
77
- tooltipElement.classList.add(...tooltipClasses.split(' '))
78
- tooltipElement.style.borderWidth = `${tooltipBorderWidth}px`
79
- tooltipElement.appendChild(textElement)
80
-
81
- // Add listener for showing Tooltip element
82
- anchorElement.addEventListener('mouseenter', () => {
83
- const anchorElementRect = anchorElement.getBoundingClientRect()
84
-
85
- // Mount Tooltip element to body
86
- const body = document.querySelector('body')
87
- body?.appendChild(tooltipElement)
88
-
89
- // Find suitable Tooltip position
90
- let hasNeededDisplaySpace = false
91
- let currentTooltipPosition = tooltipPosition
92
- for (let i = 0; i < 4; i++) {
93
- currentTooltipPosition = tooltipPositions[tooltipPosition][i]
94
-
95
- if (currentTooltipPosition === 'left') {
96
- hasNeededDisplaySpace = tryMountTooltipOnLeft(anchorElementRect)
97
- } else if (currentTooltipPosition === 'top') {
98
- hasNeededDisplaySpace = tryMountTooltipOnTop(anchorElementRect)
99
- } else if (currentTooltipPosition === 'right') {
100
- hasNeededDisplaySpace = tryMountTooltipOnRight(anchorElementRect)
101
- } else if (currentTooltipPosition === 'bottom') {
102
- hasNeededDisplaySpace = tryMountTooltipOnBottom(anchorElementRect)
103
- }
104
-
105
- if (hasNeededDisplaySpace) break
106
- }
107
-
108
- if (hasNeededDisplaySpace) {
109
- drawArrow(anchorElementRect, currentTooltipPosition)
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
- tooltipElement.style.opacity = '1'
112
- tooltipElement.style.zIndex = zIndex.toString()
113
-
114
- handleHideOnScroll(anchorElement, () => hideTooltip())
115
- handleHideOnResize(anchorElement, () => hideTooltip())
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
- function tryMountTooltipOnLeft(anchorElementRect: DOMRect) {
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
- if (tooltipAvailableMaxWidth < tooltipMinWidth || !isAnchorElementTopLowerThanOffsetFromViewport || !isAnchorElementBottomHigherThanOffsetFromViewport) return false
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
- // Set Tooltip maxWidth
147
- tooltipElement.style.maxWidth = `${tooltipAvailableMaxWidth}px`
244
+ // Set Tooltip position
245
+ tooltipElement.style.top = `${tooltipTop}px`
246
+ tooltipElement.style.left = `${tooltipLeft}px`
148
247
 
149
- // Calculate Tooltip position
150
- const tooltipElementRect = tooltipElement.getBoundingClientRect()
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
- const tooltipLeft = anchorElementRect.left - tooltipOffsetFromSource - tooltipElementRect.width
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
- // Check if anchor element is directly on right of Tooltip
162
- if (anchorElementRect.bottom < tooltipTop + arrowMinOffsetFromTooltipCorner * 2
163
- || anchorElementRect.top > tooltipTop + tooltipElementRect.height - arrowMinOffsetFromTooltipCorner * 2) return false
257
+ if (tooltipAvailableMaxWidth < tooltipMinWidth || !isAnchorElementTopLowerThanOffsetFromViewport || !isAnchorElementBottomHigherThanOffsetFromViewport) return false
258
+
259
+ // Set tooltip maxWidth
260
+ tooltipElement.style.maxWidth = `${tooltipAvailableMaxWidth}px`
164
261
 
165
- // Set Tooltip position
166
- tooltipElement.style.top = `${tooltipTop}px`
167
- tooltipElement.style.left = `${tooltipLeft}px`
262
+ // Calculate Tooltip position
263
+ const tooltipElementRect = tooltipElement.getBoundingClientRect()
168
264
 
169
- return true
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
- function tryMountTooltipOnRight(anchorElementRect: DOMRect) {
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
- if (tooltipAvailableMaxWidth < tooltipMinWidth || !isAnchorElementTopLowerThanOffsetFromViewport || !isAnchorElementBottomHigherThanOffsetFromViewport) return false
179
-
180
- // Set tooltip maxWidth
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
- // Calculate Tooltip position
184
- const tooltipElementRect = tooltipElement.getBoundingClientRect()
279
+ // Set Tooltip position
280
+ tooltipElement.style.top = `${tooltipTop}px`
281
+ tooltipElement.style.left = `${tooltipLeft}px`
185
282
 
186
- let tooltipTop = anchorElementRect.top + (anchorElementRect.height / 2) - (tooltipElementRect.height / 2)
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
- const tooltipLeft = anchorElementRect.right + tooltipOffsetFromSource
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
- // Check if anchor element is directly on left of Tooltip
197
- if (anchorElementRect.bottom < tooltipTop + arrowMinOffsetFromTooltipCorner * 2
198
- || anchorElementRect.top > tooltipTop + tooltipElementRect.height - arrowMinOffsetFromTooltipCorner * 2) return false
291
+ // Calculate Tooltip top position
292
+ const tooltipElementRect = tooltipElement.getBoundingClientRect()
293
+ let tooltipTop = anchorElementRect.top - tooltipOffsetFromSource - tooltipElementRect.height
199
294
 
200
- // Set Tooltip position
201
- tooltipElement.style.top = `${tooltipTop}px`
202
- tooltipElement.style.left = `${tooltipLeft}px`
295
+ // Check if Tooltip has enough available on top
296
+ if (tooltipTop < tooltipOffsetFromViewport) return false
203
297
 
204
- return true
205
- }
298
+ // Calculate Tooltip left position
299
+ let tooltipLeft = anchorElementRect.left + (anchorElementRect.width / 2) - (tooltipElementRect.width / 2)
206
300
 
207
- function tryMountTooltipOnTop(anchorElementRect: DOMRect) {
208
- // Calculate and set Tooltip width
209
- const tooltipAvailableMaxWidth = Math.min(window.innerWidth - (tooltipOffsetFromViewport * 2), tooltipMaxWidth)
210
- tooltipElement.style.maxWidth = `${tooltipAvailableMaxWidth}px`
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
- // Calculate Tooltip top position
213
- const tooltipElementRect = tooltipElement.getBoundingClientRect()
214
- let tooltipTop = anchorElementRect.top - tooltipOffsetFromSource - tooltipElementRect.height
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
- // Check if Tooltip has enough available on top
217
- if (tooltipTop < tooltipOffsetFromViewport) return false
311
+ // Set Tooltip position
312
+ tooltipElement.style.top = `${tooltipTop}px`
313
+ tooltipElement.style.left = `${tooltipLeft}px`
218
314
 
219
- // Calculate Tooltip left position
220
- let tooltipLeft = anchorElementRect.left + (anchorElementRect.width / 2) - (tooltipElementRect.width / 2)
315
+ return true
316
+ }
221
317
 
222
- if (tooltipLeft < tooltipOffsetFromViewport) {
223
- tooltipLeft = tooltipOffsetFromViewport
224
- } else if (tooltipLeft + tooltipElementRect.width > window.innerWidth - tooltipOffsetFromViewport) {
225
- tooltipLeft = window.innerWidth - tooltipOffsetFromViewport - tooltipElementRect.width
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
- // Check if anchor element is directly on below of Tooltip
229
- if (anchorElementRect.left > tooltipLeft + tooltipElementRect.width - arrowMinOffsetFromTooltipCorner * 2
230
- || anchorElementRect.right < tooltipLeft + arrowMinOffsetFromTooltipCorner * 2) return false
323
+ // Calculate Tooltip top position
324
+ const tooltipElementRect = tooltipElement.getBoundingClientRect()
325
+ let tooltipTop = anchorElementRect.bottom + tooltipOffsetFromSource
231
326
 
232
- // Set Tooltip position
233
- tooltipElement.style.top = `${tooltipTop}px`
234
- tooltipElement.style.left = `${tooltipLeft}px`
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
- return true
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
- function tryMountTooltipOnBottom(anchorElementRect: DOMRect) {
240
- // Calculate and set Tooltip width
241
- const tooltipAvailableMaxWidth = Math.min(window.innerWidth - (tooltipOffsetFromViewport * 2), tooltipMaxWidth)
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
- // Calculate Tooltip top position
245
- const tooltipElementRect = tooltipElement.getBoundingClientRect()
246
- let tooltipTop = anchorElementRect.bottom + tooltipOffsetFromSource
343
+ // Set Tooltip position
344
+ tooltipElement.style.top = `${tooltipTop}px`
345
+ tooltipElement.style.left = `${tooltipLeft}px`
247
346
 
248
- // Check if Tooltip has enough available on bottom
249
- if (tooltipTop + tooltipElementRect.height > window.innerHeight - tooltipOffsetFromViewport) return false
250
-
251
- // Calculate Tooltip left position
252
- let tooltipLeft = anchorElementRect.left + (anchorElementRect.width / 2) - (tooltipElementRect.width / 2)
347
+ return true
348
+ }
253
349
 
254
- if (tooltipLeft < tooltipOffsetFromViewport) {
255
- tooltipLeft = tooltipOffsetFromViewport
256
- } else if (tooltipLeft + tooltipElementRect.width > window.innerWidth - tooltipOffsetFromViewport) {
257
- tooltipLeft = window.innerWidth - tooltipOffsetFromViewport - tooltipElementRect.width
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
- // Check if anchor element is directly on top of Tooltip
261
- if (anchorElementRect.left > tooltipLeft + tooltipElementRect.width - arrowMinOffsetFromTooltipCorner * 2
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
- // Set Tooltip position
265
- tooltipElement.style.top = `${tooltipTop}px`
266
- tooltipElement.style.left = `${tooltipLeft}px`
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
- return true
269
- }
410
+ // Mount Arrow element
411
+ document.querySelector(`.${tooltipElementClass}`)?.appendChild(arrowElement)
412
+ }
270
413
 
271
- function drawArrow(anchorElementRect: DOMRect, currentTooltipPosition: TooltipPosition) {
272
- // Create Arrow element
273
- const arrowElement = document.createElement('div')
274
-
275
- // Calculate Arrow element size, positions and style/angle classes
276
- const tooltipElementRect = tooltipElement.getBoundingClientRect()
277
- const arrowHalfLengthOfLongSide = Math.sin(45 * (180 / Math.PI)) * arrowSize
278
-
279
- // 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
280
- const arrowPositionAdjuster = 1;
281
-
282
- // Arrow top/left 0 is Tooltip top/left 0
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
- function isArrowPositionWithinLimits(currentTooltipPosition: TooltipPosition, tooltipElementRect: DOMRect, arrowPosition: number) {
335
- switch (currentTooltipPosition) {
336
- case "left":
337
- case "right":
338
- return arrowPosition > arrowMinOffsetFromTooltipCorner - tooltipBorderWidth
339
- && arrowPosition < tooltipElementRect.height + tooltipBorderWidth - arrowMinOffsetFromTooltipCorner - (arrowSize * 2)
340
- case "top":
341
- case "bottom":
342
- return arrowPosition > arrowMinOffsetFromTooltipCorner - tooltipBorderWidth
343
- && arrowPosition < tooltipElementRect.width + tooltipBorderWidth - arrowMinOffsetFromTooltipCorner - (arrowSize * 2)
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
- function getArrowPositionMinLimit(currentTooltipPosition: TooltipPosition, tooltipElementRect: DOMRect, arrowPosition: number) {
348
- switch (currentTooltipPosition) {
349
- case "left":
350
- case "right":
351
- if (arrowPosition < arrowMinOffsetFromTooltipCorner - tooltipBorderWidth) {
352
- // Arrow too close to viewport top
353
- return arrowMinOffsetFromTooltipCorner - tooltipBorderWidth
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
- function getTooltipText(bindingValue: string | TooltipLocalConfig) {
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
@@ -1,7 +1,8 @@
1
1
  import TooltipConfig from "./tooltipConfig"
2
2
 
3
3
  type TooltipLocalConfig = {
4
- content: string
4
+ content: string,
5
+ show?: boolean
5
6
  } & TooltipConfig
6
7
 
7
8
  export default TooltipLocalConfig