Skip to content

Commit b19fa51

Browse files
committed
feat(hideOnOutsideClick): update component and action to support hideOnOutsideClick
1 parent 0317028 commit b19fa51

File tree

4 files changed

+333
-80
lines changed

4 files changed

+333
-80
lines changed

src/action-tooltip.svelte

Lines changed: 138 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
<script>
22
// @ts-check
3-
43
import { onMount, onDestroy } from 'svelte';
5-
import { computeTooltipPosition, formatVariableKey, getMinWidth, isElementInViewport } from './helpers';
4+
5+
import {
6+
computeTooltipPosition,
7+
formatVariableKey,
8+
getMinWidth,
9+
isElementInViewport
10+
} from './helpers';
11+
612
import { inverse } from './constants';
713
814
/** @type {HTMLElement | null} */
@@ -59,7 +65,7 @@
5965
/** @type {boolean} */
6066
let visible = false;
6167
62-
/** @type {{ bottom: number, top: number, right: number, left: number }} */
68+
/** @type {any} */
6369
let coords = {
6470
bottom: 0,
6571
top: 0,
@@ -73,7 +79,11 @@
7379
if (tooltipRef !== null) {
7480
if (isComponent && !component) {
7581
// @ts-ignore
76-
component = new content.component({ target: tooltipRef, props: { action, ...content.props } });
82+
component = new content.component({
83+
target: tooltipRef,
84+
// @ts-ignore
85+
props: { action, ...content.props }
86+
});
7787
}
7888
7989
minWidth = getMinWidth(tooltipRef, maxWidth);
@@ -88,13 +98,21 @@
8898
}
8999
}
90100
91-
// @ts-ignore
92-
if (autoPosition && !isElementInViewport(tooltipRef, targetElement, position)) {
101+
if (
102+
autoPosition &&
103+
// @ts-ignore
104+
!isElementInViewport(tooltipRef, targetElement, position)
105+
) {
93106
// @ts-ignore
94107
position = inverse[position];
95108
}
96109
97-
coords = computeTooltipPosition(targetElement, tooltipRef, position, coords);
110+
coords = computeTooltipPosition(
111+
targetElement,
112+
tooltipRef,
113+
position,
114+
coords
115+
);
98116
99117
if (animation) {
100118
animationEffect = animation;
@@ -112,12 +130,19 @@
112130
113131
const onHandleResize = () => {
114132
if (visible) {
115-
coords = computeTooltipPosition(targetElement, tooltipRef, position, coords);
133+
coords = computeTooltipPosition(
134+
targetElement,
135+
tooltipRef,
136+
position,
137+
coords
138+
);
116139
}
117140
};
118141
119142
$: isComponent = typeof content === 'object';
120-
$: tooltipRef && show ? setTimeout(() => (visible = true), animationDelay) : (visible = false);
143+
$: tooltipRef && show
144+
? setTimeout(() => (visible = true), animationDelay)
145+
: (visible = false);
121146
</script>
122147

123148
{#if content}
@@ -146,8 +171,8 @@
146171
--tooltip-background-color: rgba(0, 0, 0, 0.9);
147172
--tooltip-border-radius: 4px;
148173
--tooltip-box-shadow: 0 1px 20px rgba(0, 0, 0, 0.25);
149-
--tooltip-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell,
150-
'Helvetica Neue', sans-serif;
174+
--tooltip-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
175+
Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;
151176
--tooltip-font-size: 14px;
152177
--tooltip-font-weight: 500;
153178
--tooltip-line-height: 1.25rem;
@@ -219,7 +244,10 @@
219244
.tooltip.bottom {
220245
bottom: 0;
221246
left: 50%;
222-
transform: translate(calc(-50% + var(--tooltip-offset-x)), calc(100% + var(--tooltip-offset-y)));
247+
transform: translate(
248+
calc(-50% + var(--tooltip-offset-x)),
249+
calc(100% + var(--tooltip-offset-y))
250+
);
223251
}
224252
225253
.tooltip.bottom:after {
@@ -232,11 +260,15 @@
232260
.tooltip.top {
233261
left: 50%;
234262
top: 0;
235-
transform: translate(calc(-50% + var(--tooltip-offset-x)), calc(-100% - var(--tooltip-offset-y)));
263+
transform: translate(
264+
calc(-50% + var(--tooltip-offset-x)),
265+
calc(-100% - var(--tooltip-offset-y))
266+
);
236267
}
237268
238269
.tooltip.top:after {
239-
border-color: var(--tooltip-background-color) transparent transparent transparent;
270+
border-color: var(--tooltip-background-color) transparent transparent
271+
transparent;
240272
bottom: 0;
241273
left: 50%;
242274
transform: translate(-50%, 99%);
@@ -245,11 +277,15 @@
245277
.tooltip.left {
246278
left: 0;
247279
top: 50%;
248-
transform: translate(calc(-100% - var(--tooltip-offset-x)), calc(-50% - var(--tooltip-offset-y)));
280+
transform: translate(
281+
calc(-100% - var(--tooltip-offset-x)),
282+
calc(-50% - var(--tooltip-offset-y))
283+
);
249284
}
250285
251286
.tooltip.left:after {
252-
border-color: transparent transparent transparent var(--tooltip-background-color);
287+
border-color: transparent transparent transparent
288+
var(--tooltip-background-color);
253289
right: 0;
254290
top: 50%;
255291
transform: translate(99%, -50%);
@@ -258,11 +294,15 @@
258294
.tooltip.right {
259295
right: 0;
260296
top: 50%;
261-
transform: translate(calc(100% + var(--tooltip-offset-x)), calc(-50% - var(--tooltip-offset-y)));
297+
transform: translate(
298+
calc(100% + var(--tooltip-offset-x)),
299+
calc(-50% - var(--tooltip-offset-y))
300+
);
262301
}
263302
264303
.tooltip.right:after {
265-
border-color: transparent var(--tooltip-background-color) transparent transparent;
304+
border-color: transparent var(--tooltip-background-color) transparent
305+
transparent;
266306
left: 0;
267307
top: 50%;
268308
transform: translate(-99%, -50%);
@@ -342,7 +382,11 @@
342382
.tooltip.left.animation-puff {
343383
filter: blur(2px);
344384
opacity: 0;
345-
transform: translate(calc(-100% - var(--tooltip-offset-x)), calc(-50% - var(--tooltip-offset-y))) scale(2, 2);
385+
transform: translate(
386+
calc(-100% - var(--tooltip-offset-x)),
387+
calc(-50% - var(--tooltip-offset-y))
388+
)
389+
scale(2, 2);
346390
transform-origin: 50% 50%;
347391
transition:
348392
opacity 0.25s ease-in-out,
@@ -353,13 +397,21 @@
353397
.tooltip.left.animation-puff.show {
354398
filter: blur(0);
355399
opacity: 1;
356-
transform: translate(calc(-100% - var(--tooltip-offset-x)), calc(-50% - var(--tooltip-offset-y))) scale(1, 1);
400+
transform: translate(
401+
calc(-100% - var(--tooltip-offset-x)),
402+
calc(-50% - var(--tooltip-offset-y))
403+
)
404+
scale(1, 1);
357405
}
358406
359407
.tooltip.right.animation-puff {
360408
filter: blur(2px);
361409
opacity: 0;
362-
transform: translate(calc(100% + var(--tooltip-offset-x)), calc(-50% - var(--tooltip-offset-y))) scale(2, 2);
410+
transform: translate(
411+
calc(100% + var(--tooltip-offset-x)),
412+
calc(-50% - var(--tooltip-offset-y))
413+
)
414+
scale(2, 2);
363415
transform-origin: 50% 50%;
364416
transition:
365417
opacity 0.25s ease-in-out,
@@ -370,13 +422,21 @@
370422
.tooltip.right.animation-puff.show {
371423
filter: blur(0);
372424
opacity: 1;
373-
transform: translate(calc(100% + var(--tooltip-offset-x)), calc(-50% - var(--tooltip-offset-y))) scale(1, 1);
425+
transform: translate(
426+
calc(100% + var(--tooltip-offset-x)),
427+
calc(-50% - var(--tooltip-offset-y))
428+
)
429+
scale(1, 1);
374430
}
375431
376432
.tooltip.top.animation-puff {
377433
filter: blur(2px);
378434
opacity: 0;
379-
transform: translate(calc(-50% + var(--tooltip-offset-x)), calc(-100% - var(--tooltip-offset-y))) scale(2, 2);
435+
transform: translate(
436+
calc(-50% + var(--tooltip-offset-x)),
437+
calc(-100% - var(--tooltip-offset-y))
438+
)
439+
scale(2, 2);
380440
transform-origin: 50% 50%;
381441
transition:
382442
opacity 0.25s ease-in-out,
@@ -387,13 +447,21 @@
387447
.tooltip.top.animation-puff.show {
388448
filter: blur(0);
389449
opacity: 1;
390-
transform: translate(calc(-50% + var(--tooltip-offset-x)), calc(-100% - var(--tooltip-offset-y))) scale(1, 1);
450+
transform: translate(
451+
calc(-50% + var(--tooltip-offset-x)),
452+
calc(-100% - var(--tooltip-offset-y))
453+
)
454+
scale(1, 1);
391455
}
392456
393457
.tooltip.bottom.animation-puff {
394458
filter: blur(2px);
395459
opacity: 0;
396-
transform: translate(calc(-50% + var(--tooltip-offset-x)), calc(100% + var(--tooltip-offset-y))) scale(2, 2);
460+
transform: translate(
461+
calc(-50% + var(--tooltip-offset-x)),
462+
calc(100% + var(--tooltip-offset-y))
463+
)
464+
scale(2, 2);
397465
transform-origin: 50% 50%;
398466
transition:
399467
opacity 0.25s ease-in-out,
@@ -404,14 +472,22 @@
404472
.tooltip.bottom.animation-puff.show {
405473
filter: blur(0);
406474
opacity: 1;
407-
transform: translate(calc(-50% + var(--tooltip-offset-x)), calc(100% + var(--tooltip-offset-y))) scale(1, 1);
475+
transform: translate(
476+
calc(-50% + var(--tooltip-offset-x)),
477+
calc(100% + var(--tooltip-offset-y))
478+
)
479+
scale(1, 1);
408480
}
409481
410482
/* Bounce */
411483
412484
.tooltip.left.animation-bounce {
413485
opacity: 0;
414-
transform: translate(calc(-100% - var(--tooltip-offset-x)), calc(-50% + var(--tooltip-offset-y))) scale(1.2, 1.2);
486+
transform: translate(
487+
calc(-100% - var(--tooltip-offset-x)),
488+
calc(-50% + var(--tooltip-offset-y))
489+
)
490+
scale(1.2, 1.2);
415491
transform-origin: 50% 50%;
416492
transition:
417493
opacity 0.25s ease-in-out,
@@ -420,12 +496,20 @@
420496
421497
.tooltip.left.animation-bounce.show {
422498
opacity: 1;
423-
transform: translate(calc(-100% - var(--tooltip-offset-x)), calc(-50% + var(--tooltip-offset-y))) scale(1, 1);
499+
transform: translate(
500+
calc(-100% - var(--tooltip-offset-x)),
501+
calc(-50% + var(--tooltip-offset-y))
502+
)
503+
scale(1, 1);
424504
}
425505
426506
.tooltip.right.animation-bounce {
427507
opacity: 0;
428-
transform: translate(calc(100% + var(--tooltip-offset-x)), calc(-50% + var(--tooltip-offset-y))) scale(1.2, 1.2);
508+
transform: translate(
509+
calc(100% + var(--tooltip-offset-x)),
510+
calc(-50% + var(--tooltip-offset-y))
511+
)
512+
scale(1.2, 1.2);
429513
transform-origin: 50% 50%;
430514
transition:
431515
opacity 0.25s ease-in-out,
@@ -434,12 +518,20 @@
434518
435519
.tooltip.right.animation-bounce.show {
436520
opacity: 1;
437-
transform: translate(calc(100% + var(--tooltip-offset-x)), calc(-50% + var(--tooltip-offset-y))) scale(1, 1);
521+
transform: translate(
522+
calc(100% + var(--tooltip-offset-x)),
523+
calc(-50% + var(--tooltip-offset-y))
524+
)
525+
scale(1, 1);
438526
}
439527
440528
.tooltip.top.animation-bounce {
441529
opacity: 0;
442-
transform: translate(calc(-50% + var(--tooltip-offset-x)), calc(-100% - var(--tooltip-offset-y))) scale(1.2, 1.2);
530+
transform: translate(
531+
calc(-50% + var(--tooltip-offset-x)),
532+
calc(-100% - var(--tooltip-offset-y))
533+
)
534+
scale(1.2, 1.2);
443535
transform-origin: 50% 50%;
444536
transition:
445537
opacity 0.25s ease-in-out,
@@ -448,12 +540,20 @@
448540
449541
.tooltip.top.animation-bounce.show {
450542
opacity: 1;
451-
transform: translate(calc(-50% + var(--tooltip-offset-x)), calc(-100% - var(--tooltip-offset-y))) scale(1, 1);
543+
transform: translate(
544+
calc(-50% + var(--tooltip-offset-x)),
545+
calc(-100% - var(--tooltip-offset-y))
546+
)
547+
scale(1, 1);
452548
}
453549
454550
.tooltip.bottom.animation-bounce {
455551
opacity: 0;
456-
transform: translate(calc(-50% + var(--tooltip-offset-x)), calc(100% + var(--tooltip-offset-y))) scale(1.2, 1.2);
552+
transform: translate(
553+
calc(-50% + var(--tooltip-offset-x)),
554+
calc(100% + var(--tooltip-offset-y))
555+
)
556+
scale(1.2, 1.2);
457557
transform-origin: 50% 50%;
458558
transition:
459559
opacity 0.25s ease-in-out,
@@ -462,6 +562,10 @@
462562
463563
.tooltip.bottom.animation-bounce.show {
464564
opacity: 1;
465-
transform: translate(calc(-50% + var(--tooltip-offset-x)), calc(100% + var(--tooltip-offset-y))) scale(1, 1);
565+
transform: translate(
566+
calc(-50% + var(--tooltip-offset-x)),
567+
calc(100% + var(--tooltip-offset-y))
568+
)
569+
scale(1, 1);
466570
}
467571
</style>

src/action.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Tooltip from './action-tooltip.svelte';
2+
import { onClickOutside } from './helpers';
23

34
export const tooltip = (element, props) => {
45
let component = null;
@@ -49,14 +50,18 @@ export const tooltip = (element, props) => {
4950

5051
if (action === 'click') {
5152
element.addEventListener('click', onClick);
53+
54+
if (config.hideOnClickOutside) {
55+
onClickOutside(element, onHide);
56+
}
5257
}
5358

5459
if (action === 'hover') {
5560
element.addEventListener('mouseenter', onShow);
5661
element.addEventListener('mouseleave', onHide);
5762
}
5863
}
59-
}
64+
};
6065

6166
const removeListeners = () => {
6267
if (element !== null) {
@@ -77,4 +82,4 @@ export const tooltip = (element, props) => {
7782
}
7883
}
7984
};
80-
}
85+
};

0 commit comments

Comments
 (0)