|
1 | 1 | <script>
|
2 | 2 | import { onMount, onDestroy } from 'svelte';
|
| 3 | + import { formatVariableKey, getMinWidth, isInViewport } from './helpers'; |
| 4 | + import { inverse } from './constants'; |
3 | 5 |
|
4 | 6 | export let content = '';
|
5 | 7 | export let align = 'left';
|
|
14 | 16 | let ref = null;
|
15 | 17 | let minWidth = 0;
|
16 | 18 | let component = null;
|
17 |
| -
|
18 |
| - const inverse = { |
19 |
| - left: 'right', |
20 |
| - right: 'left', |
21 |
| - top: 'bottom', |
22 |
| - bottom: 'top' |
23 |
| - }; |
24 |
| -
|
25 |
| - const isInViewport = () => { |
26 |
| - const rect = ref.getBoundingClientRect(); |
27 |
| -
|
28 |
| - return ( |
29 |
| - rect.top >= 0 && |
30 |
| - rect.left >= 0 && |
31 |
| - rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && |
32 |
| - rect.right <= (window.innerWidth || document.documentElement.clientWidth) |
33 |
| - ); |
34 |
| - }; |
| 19 | + let animationEffect = null; |
| 20 | + let show = false; |
35 | 21 |
|
36 | 22 | onMount(() => {
|
| 23 | + const delay = animation ? 200 : 0; |
| 24 | +
|
37 | 25 | if (ref !== null) {
|
38 | 26 | if (isComponent && !component) {
|
39 | 27 | component = new content.component({ target: ref, props: content.props });
|
40 | 28 | }
|
41 | 29 |
|
42 |
| - const elementWidth = ref.getBoundingClientRect().width; |
43 |
| - const elementStyle = window.getComputedStyle(ref); |
44 |
| - const elementPaddingLeft = parseInt(elementStyle.getPropertyValue('padding-left'), 10); |
45 |
| - const elementPaddingRight = parseInt(elementStyle.getPropertyValue('padding-right'), 10); |
46 |
| - const elementPadding = elementPaddingLeft + elementPaddingRight; |
47 |
| - const contentWidth = elementWidth - elementPadding; |
48 |
| -
|
49 |
| - minWidth = Math.round(Math.min(maxWidth, contentWidth)); |
| 30 | + minWidth = getMinWidth(ref, maxWidth); |
50 | 31 |
|
51 | 32 | if (style && typeof style === 'object') {
|
52 | 33 | for (let prop in style) {
|
| 34 | + const key = formatVariableKey(prop); |
53 | 35 | const value = style[prop];
|
54 |
| - const key = prop |
55 |
| - .replace(/-_$/g, '') |
56 |
| - .replace(/([a-z0-9])([A-Z])/g, '$1-$2') |
57 |
| - .replace(/([A-Z])([A-Z])(?=[a-z])/g, '$1-$2') |
58 |
| - .toLowerCase(); |
59 | 36 |
|
60 | 37 | ref.style.setProperty(`--tooltip-${key}`, value);
|
61 | 38 | }
|
62 | 39 | }
|
63 | 40 | }
|
64 | 41 |
|
65 |
| - if (autoPosition && !isInViewport()) { |
| 42 | + if (autoPosition && !isInViewport(ref)) { |
66 | 43 | position = inverse[position];
|
67 | 44 | }
|
68 | 45 |
|
69 |
| - ref.classList.add('show'); |
| 46 | + if (animation) { |
| 47 | + animationEffect = animation; |
| 48 | + } |
| 49 | +
|
| 50 | + setTimeout(() => (show = true), delay); |
70 | 51 | });
|
71 | 52 |
|
72 | 53 | onDestroy(() => {
|
|
81 | 62 |
|
82 | 63 | <div
|
83 | 64 | bind:this={ref}
|
84 |
| - class="tooltip animation-{animation} {position} {theme}" |
| 65 | + class="tooltip animation-{animationEffect} {position} {theme}" |
| 66 | + class:show |
85 | 67 | class:arrowless={!arrow}
|
86 | 68 | style="min-width: {minWidth}px; max-width: {maxWidth}px; text-align: {align};"
|
87 | 69 | >
|
|
121 | 103 | box-shadow: var(--tooltip-box-shadow);
|
122 | 104 | border-radius: var(--tooltip-border-radius);
|
123 | 105 | color: var(--tooltip-color);
|
| 106 | + opacity: 0; |
124 | 107 | font-family: var(--tooltip-font-family);
|
125 | 108 | font-size: var(--tooltip-font-size);
|
126 | 109 | font-style: normal;
|
|
129 | 112 | padding: var(--tooltip-padding);
|
130 | 113 | position: absolute;
|
131 | 114 | text-align: left;
|
| 115 | + visibility: hidden; |
132 | 116 | white-space: nowrap;
|
133 | 117 | z-index: var(--tooltip-z-index);
|
134 | 118 | }
|
135 | 119 |
|
136 | 120 | .tooltip.show {
|
| 121 | + opacity: 1; |
| 122 | + visibility: visible; |
137 | 123 | white-space: normal;
|
138 | 124 | }
|
139 | 125 |
|
|
210 | 196 |
|
211 | 197 | .tooltip.animation-fade {
|
212 | 198 | opacity: 0;
|
213 |
| - transition: opacity 0.3s ease-in-out; |
| 199 | + transition: opacity 0.25s ease-in-out; |
214 | 200 | }
|
215 | 201 |
|
216 | 202 | .tooltip.animation-fade.show {
|
|
222 | 208 | .tooltip.top.animation-slide {
|
223 | 209 | margin-top: 10px;
|
224 | 210 | opacity: 0;
|
225 |
| - transition: opacity 0.3s ease-in-out, margin 0.3s ease-in-out; |
| 211 | + transition: opacity 0.25s ease-in-out, margin 0.25s ease-in-out; |
226 | 212 | }
|
227 | 213 |
|
228 | 214 | .tooltip.top.animation-slide.show {
|
|
233 | 219 | .tooltip.bottom.animation-slide {
|
234 | 220 | margin-bottom: 20px;
|
235 | 221 | opacity: 0;
|
236 |
| - transition: opacity 0.3s ease-in-out, margin 0.3s ease-in-out; |
| 222 | + transition: opacity 0.25s ease-in-out, margin 0.25s ease-in-out; |
237 | 223 | }
|
238 | 224 |
|
239 | 225 | .tooltip.bottom.animation-slide.show {
|
|
244 | 230 | .tooltip.right.animation-slide {
|
245 | 231 | margin-right: 20px;
|
246 | 232 | opacity: 0;
|
247 |
| - transition: opacity 0.3s ease-in-out, margin 0.3s ease-in-out; |
| 233 | + transition: opacity 0.25s ease-in-out, margin 0.25s ease-in-out; |
248 | 234 | }
|
249 | 235 |
|
250 | 236 | .tooltip.right.animation-slide.show {
|
|
255 | 241 | .tooltip.left.animation-slide {
|
256 | 242 | margin-left: 20px;
|
257 | 243 | opacity: 0;
|
258 |
| - transition: opacity 0.3s ease-in-out, margin 0.3s ease-in-out; |
| 244 | + transition: opacity 0.25s ease-in-out, margin 0.25s ease-in-out; |
259 | 245 | }
|
260 | 246 |
|
261 | 247 | .tooltip.left.animation-slide.show {
|
|
270 | 256 | opacity: 0;
|
271 | 257 | transform: translate(calc(-100% - var(--tooltip-offset-x)), -50%) scale(2, 2);
|
272 | 258 | transform-origin: 50% 50%;
|
273 |
| - transition: opacity 0.3s ease-in-out, filter 0.3s ease-in-out, transform 0.3s ease-in-out; |
| 259 | + transition: opacity 0.25s ease-in-out, filter 0.25s ease-in-out, transform 0.25s ease-in-out; |
274 | 260 | }
|
275 | 261 |
|
276 | 262 | .tooltip.left.animation-puff.show {
|
|
284 | 270 | opacity: 0;
|
285 | 271 | transform: translate(calc(100% + var(--tooltip-offset-x)), -50%) scale(2, 2);
|
286 | 272 | transform-origin: 50% 50%;
|
287 |
| - transition: opacity 0.3s ease-in-out, filter 0.3s ease-in-out, transform 0.3s ease-in-out; |
| 273 | + transition: opacity 0.25s ease-in-out, filter 0.25s ease-in-out, transform 0.25s ease-in-out; |
288 | 274 | }
|
289 | 275 |
|
290 | 276 | .tooltip.right.animation-puff.show {
|
|
298 | 284 | opacity: 0;
|
299 | 285 | transform: translate(-50%, calc(-100% - var(--tooltip-offset-y))) scale(2, 2);
|
300 | 286 | transform-origin: 50% 50%;
|
301 |
| - transition: opacity 0.3s ease-in-out, filter 0.3s ease-in-out, transform 0.3s ease-in-out; |
| 287 | + transition: opacity 0.25s ease-in-out, filter 0.25s ease-in-out, transform 0.25s ease-in-out; |
302 | 288 | }
|
303 | 289 |
|
304 | 290 | .tooltip.top.animation-puff.show {
|
|
312 | 298 | opacity: 0;
|
313 | 299 | transform: translate(-50%, calc(100% + var(--tooltip-offset-y))) scale(2, 2);
|
314 | 300 | transform-origin: 50% 50%;
|
315 |
| - transition: opacity 0.3s ease-in-out, filter 0.3s ease-in-out, transform 0.3s ease-in-out; |
| 301 | + transition: opacity 0.25s ease-in-out, filter 0.25s ease-in-out, transform 0.25s ease-in-out; |
316 | 302 | }
|
317 | 303 |
|
318 | 304 | .tooltip.bottom.animation-puff.show {
|
|
327 | 313 | opacity: 0;
|
328 | 314 | transform: translate(calc(-100% - var(--tooltip-offset-x)), -50%) scale(1.2, 1.2);
|
329 | 315 | transform-origin: 50% 50%;
|
330 |
| - transition: opacity 0.3s ease-in-out, transform 0.3s cubic-bezier(0.5, -1, 0.5, 3); |
| 316 | + transition: opacity 0.25s ease-in-out, transform 0.25s cubic-bezier(0.5, -1, 0.5, 3); |
331 | 317 | }
|
332 | 318 |
|
333 | 319 | .tooltip.left.animation-bounce.show {
|
|
339 | 325 | opacity: 0;
|
340 | 326 | transform: translate(calc(100% + var(--tooltip-offset-x)), -50%) scale(1.2, 1.2);
|
341 | 327 | transform-origin: 50% 50%;
|
342 |
| - transition: opacity 0.3s ease-in-out, transform 0.3s cubic-bezier(0.5, -1, 0.5, 3); |
| 328 | + transition: opacity 0.25s ease-in-out, transform 0.25s cubic-bezier(0.5, -1, 0.5, 3); |
343 | 329 | }
|
344 | 330 |
|
345 | 331 | .tooltip.right.animation-bounce.show {
|
|
351 | 337 | opacity: 0;
|
352 | 338 | transform: translate(-50%, calc(-100% - var(--tooltip-offset-y))) scale(1.2, 1.2);
|
353 | 339 | transform-origin: 50% 50%;
|
354 |
| - transition: opacity 0.3s ease-in-out, transform 0.3s cubic-bezier(0.5, -1, 0.5, 3); |
| 340 | + transition: opacity 0.25s ease-in-out, transform 0.25s cubic-bezier(0.5, -1, 0.5, 3); |
355 | 341 | }
|
356 | 342 |
|
357 | 343 | .tooltip.top.animation-bounce.show {
|
|
363 | 349 | opacity: 0;
|
364 | 350 | transform: translate(-50%, calc(100% + var(--tooltip-offset-y))) scale(1.2, 1.2);
|
365 | 351 | transform-origin: 50% 50%;
|
366 |
| - transition: opacity 0.3s ease-in-out, transform 0.3s cubic-bezier(0.5, -1, 0.5, 3); |
| 352 | + transition: opacity 0.25s ease-in-out, transform 0.25s cubic-bezier(0.5, -1, 0.5, 3); |
367 | 353 | }
|
368 | 354 |
|
369 | 355 | .tooltip.bottom.animation-bounce.show {
|
|
0 commit comments