zero-tooltip 0.0.9 → 1.0.1
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 +2 -2
- package/dist/index.d.ts +20 -16
- package/dist/styles.css +1 -1
- package/dist/zero-tooltip.js +119 -81
- package/dist/zero-tooltip.umd.cjs +1 -1
- package/package.json +2 -3
- package/src/composables/useHideOnScroll.ts +49 -0
- package/src/index.ts +9 -2
- package/src/tooltip.ts +103 -64
- package/src/types/tooltipConfig.ts +19 -0
- package/src/types/tooltipLocalConfig.ts +7 -0
- package/src/types/tooltipPositions.ts +4 -4
- package/src/types/config.ts +0 -19
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ Default position for tooltip is above/on top of the element that is being hovere
|
|
|
43
43
|
<button v-tooltip:right="'Submits this form'">Submit</button>
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
Acceptable arguments are: `left` | `top` | `right` | `bottom`
|
|
46
|
+
Acceptable arguments are: `left` | `top` | `right` | `bottom`. Passing this argument locally, it overrides default tooltip position given as `defaultPosition` when registering directive at the app level.
|
|
47
47
|
|
|
48
48
|
You can also define default position globally when registering directive at the app level:
|
|
49
49
|
|
|
@@ -77,7 +77,7 @@ All above settings are optional.
|
|
|
77
77
|
| Property | <div style="width:260px">Default value</div> | Type | Details |
|
|
78
78
|
|---|---|---|---|
|
|
79
79
|
| defaultPosition | *top* | TooltipPosition | Postion of tooltip component relative to element that is being hovered |
|
|
80
|
-
| positions | *{ <br>  
|
|
80
|
+
| positions | *{ <br>   left: ['left', 'right', 'top', 'bottom'], <br>   top: ['top', 'bottom', 'right', 'left'], <br>   right: ['right', 'left', 'top', 'bottom'], <br>   bottom: ['bottom', 'top', 'right', 'left'], <br> }* | TooltipPositions | Ordered list of fallback positions in case tooltip does not have enough space in default position. If none of given positions will have enough space for tooltip, then it will not be rendered. |
|
|
81
81
|
| offsetFromSource | *10* | number | Tooltip offset in `px` from element that's being hovered *(arrow size is not added to this value)* |
|
|
82
82
|
| offsetFromViewport | *20* | number | Minimal allowed tooltip offset in `px` from viewports sides |
|
|
83
83
|
| minWidth | *100* | number | Minimal tooltip width in `px` that will be allowed to render |
|
package/dist/index.d.ts
CHANGED
|
@@ -4,27 +4,31 @@ declare const ZeroTooltip: (config?: ZeroTooltipConfig) => Directive;
|
|
|
4
4
|
export default ZeroTooltip;
|
|
5
5
|
|
|
6
6
|
export declare type ZeroTooltipConfig = {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
7
|
+
defaultPosition?: ZeroTooltipPosition;
|
|
8
|
+
positions?: Partial<ZeroTooltipPositions>;
|
|
9
|
+
offsetFromSource?: number;
|
|
10
|
+
offsetFromViewport?: number;
|
|
11
|
+
minWidth?: number;
|
|
12
|
+
maxWidth?: number;
|
|
13
|
+
tooltipBorderWidth?: number;
|
|
14
|
+
tooltipClasses?: string;
|
|
15
|
+
textClasses?: string;
|
|
16
|
+
arrowSize?: number;
|
|
17
|
+
arrowClasses?: string;
|
|
18
|
+
arrowMinOffsetFromTooltipCorner?: number;
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
export declare type ZeroTooltipLocalConfig = {
|
|
22
|
+
content: string;
|
|
23
|
+
} & ZeroTooltipConfig;
|
|
24
|
+
|
|
21
25
|
export declare type ZeroTooltipPosition = 'left' | 'top' | 'right' | 'bottom';
|
|
22
26
|
|
|
23
27
|
export declare type ZeroTooltipPositions = {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
left: [ZeroTooltipPosition, ZeroTooltipPosition, ZeroTooltipPosition, ZeroTooltipPosition];
|
|
29
|
+
top: [ZeroTooltipPosition, ZeroTooltipPosition, ZeroTooltipPosition, ZeroTooltipPosition];
|
|
30
|
+
right: [ZeroTooltipPosition, ZeroTooltipPosition, ZeroTooltipPosition, ZeroTooltipPosition];
|
|
31
|
+
bottom: [ZeroTooltipPosition, ZeroTooltipPosition, ZeroTooltipPosition, ZeroTooltipPosition];
|
|
28
32
|
};
|
|
29
33
|
|
|
30
34
|
export { }
|
package/dist/styles.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
/*! tailwindcss v3.3.3 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.zt-absolute{position:absolute}.zt-box-border{box-sizing:border-box}.zt-inline-block{display:inline-block}.zt-w-fit{width:-moz-fit-content;width:fit-content}.zt-whitespace-pre-wrap{white-space:pre-wrap}.zt-break-words{overflow-wrap:break-word}.zt-rounded-md{border-radius:.375rem}.zt-border-solid{border-style:solid}.zt-border-\[\#495057\]{--tw-border-opacity:1;border-color:rgb(73 80 87/var(--tw-border-opacity))}
|
|
1
|
+
/*! tailwindcss v3.3.3 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.zt-fixed{position:fixed}.zt-absolute{position:absolute}.zt-box-border{box-sizing:border-box}.zt-inline-block{display:inline-block}.zt-h-\[2000px\]{height:2000px}.zt-w-fit{width:-moz-fit-content;width:fit-content}.zt-w-full{width:100%}.zt-whitespace-pre-wrap{white-space:pre-wrap}.zt-break-words{overflow-wrap:break-word}.zt-rounded-md{border-radius:.375rem}.zt-border-solid{border-style:solid}.zt-border-\[\#495057\]{--tw-border-opacity:1;border-color:rgb(73 80 87/var(--tw-border-opacity))}.\!zt-border-x-transparent{border-left-color:#0000!important;border-right-color:#0000!important}.\!zt-border-y-transparent{border-top-color:#0000!important}.\!zt-border-b-transparent,.\!zt-border-y-transparent{border-bottom-color:#0000!important}.\!zt-border-l-transparent{border-left-color:#0000!important}.\!zt-border-r-transparent{border-right-color:#0000!important}.\!zt-border-t-transparent{border-top-color:#0000!important}.zt-bg-\[\#495057\]{--tw-bg-opacity:1;background-color:rgb(73 80 87/var(--tw-bg-opacity))}.zt-bg-gray-200{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity))}.zt-px-2{padding-left:.5rem;padding-right:.5rem}.zt-px-2\.5{padding-left:.625rem;padding-right:.625rem}.zt-py-1{padding-top:.25rem;padding-bottom:.25rem}.zt-py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.zt-text-sm{font-size:.875rem;line-height:1.25rem}.zt-text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.zt-opacity-0{opacity:0}.zt-shadow-\[0_2px_12px_0_rgba\(0\,0\,0\,0\.1\)\]{--tw-shadow:0 2px 12px 0 #0000001a;--tw-shadow-colored:0 2px 12px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
|
package/dist/zero-tooltip.js
CHANGED
|
@@ -1,125 +1,163 @@
|
|
|
1
|
-
|
|
1
|
+
function K() {
|
|
2
|
+
let e = [];
|
|
3
|
+
const w = (u, h) => {
|
|
4
|
+
if (m(u), e.length > 0)
|
|
5
|
+
for (const p of e)
|
|
6
|
+
p.addEventListener("scroll", h);
|
|
7
|
+
window.addEventListener("scroll", () => {
|
|
8
|
+
h(), s(h);
|
|
9
|
+
});
|
|
10
|
+
}, m = (u) => {
|
|
11
|
+
let h = u;
|
|
12
|
+
for (; h !== null && h.tagName !== "HTML"; ) {
|
|
13
|
+
if (h.scrollHeight !== h.clientHeight) {
|
|
14
|
+
const p = window.getComputedStyle(h);
|
|
15
|
+
(p.overflow === "auto" || p.overflow === "scroll") && e.push(h);
|
|
16
|
+
}
|
|
17
|
+
h = h.parentElement;
|
|
18
|
+
}
|
|
19
|
+
}, s = (u) => {
|
|
20
|
+
if (e.length > 0) {
|
|
21
|
+
for (const h of e)
|
|
22
|
+
h.removeEventListener("scroll", u);
|
|
23
|
+
e = [];
|
|
24
|
+
}
|
|
25
|
+
window.removeEventListener("scroll", u);
|
|
26
|
+
};
|
|
27
|
+
return { handleHideOnScroll: w };
|
|
28
|
+
}
|
|
29
|
+
const { handleHideOnScroll: Q } = K(), L = "zero-tooltip__container", U = "zero-tooltip__text", q = "zero-tooltip__arrow", W = {
|
|
2
30
|
left: ["left", "right", "top", "bottom"],
|
|
3
31
|
top: ["top", "bottom", "right", "left"],
|
|
4
32
|
right: ["right", "left", "top", "bottom"],
|
|
5
33
|
bottom: ["bottom", "top", "right", "left"]
|
|
6
34
|
};
|
|
7
|
-
let
|
|
8
|
-
const
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
left: ((
|
|
13
|
-
top: ((
|
|
14
|
-
right: ((
|
|
15
|
-
bottom: ((
|
|
16
|
-
},
|
|
35
|
+
let _ = "top";
|
|
36
|
+
const X = 10, Y = 20, c = 100, E = 250, V = 0, R = "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", g = "zt-text-sm zt-text-white zt-whitespace-pre-wrap zt-break-words", tt = 5, et = "zt-absolute zt-border-solid zt-border-[#495057]", ot = 6, st = (e) => {
|
|
37
|
+
var b, F, O, $;
|
|
38
|
+
e != null && e.defaultPosition && (_ = e.defaultPosition);
|
|
39
|
+
let w = {
|
|
40
|
+
left: ((b = e == null ? void 0 : e.positions) == null ? void 0 : b.left) ?? W.left,
|
|
41
|
+
top: ((F = e == null ? void 0 : e.positions) == null ? void 0 : F.top) ?? W.top,
|
|
42
|
+
right: ((O = e == null ? void 0 : e.positions) == null ? void 0 : O.right) ?? W.right,
|
|
43
|
+
bottom: (($ = e == null ? void 0 : e.positions) == null ? void 0 : $.bottom) ?? W.bottom
|
|
44
|
+
}, m = (e == null ? void 0 : e.offsetFromSource) ?? X, s = (e == null ? void 0 : e.offsetFromViewport) ?? Y, u = (e == null ? void 0 : e.minWidth) ?? c, h = (e == null ? void 0 : e.maxWidth) ?? E, p = (e == null ? void 0 : e.tooltipBorderWidth) ?? V, S = L + " " + R + " " + (e == null ? void 0 : e.tooltipClasses), v = U + " " + g + " " + (e == null ? void 0 : e.textClasses), x = (e == null ? void 0 : e.arrowSize) ?? tt, n = (e == null ? void 0 : e.arrowMinOffsetFromTooltipCorner) ?? ot;
|
|
17
45
|
return {
|
|
18
|
-
mounted: (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
46
|
+
mounted: (z, T) => {
|
|
47
|
+
let y = T.arg ?? _;
|
|
48
|
+
typeof T.value != "string" && N(T.value);
|
|
49
|
+
const P = rt(T.value), M = document.createElement("p");
|
|
50
|
+
M.classList.add(...v.split(" ")), M.innerHTML = P;
|
|
51
|
+
const a = document.createElement("div");
|
|
52
|
+
a.classList.add(...S.split(" ")), a.style.borderWidth = `${p}px`, a.appendChild(M), z.addEventListener("mouseenter", () => {
|
|
53
|
+
const t = z.getBoundingClientRect(), i = document.querySelector("body");
|
|
54
|
+
i == null || i.appendChild(a);
|
|
55
|
+
let o = !1, l = y;
|
|
56
|
+
for (let r = 0; r < 4 && (l = w[y][r], l === "left" ? o = j(t) : l === "top" ? o = I(t) : l === "right" ? o = D(t) : l === "bottom" && (o = Z(t)), !o); r++)
|
|
57
|
+
;
|
|
58
|
+
o && (G(t, l), a.style.opacity = "1", Q(z, () => k()));
|
|
59
|
+
}), z.addEventListener("mouseleave", () => k());
|
|
60
|
+
function N(t) {
|
|
61
|
+
t.defaultPosition && (y = t.defaultPosition), t.positions && (w = { ...w, ...t.positions }), t.offsetFromSource && (m = t.offsetFromSource), t.offsetFromViewport && (s = t.offsetFromViewport), t.minWidth && (u = t.minWidth), t.maxWidth && (h = t.maxWidth), t.tooltipBorderWidth && (p = t.tooltipBorderWidth), t.tooltipClasses && (S = t.tooltipClasses), t.textClasses && (v = t.textClasses), t.arrowSize && (x = t.arrowSize), t.arrowMinOffsetFromTooltipCorner && (n = t.arrowMinOffsetFromTooltipCorner);
|
|
62
|
+
}
|
|
63
|
+
function j(t) {
|
|
64
|
+
const i = Math.min(t.left - m - s, h), o = t.top >= s, l = window.innerHeight - t.bottom >= s;
|
|
65
|
+
if (i < u || !o || !l)
|
|
26
66
|
return !1;
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
let
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
return
|
|
67
|
+
a.style.maxWidth = `${i}px`;
|
|
68
|
+
const r = a.getBoundingClientRect();
|
|
69
|
+
let d = t.top + t.height / 2 - r.height / 2;
|
|
70
|
+
d < s ? d = s : d + r.height > window.innerHeight - s && (d = window.innerHeight - s - r.height);
|
|
71
|
+
const f = t.left - m - r.width;
|
|
72
|
+
return t.bottom < d + n * 2 || t.top > d + r.height - n * 2 ? !1 : (a.style.top = `${d}px`, a.style.left = `${f}px`, !0);
|
|
33
73
|
}
|
|
34
|
-
function D(
|
|
35
|
-
const i = Math.min(window.innerWidth - (
|
|
36
|
-
if (i <
|
|
74
|
+
function D(t) {
|
|
75
|
+
const i = Math.min(window.innerWidth - (t.right + m) - s, h), o = t.top >= s, l = window.innerHeight - t.bottom >= s;
|
|
76
|
+
if (i < u || !o || !l)
|
|
37
77
|
return !1;
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
let
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
return
|
|
78
|
+
a.style.maxWidth = `${i}px`;
|
|
79
|
+
const r = a.getBoundingClientRect();
|
|
80
|
+
let d = t.top + t.height / 2 - r.height / 2;
|
|
81
|
+
d < s ? d = s : d + r.height > window.innerHeight - s && (d = window.innerHeight - s - r.height);
|
|
82
|
+
const f = t.right + m;
|
|
83
|
+
return t.bottom < d + n * 2 || t.top > d + r.height - n * 2 ? !1 : (a.style.top = `${d}px`, a.style.left = `${f}px`, !0);
|
|
44
84
|
}
|
|
45
|
-
function I(
|
|
46
|
-
const i = Math.min(window.innerWidth -
|
|
47
|
-
|
|
48
|
-
const o =
|
|
49
|
-
let
|
|
50
|
-
if (
|
|
85
|
+
function I(t) {
|
|
86
|
+
const i = Math.min(window.innerWidth - s * 2, h);
|
|
87
|
+
a.style.maxWidth = `${i}px`;
|
|
88
|
+
const o = a.getBoundingClientRect();
|
|
89
|
+
let l = t.top - m - o.height;
|
|
90
|
+
if (l < s)
|
|
51
91
|
return !1;
|
|
52
|
-
let
|
|
53
|
-
return
|
|
92
|
+
let r = t.left + t.width / 2 - o.width / 2;
|
|
93
|
+
return r < s ? r = s : r + o.width > window.innerWidth - s && (r = window.innerWidth - s - o.width), t.left > r + o.width - n * 2 || t.right < r + n * 2 ? !1 : (a.style.top = `${l}px`, a.style.left = `${r}px`, !0);
|
|
54
94
|
}
|
|
55
|
-
function
|
|
56
|
-
const i = Math.min(window.innerWidth -
|
|
57
|
-
|
|
58
|
-
const o =
|
|
59
|
-
let
|
|
60
|
-
if (
|
|
95
|
+
function Z(t) {
|
|
96
|
+
const i = Math.min(window.innerWidth - s * 2, h);
|
|
97
|
+
a.style.maxWidth = `${i}px`;
|
|
98
|
+
const o = a.getBoundingClientRect();
|
|
99
|
+
let l = t.bottom + m;
|
|
100
|
+
if (l + o.height > window.innerHeight - s)
|
|
61
101
|
return !1;
|
|
62
|
-
let
|
|
63
|
-
return
|
|
102
|
+
let r = t.left + t.width / 2 - o.width / 2;
|
|
103
|
+
return r < s ? r = s : r + o.width > window.innerWidth - s && (r = window.innerWidth - s - o.width), t.left > r + o.width - n * 2 || t.right < r + n * 2 ? !1 : (a.style.top = `${l}px`, a.style.left = `${r}px`, !0);
|
|
64
104
|
}
|
|
65
|
-
function
|
|
105
|
+
function G(t, i) {
|
|
66
106
|
var B;
|
|
67
|
-
const o = document.createElement("div"),
|
|
68
|
-
let
|
|
107
|
+
const o = document.createElement("div"), l = a.getBoundingClientRect(), r = Math.sin(45 * (180 / Math.PI)) * x;
|
|
108
|
+
let d = 0, f = 0, C = "";
|
|
69
109
|
switch (i) {
|
|
70
110
|
case "left":
|
|
71
|
-
|
|
111
|
+
C = "!zt-border-y-transparent !zt-border-r-transparent", d = t.top - l.top + t.height / 2 - r - p, f = l.width - p;
|
|
72
112
|
break;
|
|
73
113
|
case "top":
|
|
74
|
-
|
|
114
|
+
C = "!zt-border-x-transparent !zt-border-b-transparent", d = l.height - p, f = t.left - l.left + t.width / 2 - r - p;
|
|
75
115
|
break;
|
|
76
116
|
case "right":
|
|
77
|
-
|
|
117
|
+
C = "!zt-border-y-transparent !zt-border-l-transparent", d = t.top - l.top + t.height / 2 - r - p, f = -x * 2 - p;
|
|
78
118
|
break;
|
|
79
119
|
case "bottom":
|
|
80
|
-
|
|
120
|
+
C = "!zt-border-x-transparent !zt-border-t-transparent", d = -x * 2 - p, f = t.left - l.left + t.width / 2 - r - p;
|
|
81
121
|
break;
|
|
82
122
|
}
|
|
83
|
-
i === "left" || i === "right" ?
|
|
84
|
-
const
|
|
85
|
-
o.classList.add(...
|
|
123
|
+
i === "left" || i === "right" ? H(i, l, d) || (d = A(i, l, d)) : H(i, l, f) || (f = A(i, l, f));
|
|
124
|
+
const J = q + " " + et + " " + C + " " + (e == null ? void 0 : e.arrowClasses);
|
|
125
|
+
o.classList.add(...J.split(" ")), o.style.top = `${d}px`, o.style.left = `${f}px`, o.style.borderWidth = `${x}px`, (B = document.querySelector(`.${L}`)) == null || B.appendChild(o);
|
|
86
126
|
}
|
|
87
|
-
function
|
|
88
|
-
switch (
|
|
127
|
+
function H(t, i, o) {
|
|
128
|
+
switch (t) {
|
|
89
129
|
case "left":
|
|
90
130
|
case "right":
|
|
91
|
-
return o >
|
|
131
|
+
return o > n - p && o < i.height + p - n - x * 2;
|
|
92
132
|
case "top":
|
|
93
133
|
case "bottom":
|
|
94
|
-
return o >
|
|
134
|
+
return o > n - p && o < i.width + p - n - x * 2;
|
|
95
135
|
}
|
|
96
136
|
}
|
|
97
|
-
function
|
|
98
|
-
switch (
|
|
137
|
+
function A(t, i, o) {
|
|
138
|
+
switch (t) {
|
|
99
139
|
case "left":
|
|
100
140
|
case "right":
|
|
101
|
-
return o <
|
|
141
|
+
return o < n - p ? n - p : i.height - p - n - x * 2;
|
|
102
142
|
case "top":
|
|
103
143
|
case "bottom":
|
|
104
|
-
return o <
|
|
144
|
+
return o < n - p ? n - p : i.width - p - n - x * 2;
|
|
105
145
|
}
|
|
106
146
|
}
|
|
107
|
-
y.addEventListener("mouseenter", () => {
|
|
108
|
-
const e = y.getBoundingClientRect(), i = document.querySelector("body");
|
|
109
|
-
i == null || i.appendChild(d);
|
|
110
|
-
let o = !1, r = A;
|
|
111
|
-
for (let s = 0; s < 4 && (r = b[A][s], r === "left" ? o = q(e) : r === "top" ? o = I(e) : r === "right" ? o = D(e) : r === "bottom" && (o = N(e)), !o); s++)
|
|
112
|
-
;
|
|
113
|
-
o && (Z(e, r), d.style.opacity = "1");
|
|
114
|
-
}), y.addEventListener("mouseleave", () => c());
|
|
115
147
|
}
|
|
116
148
|
};
|
|
117
149
|
};
|
|
118
|
-
function
|
|
119
|
-
var
|
|
120
|
-
const
|
|
121
|
-
(
|
|
150
|
+
function k() {
|
|
151
|
+
var w;
|
|
152
|
+
const e = document.querySelector(`.${L}`);
|
|
153
|
+
(w = e == null ? void 0 : e.querySelector(`.${q}`)) == null || w.remove(), e == null || e.remove();
|
|
154
|
+
}
|
|
155
|
+
function rt(e) {
|
|
156
|
+
let w = "";
|
|
157
|
+
if (typeof e == "string" ? w = e : w = e.content, !w)
|
|
158
|
+
throw new Error("Please enter valid tooltip value");
|
|
159
|
+
return w;
|
|
122
160
|
}
|
|
123
161
|
export {
|
|
124
|
-
|
|
162
|
+
st as default
|
|
125
163
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(C,T){typeof exports=="object"&&typeof module<"u"?module.exports=T():typeof define=="function"&&define.amd?define(T):(C=typeof globalThis<"u"?globalThis:C||self,C.ZeroTooltip=T())})(this,function(){"use strict";function C(){let e=[];const f=(u,a)=>{if(m(u),e.length>0)for(const p of e)p.addEventListener("scroll",a);window.addEventListener("scroll",()=>{a(),s(a)})},m=u=>{let a=u;for(;a!==null&&a.tagName!=="HTML";){if(a.scrollHeight!==a.clientHeight){const p=window.getComputedStyle(a);(p.overflow==="auto"||p.overflow==="scroll")&&e.push(a)}a=a.parentElement}},s=u=>{if(e.length>0){for(const a of e)a.removeEventListener("scroll",u);e=[]}window.removeEventListener("scroll",u)};return{handleHideOnScroll:f}}const{handleHideOnScroll:T}=C(),L="zero-tooltip__container",N="zero-tooltip__text",b="zero-tooltip__arrow",z={left:["left","right","top","bottom"],top:["top","bottom","right","left"],right:["right","left","top","bottom"],bottom:["bottom","top","right","left"]};let F="top";const Z=10,D=20,I=100,G=250,J=0,K="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",Q="zt-text-sm zt-text-white zt-whitespace-pre-wrap zt-break-words",U=5,X="zt-absolute zt-border-solid zt-border-[#495057]",Y=6,c=e=>{var A,B,_,k;e!=null&&e.defaultPosition&&(F=e.defaultPosition);let f={left:((A=e==null?void 0:e.positions)==null?void 0:A.left)??z.left,top:((B=e==null?void 0:e.positions)==null?void 0:B.top)??z.top,right:((_=e==null?void 0:e.positions)==null?void 0:_.right)??z.right,bottom:((k=e==null?void 0:e.positions)==null?void 0:k.bottom)??z.bottom},m=(e==null?void 0:e.offsetFromSource)??Z,s=(e==null?void 0:e.offsetFromViewport)??D,u=(e==null?void 0:e.minWidth)??I,a=(e==null?void 0:e.maxWidth)??G,p=(e==null?void 0:e.tooltipBorderWidth)??J,$=L+" "+K+" "+(e==null?void 0:e.tooltipClasses),H=N+" "+Q+" "+(e==null?void 0:e.textClasses),x=(e==null?void 0:e.arrowSize)??U,n=(e==null?void 0:e.arrowMinOffsetFromTooltipCorner)??Y;return{mounted:(W,M)=>{let S=M.arg??F;typeof M.value!="string"&&R(M.value);const V=E(M.value),v=document.createElement("p");v.classList.add(...H.split(" ")),v.innerHTML=V;const h=document.createElement("div");h.classList.add(...$.split(" ")),h.style.borderWidth=`${p}px`,h.appendChild(v),W.addEventListener("mouseenter",()=>{const t=W.getBoundingClientRect(),i=document.querySelector("body");i==null||i.appendChild(h);let o=!1,l=S;for(let r=0;r<4&&(l=f[S][r],l==="left"?o=g(t):l==="top"?o=et(t):l==="right"?o=tt(t):l==="bottom"&&(o=ot(t)),!o);r++);o&&(rt(t,l),h.style.opacity="1",T(W,()=>O()))}),W.addEventListener("mouseleave",()=>O());function R(t){t.defaultPosition&&(S=t.defaultPosition),t.positions&&(f={...f,...t.positions}),t.offsetFromSource&&(m=t.offsetFromSource),t.offsetFromViewport&&(s=t.offsetFromViewport),t.minWidth&&(u=t.minWidth),t.maxWidth&&(a=t.maxWidth),t.tooltipBorderWidth&&(p=t.tooltipBorderWidth),t.tooltipClasses&&($=t.tooltipClasses),t.textClasses&&(H=t.textClasses),t.arrowSize&&(x=t.arrowSize),t.arrowMinOffsetFromTooltipCorner&&(n=t.arrowMinOffsetFromTooltipCorner)}function g(t){const i=Math.min(t.left-m-s,a),o=t.top>=s,l=window.innerHeight-t.bottom>=s;if(i<u||!o||!l)return!1;h.style.maxWidth=`${i}px`;const r=h.getBoundingClientRect();let d=t.top+t.height/2-r.height/2;d<s?d=s:d+r.height>window.innerHeight-s&&(d=window.innerHeight-s-r.height);const w=t.left-m-r.width;return t.bottom<d+n*2||t.top>d+r.height-n*2?!1:(h.style.top=`${d}px`,h.style.left=`${w}px`,!0)}function tt(t){const i=Math.min(window.innerWidth-(t.right+m)-s,a),o=t.top>=s,l=window.innerHeight-t.bottom>=s;if(i<u||!o||!l)return!1;h.style.maxWidth=`${i}px`;const r=h.getBoundingClientRect();let d=t.top+t.height/2-r.height/2;d<s?d=s:d+r.height>window.innerHeight-s&&(d=window.innerHeight-s-r.height);const w=t.right+m;return t.bottom<d+n*2||t.top>d+r.height-n*2?!1:(h.style.top=`${d}px`,h.style.left=`${w}px`,!0)}function et(t){const i=Math.min(window.innerWidth-s*2,a);h.style.maxWidth=`${i}px`;const o=h.getBoundingClientRect();let l=t.top-m-o.height;if(l<s)return!1;let r=t.left+t.width/2-o.width/2;return r<s?r=s:r+o.width>window.innerWidth-s&&(r=window.innerWidth-s-o.width),t.left>r+o.width-n*2||t.right<r+n*2?!1:(h.style.top=`${l}px`,h.style.left=`${r}px`,!0)}function ot(t){const i=Math.min(window.innerWidth-s*2,a);h.style.maxWidth=`${i}px`;const o=h.getBoundingClientRect();let l=t.bottom+m;if(l+o.height>window.innerHeight-s)return!1;let r=t.left+t.width/2-o.width/2;return r<s?r=s:r+o.width>window.innerWidth-s&&(r=window.innerWidth-s-o.width),t.left>r+o.width-n*2||t.right<r+n*2?!1:(h.style.top=`${l}px`,h.style.left=`${r}px`,!0)}function rt(t,i){var j;const o=document.createElement("div"),l=h.getBoundingClientRect(),r=Math.sin(45*(180/Math.PI))*x;let d=0,w=0,y="";switch(i){case"left":y="!zt-border-y-transparent !zt-border-r-transparent",d=t.top-l.top+t.height/2-r-p,w=l.width-p;break;case"top":y="!zt-border-x-transparent !zt-border-b-transparent",d=l.height-p,w=t.left-l.left+t.width/2-r-p;break;case"right":y="!zt-border-y-transparent !zt-border-l-transparent",d=t.top-l.top+t.height/2-r-p,w=-x*2-p;break;case"bottom":y="!zt-border-x-transparent !zt-border-t-transparent",d=-x*2-p,w=t.left-l.left+t.width/2-r-p;break}i==="left"||i==="right"?q(i,l,d)||(d=P(i,l,d)):q(i,l,w)||(w=P(i,l,w));const st=b+" "+X+" "+y+" "+(e==null?void 0:e.arrowClasses);o.classList.add(...st.split(" ")),o.style.top=`${d}px`,o.style.left=`${w}px`,o.style.borderWidth=`${x}px`,(j=document.querySelector(`.${L}`))==null||j.appendChild(o)}function q(t,i,o){switch(t){case"left":case"right":return o>n-p&&o<i.height+p-n-x*2;case"top":case"bottom":return o>n-p&&o<i.width+p-n-x*2}}function P(t,i,o){switch(t){case"left":case"right":return o<n-p?n-p:i.height-p-n-x*2;case"top":case"bottom":return o<n-p?n-p:i.width-p-n-x*2}}}}};function O(){var f;const e=document.querySelector(`.${L}`);(f=e==null?void 0:e.querySelector(`.${b}`))==null||f.remove(),e==null||e.remove()}function E(e){let f="";if(typeof e=="string"?f=e:f=e.content,!f)throw new Error("Please enter valid tooltip value");return f}return c});
|
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"dist",
|
|
17
17
|
"src"
|
|
18
18
|
],
|
|
19
|
-
"version": "
|
|
19
|
+
"version": "1.0.1",
|
|
20
20
|
"type": "module",
|
|
21
21
|
"scripts": {
|
|
22
22
|
"dev": "vite",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"preview": "vite preview"
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
|
-
"vue": "3.
|
|
27
|
+
"vue": "^3.0.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@rollup/plugin-typescript": "^11.1.4",
|
|
@@ -46,7 +46,6 @@
|
|
|
46
46
|
"keywords": [
|
|
47
47
|
"tooltip",
|
|
48
48
|
"vue3",
|
|
49
|
-
"tailwind",
|
|
50
49
|
"typescript"
|
|
51
50
|
],
|
|
52
51
|
"author": "Andris Paškovskis",
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
|
|
2
|
+
export default function useHideOnScroll() {
|
|
3
|
+
let scrollContainers: Array<HTMLElement> = []
|
|
4
|
+
|
|
5
|
+
const handleHideOnScroll = (anchorElement: HTMLElement, hideOverlay: () => void) => {
|
|
6
|
+
getScrollContainers(anchorElement)
|
|
7
|
+
|
|
8
|
+
if (scrollContainers.length > 0) {
|
|
9
|
+
for (const scrollContainer of scrollContainers) {
|
|
10
|
+
scrollContainer.addEventListener('scroll', hideOverlay)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
window.addEventListener('scroll', () => {
|
|
15
|
+
hideOverlay()
|
|
16
|
+
removeHideOnScrollListeners(hideOverlay)
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const getScrollContainers = (anchorElement: HTMLElement) => {
|
|
21
|
+
let currentElement: HTMLElement | null = anchorElement
|
|
22
|
+
|
|
23
|
+
while (currentElement !== null && currentElement.tagName !== 'HTML') {
|
|
24
|
+
if (currentElement.scrollHeight !== currentElement.clientHeight) {
|
|
25
|
+
const computedStyle = window.getComputedStyle(currentElement)
|
|
26
|
+
|
|
27
|
+
if (computedStyle.overflow === 'auto' || computedStyle.overflow === 'scroll') {
|
|
28
|
+
scrollContainers.push(currentElement)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
currentElement = currentElement.parentElement
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const removeHideOnScrollListeners = (hideOverlay: () => void) => {
|
|
37
|
+
if (scrollContainers.length > 0) {
|
|
38
|
+
for (const scrollContainer of scrollContainers) {
|
|
39
|
+
scrollContainer.removeEventListener('scroll', hideOverlay)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
scrollContainers = []
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
window.removeEventListener('scroll', hideOverlay)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return { handleHideOnScroll }
|
|
49
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import ZeroTooltip from "./tooltip"
|
|
2
|
-
import TooltipConfig from "./types/
|
|
2
|
+
import TooltipConfig from "./types/tooltipConfig"
|
|
3
|
+
import TooltipLocalConfig from "./types/tooltipLocalConfig"
|
|
3
4
|
import TooltipPosition from "./types/tooltipPosition"
|
|
4
5
|
import TooltipPositions from "./types/tooltipPositions"
|
|
5
6
|
|
|
6
7
|
export default ZeroTooltip
|
|
7
|
-
|
|
8
|
+
|
|
9
|
+
export type {
|
|
10
|
+
TooltipConfig as ZeroTooltipConfig,
|
|
11
|
+
TooltipPosition as ZeroTooltipPosition,
|
|
12
|
+
TooltipPositions as ZeroTooltipPositions,
|
|
13
|
+
TooltipLocalConfig as ZeroTooltipLocalConfig
|
|
14
|
+
}
|
package/src/tooltip.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { Directive } from "vue"
|
|
2
|
-
import TooltipConfig from "./types/
|
|
2
|
+
import TooltipConfig from "./types/tooltipConfig"
|
|
3
3
|
import TooltipPosition from "./types/tooltipPosition"
|
|
4
4
|
import TooltipPositions from "./types/tooltipPositions"
|
|
5
|
+
import useHideOnScroll from './composables/useHideOnScroll'
|
|
6
|
+
import TooltipLocalConfig from "./types/tooltipLocalConfig"
|
|
7
|
+
|
|
8
|
+
const { handleHideOnScroll } = useHideOnScroll()
|
|
5
9
|
|
|
6
10
|
const tooltipElementClass = 'zero-tooltip__container'
|
|
7
11
|
const textElementClass = 'zero-tooltip__text'
|
|
@@ -10,10 +14,10 @@ const arrowElementClass = 'zero-tooltip__arrow'
|
|
|
10
14
|
// For each TooltipPosition define sequence of positions that will be checked when determining where to render Tooltip
|
|
11
15
|
// Meant as fallback positions in case Tooltip do not have enough space in originally set position
|
|
12
16
|
const defaultTooltipPositions: TooltipPositions = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
left: ['left', 'right', 'top', 'bottom'],
|
|
18
|
+
top: ['top', 'bottom', 'right', 'left'],
|
|
19
|
+
right: ['right', 'left', 'top', 'bottom'],
|
|
20
|
+
bottom: ['bottom', 'top', 'right', 'left'],
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
let defaultTooltipPosition: TooltipPosition = 'top'
|
|
@@ -22,7 +26,7 @@ const defaultTooltipOffsetFromViewport = 20
|
|
|
22
26
|
const defaultTooltipMinWidth = 100
|
|
23
27
|
const defaultTooltipMaxWidth = 250
|
|
24
28
|
const defaultTooltipBorderWidth = 0
|
|
25
|
-
const defaultTooltipClasses = 'zt-
|
|
29
|
+
const defaultTooltipClasses = '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'
|
|
26
30
|
const defaultTextClasses = 'zt-text-sm zt-text-white zt-whitespace-pre-wrap zt-break-words'
|
|
27
31
|
const defaultArrowSize = 5
|
|
28
32
|
const defaultArrowClasses = 'zt-absolute zt-border-solid zt-border-[#495057]'
|
|
@@ -34,38 +38,94 @@ const ZeroTooltip = (config?: TooltipConfig): Directive => {
|
|
|
34
38
|
}
|
|
35
39
|
|
|
36
40
|
// Get Tooltip config
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
let tooltipPositions: TooltipPositions = {
|
|
42
|
+
left: config?.positions?.left ?? defaultTooltipPositions.left,
|
|
43
|
+
top: config?.positions?.top ?? defaultTooltipPositions.top,
|
|
44
|
+
right: config?.positions?.right ?? defaultTooltipPositions.right,
|
|
45
|
+
bottom: config?.positions?.bottom ?? defaultTooltipPositions.bottom,
|
|
42
46
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
let tooltipOffsetFromSource = config?.offsetFromSource ?? defaultTooltipOffsetFromSource
|
|
48
|
+
let tooltipOffsetFromViewport = config?.offsetFromViewport ?? defaultTooltipOffsetFromViewport
|
|
49
|
+
let tooltipMinWidth = config?.minWidth ?? defaultTooltipMinWidth
|
|
50
|
+
let tooltipMaxWidth = config?.maxWidth ?? defaultTooltipMaxWidth
|
|
51
|
+
let tooltipBorderWidth = config?.tooltipBorderWidth ?? defaultTooltipBorderWidth
|
|
52
|
+
let tooltipClasses = tooltipElementClass + ' ' + defaultTooltipClasses + ' ' + config?.tooltipClasses ?? ''
|
|
53
|
+
let textClasses = textElementClass + ' ' + defaultTextClasses + ' ' + config?.textClasses ?? ''
|
|
54
|
+
let arrowSize = config?.arrowSize ?? defaultArrowSize
|
|
55
|
+
let arrowMinOffsetFromTooltipCorner = config?.arrowMinOffsetFromTooltipCorner ?? defaultMinArrowOffsetFromTooltipCorner
|
|
52
56
|
|
|
53
57
|
return {
|
|
54
58
|
mounted: (anchorElement: HTMLElement, binding) => {
|
|
55
59
|
// Get Tooltip position and text
|
|
56
|
-
|
|
57
|
-
|
|
60
|
+
let tooltipPosition: TooltipPosition = (binding.arg ?? defaultTooltipPosition) as TooltipPosition
|
|
61
|
+
|
|
62
|
+
if (typeof(binding.value) !== 'string') adjustTooltipSettings(binding.value)
|
|
63
|
+
|
|
64
|
+
const text: string = getTooltipText(binding.value)
|
|
58
65
|
|
|
59
66
|
// Create Text element
|
|
60
67
|
const textElement = document.createElement('p')
|
|
61
68
|
textElement.classList.add(...textClasses.split(' '))
|
|
62
|
-
textElement.
|
|
69
|
+
textElement.innerHTML = text
|
|
63
70
|
|
|
64
71
|
// Create Tooltip element
|
|
65
72
|
const tooltipElement = document.createElement('div')
|
|
66
73
|
tooltipElement.classList.add(...tooltipClasses.split(' '))
|
|
67
74
|
tooltipElement.style.borderWidth = `${tooltipBorderWidth}px`
|
|
68
75
|
tooltipElement.appendChild(textElement)
|
|
76
|
+
|
|
77
|
+
// Add listener for showing Tooltip element
|
|
78
|
+
anchorElement.addEventListener('mouseenter', () => {
|
|
79
|
+
const anchorElementRect = anchorElement.getBoundingClientRect()
|
|
80
|
+
|
|
81
|
+
// Mount Tooltip element to body
|
|
82
|
+
const body = document.querySelector('body')
|
|
83
|
+
body?.appendChild(tooltipElement)
|
|
84
|
+
|
|
85
|
+
// Find suitable Tooltip position
|
|
86
|
+
let hasNeededDisplaySpace = false
|
|
87
|
+
let currentTooltipPosition = tooltipPosition
|
|
88
|
+
for (let i = 0; i < 4; i++) {
|
|
89
|
+
currentTooltipPosition = tooltipPositions[tooltipPosition][i]
|
|
90
|
+
|
|
91
|
+
if (currentTooltipPosition === 'left') {
|
|
92
|
+
hasNeededDisplaySpace = tryMountTooltipOnLeft(anchorElementRect)
|
|
93
|
+
} else if (currentTooltipPosition === 'top') {
|
|
94
|
+
hasNeededDisplaySpace = tryMountTooltipOnTop(anchorElementRect)
|
|
95
|
+
} else if (currentTooltipPosition === 'right') {
|
|
96
|
+
hasNeededDisplaySpace = tryMountTooltipOnRight(anchorElementRect)
|
|
97
|
+
} else if (currentTooltipPosition === 'bottom') {
|
|
98
|
+
hasNeededDisplaySpace = tryMountTooltipOnBottom(anchorElementRect)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (hasNeededDisplaySpace) break
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (hasNeededDisplaySpace) {
|
|
105
|
+
drawArrow(anchorElementRect, currentTooltipPosition)
|
|
106
|
+
|
|
107
|
+
tooltipElement.style.opacity = '1'
|
|
108
|
+
handleHideOnScroll(anchorElement, () => hideTooltip())
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
// Add listener for hiding Tooltip element
|
|
113
|
+
anchorElement.addEventListener('mouseleave', () => hideTooltip())
|
|
114
|
+
|
|
115
|
+
// --- Helper functions (placed here because of variables scopes are local (don't wan to use a lot of parameters)) --- //
|
|
116
|
+
function adjustTooltipSettings(bindingValue: TooltipLocalConfig) {
|
|
117
|
+
if (bindingValue.defaultPosition) tooltipPosition = bindingValue.defaultPosition
|
|
118
|
+
if (bindingValue.positions) tooltipPositions = {...tooltipPositions, ...bindingValue.positions}
|
|
119
|
+
if (bindingValue.offsetFromSource) tooltipOffsetFromSource = bindingValue.offsetFromSource
|
|
120
|
+
if (bindingValue.offsetFromViewport) tooltipOffsetFromViewport = bindingValue.offsetFromViewport
|
|
121
|
+
if (bindingValue.minWidth) tooltipMinWidth = bindingValue.minWidth
|
|
122
|
+
if (bindingValue.maxWidth) tooltipMaxWidth = bindingValue.maxWidth
|
|
123
|
+
if (bindingValue.tooltipBorderWidth) tooltipBorderWidth = bindingValue.tooltipBorderWidth
|
|
124
|
+
if (bindingValue.tooltipClasses) tooltipClasses = bindingValue.tooltipClasses
|
|
125
|
+
if (bindingValue.textClasses) textClasses = bindingValue.textClasses
|
|
126
|
+
if (bindingValue.arrowSize) arrowSize = bindingValue.arrowSize
|
|
127
|
+
if (bindingValue.arrowMinOffsetFromTooltipCorner) arrowMinOffsetFromTooltipCorner = bindingValue.arrowMinOffsetFromTooltipCorner
|
|
128
|
+
}
|
|
69
129
|
|
|
70
130
|
function tryMountTooltipOnLeft(anchorElementRect: DOMRect) {
|
|
71
131
|
// Check if Tooltip has enough available horizontal space, top and bottom offset from viewport
|
|
@@ -216,22 +276,22 @@ const ZeroTooltip = (config?: TooltipConfig): Directive => {
|
|
|
216
276
|
|
|
217
277
|
switch (currentTooltipPosition) {
|
|
218
278
|
case "left":
|
|
219
|
-
arrowClassForCorrectAngle = 'zt-border-y-transparent zt-border-r-transparent'
|
|
279
|
+
arrowClassForCorrectAngle = '!zt-border-y-transparent !zt-border-r-transparent'
|
|
220
280
|
arrowTop = anchorElementRect.top - tooltipElementRect.top + (anchorElementRect.height / 2) - arrowHalfLengthOfLongSide - tooltipBorderWidth
|
|
221
281
|
arrowLeft = tooltipElementRect.width - tooltipBorderWidth
|
|
222
282
|
break;
|
|
223
283
|
case "top":
|
|
224
|
-
arrowClassForCorrectAngle = 'zt-border-x-transparent zt-border-b-transparent'
|
|
284
|
+
arrowClassForCorrectAngle = '!zt-border-x-transparent !zt-border-b-transparent'
|
|
225
285
|
arrowTop = tooltipElementRect.height - tooltipBorderWidth
|
|
226
286
|
arrowLeft = anchorElementRect.left - tooltipElementRect.left + (anchorElementRect.width / 2) - arrowHalfLengthOfLongSide - tooltipBorderWidth
|
|
227
287
|
break;
|
|
228
288
|
case "right":
|
|
229
|
-
arrowClassForCorrectAngle = 'zt-border-y-transparent zt-border-l-transparent'
|
|
289
|
+
arrowClassForCorrectAngle = '!zt-border-y-transparent !zt-border-l-transparent'
|
|
230
290
|
arrowTop = anchorElementRect.top - tooltipElementRect.top + (anchorElementRect.height / 2) - arrowHalfLengthOfLongSide - tooltipBorderWidth
|
|
231
291
|
arrowLeft = (-arrowSize * 2) - tooltipBorderWidth
|
|
232
292
|
break;
|
|
233
293
|
case "bottom":
|
|
234
|
-
arrowClassForCorrectAngle = 'zt-border-x-transparent zt-border-t-transparent'
|
|
294
|
+
arrowClassForCorrectAngle = '!zt-border-x-transparent !zt-border-t-transparent'
|
|
235
295
|
arrowTop = (-arrowSize * 2) - tooltipBorderWidth
|
|
236
296
|
arrowLeft = anchorElementRect.left - tooltipElementRect.left + (anchorElementRect.width / 2) - arrowHalfLengthOfLongSide - tooltipBorderWidth
|
|
237
297
|
break;
|
|
@@ -295,43 +355,6 @@ const ZeroTooltip = (config?: TooltipConfig): Directive => {
|
|
|
295
355
|
}
|
|
296
356
|
}
|
|
297
357
|
}
|
|
298
|
-
|
|
299
|
-
// Add listener for showing Tooltip element
|
|
300
|
-
anchorElement.addEventListener('mouseenter', () => {
|
|
301
|
-
const anchorElementRect = anchorElement.getBoundingClientRect()
|
|
302
|
-
|
|
303
|
-
// Mount Tooltip element to body
|
|
304
|
-
const body = document.querySelector('body')
|
|
305
|
-
body?.appendChild(tooltipElement)
|
|
306
|
-
|
|
307
|
-
// Find suitable Tooltip position
|
|
308
|
-
let hasNeededDisplaySpace = false
|
|
309
|
-
let currentTooltipPosition = tooltipPosition
|
|
310
|
-
for (let i = 0; i < 4; i++) {
|
|
311
|
-
currentTooltipPosition = tooltipPositions[tooltipPosition][i]
|
|
312
|
-
|
|
313
|
-
if (currentTooltipPosition === 'left') {
|
|
314
|
-
hasNeededDisplaySpace = tryMountTooltipOnLeft(anchorElementRect)
|
|
315
|
-
} else if (currentTooltipPosition === 'top') {
|
|
316
|
-
hasNeededDisplaySpace = tryMountTooltipOnTop(anchorElementRect)
|
|
317
|
-
} else if (currentTooltipPosition === 'right') {
|
|
318
|
-
hasNeededDisplaySpace = tryMountTooltipOnRight(anchorElementRect)
|
|
319
|
-
} else if (currentTooltipPosition === 'bottom') {
|
|
320
|
-
hasNeededDisplaySpace = tryMountTooltipOnBottom(anchorElementRect)
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
if (hasNeededDisplaySpace) break
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
if (hasNeededDisplaySpace) {
|
|
327
|
-
drawArrow(anchorElementRect, currentTooltipPosition)
|
|
328
|
-
|
|
329
|
-
tooltipElement.style.opacity = '1'
|
|
330
|
-
}
|
|
331
|
-
})
|
|
332
|
-
|
|
333
|
-
// Add listener for hiding Tooltip element
|
|
334
|
-
anchorElement.addEventListener('mouseleave', () => hideTooltip())
|
|
335
358
|
},
|
|
336
359
|
}
|
|
337
360
|
}
|
|
@@ -345,4 +368,20 @@ function hideTooltip() {
|
|
|
345
368
|
tooltipElement?.remove()
|
|
346
369
|
}
|
|
347
370
|
|
|
371
|
+
function getTooltipText(bindingValue: string | TooltipLocalConfig) {
|
|
372
|
+
let tooltipText = ''
|
|
373
|
+
|
|
374
|
+
if (typeof(bindingValue) === 'string') {
|
|
375
|
+
tooltipText = bindingValue
|
|
376
|
+
} else {
|
|
377
|
+
tooltipText = bindingValue.content
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
if (!tooltipText) {
|
|
381
|
+
throw new Error("Please enter valid tooltip value");
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
return tooltipText
|
|
385
|
+
}
|
|
386
|
+
|
|
348
387
|
export default ZeroTooltip
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import TooltipPosition from "./tooltipPosition"
|
|
2
|
+
import TooltipPositions from "./tooltipPositions"
|
|
3
|
+
|
|
4
|
+
type TooltipConfig = {
|
|
5
|
+
defaultPosition?: TooltipPosition,
|
|
6
|
+
positions?: Partial<TooltipPositions>,
|
|
7
|
+
offsetFromSource?: number,
|
|
8
|
+
offsetFromViewport?: number,
|
|
9
|
+
minWidth?: number,
|
|
10
|
+
maxWidth?: number,
|
|
11
|
+
tooltipBorderWidth?: number,
|
|
12
|
+
tooltipClasses?: string,
|
|
13
|
+
textClasses?: string,
|
|
14
|
+
arrowSize?: number,
|
|
15
|
+
arrowClasses?: string,
|
|
16
|
+
arrowMinOffsetFromTooltipCorner?: number
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default TooltipConfig
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import TooltipPosition from "./tooltipPosition"
|
|
2
2
|
|
|
3
3
|
type TooltipPositions = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
left: [ TooltipPosition, TooltipPosition, TooltipPosition, TooltipPosition]
|
|
5
|
+
top: [ TooltipPosition, TooltipPosition, TooltipPosition, TooltipPosition]
|
|
6
|
+
right: [ TooltipPosition, TooltipPosition, TooltipPosition, TooltipPosition]
|
|
7
|
+
bottom: [ TooltipPosition, TooltipPosition, TooltipPosition, TooltipPosition]
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export default TooltipPositions
|
package/src/types/config.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import TooltipPosition from "./tooltipPosition"
|
|
2
|
-
import TooltipPositions from "./tooltipPositions"
|
|
3
|
-
|
|
4
|
-
type TooltipConfig = {
|
|
5
|
-
'defaultPosition'?: TooltipPosition,
|
|
6
|
-
'positions'?: Partial<TooltipPositions>,
|
|
7
|
-
'offsetFromSource'?: number,
|
|
8
|
-
'offsetFromViewport'?: number,
|
|
9
|
-
'minWidth'?: number,
|
|
10
|
-
'maxWidth'?: number,
|
|
11
|
-
'tooltipBorderWidth'?: number,
|
|
12
|
-
'tooltipClasses'?: string,
|
|
13
|
-
'textClasses'?: string,
|
|
14
|
-
'arrowSize'?: number,
|
|
15
|
-
'arrowClasses'?: string,
|
|
16
|
-
'arrowMinOffsetFromTooltipCorner'?: number
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export default TooltipConfig
|