lutra 0.1.59 → 0.1.60
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.
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/** Tracks if any tooltip is currently showing (for immediate show on warm hover) */
|
|
3
|
+
let tooltipWarm = $state(false);
|
|
4
|
+
let warmTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
5
|
+
const WARM_DURATION = 400; // ms to stay "warm" after leaving a tooltip
|
|
6
|
+
|
|
7
|
+
function setWarm() {
|
|
8
|
+
tooltipWarm = true;
|
|
9
|
+
if (warmTimeout) clearTimeout(warmTimeout);
|
|
10
|
+
warmTimeout = null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function startCooldown() {
|
|
14
|
+
if (warmTimeout) clearTimeout(warmTimeout);
|
|
15
|
+
warmTimeout = setTimeout(() => {
|
|
16
|
+
tooltipWarm = false;
|
|
17
|
+
warmTimeout = null;
|
|
18
|
+
}, WARM_DURATION);
|
|
19
|
+
}
|
|
20
|
+
</script>
|
|
21
|
+
|
|
1
22
|
<script lang="ts">
|
|
2
23
|
import Theme from "./Theme.svelte";
|
|
3
24
|
import type { Snippet } from "svelte";
|
|
@@ -5,6 +26,7 @@
|
|
|
5
26
|
/**
|
|
6
27
|
* A tooltip using CSS Anchor Positioning for automatic overflow handling.
|
|
7
28
|
* Displays on hover (with delay) or focus (immediate).
|
|
29
|
+
* Supports "warming" - if a tooltip was recently shown, new tooltips appear instantly.
|
|
8
30
|
* @supports prefers-reduced-motion
|
|
9
31
|
* @cssprop --delay - Hover delay before showing (default: 0.5s)
|
|
10
32
|
*/
|
|
@@ -23,9 +45,30 @@
|
|
|
23
45
|
|
|
24
46
|
const id = crypto.randomUUID();
|
|
25
47
|
const anchorName = `--tooltip-${id}`;
|
|
48
|
+
|
|
49
|
+
let hovering = $state(false);
|
|
50
|
+
|
|
51
|
+
function handleMouseEnter() {
|
|
52
|
+
hovering = true;
|
|
53
|
+
setWarm();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function handleMouseLeave() {
|
|
57
|
+
hovering = false;
|
|
58
|
+
startCooldown();
|
|
59
|
+
}
|
|
26
60
|
</script>
|
|
27
61
|
|
|
28
|
-
<span
|
|
62
|
+
<span
|
|
63
|
+
class="Tooltip"
|
|
64
|
+
class:open
|
|
65
|
+
class:warm={tooltipWarm}
|
|
66
|
+
class:hovering
|
|
67
|
+
role="group"
|
|
68
|
+
style="anchor-name: {anchorName};"
|
|
69
|
+
onmouseenter={handleMouseEnter}
|
|
70
|
+
onmouseleave={handleMouseLeave}
|
|
71
|
+
>
|
|
29
72
|
<span
|
|
30
73
|
class="TooltipContent"
|
|
31
74
|
id={id}
|
|
@@ -88,9 +131,13 @@
|
|
|
88
131
|
align-items: center;
|
|
89
132
|
}
|
|
90
133
|
|
|
91
|
-
.Tooltip
|
|
134
|
+
.Tooltip.hovering:not(.open) .TooltipContent {
|
|
92
135
|
opacity: 1;
|
|
93
|
-
transition-delay: var(--delay, 0.
|
|
136
|
+
transition-delay: var(--delay, 0.4s);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.Tooltip.hovering.warm:not(.open) .TooltipContent {
|
|
140
|
+
transition-delay: 0s;
|
|
94
141
|
}
|
|
95
142
|
|
|
96
143
|
.Tooltip:has(.TooltipTrigger:focus-within) .TooltipContent {
|