diff --git a/.changeset/chilled-files-poke.md b/.changeset/chilled-files-poke.md
new file mode 100644
index 000000000..d1d07c87c
--- /dev/null
+++ b/.changeset/chilled-files-poke.md
@@ -0,0 +1,5 @@
+---
+'layerchart': patch
+---
+
+Added hideDelay prop to Tooltip for configurable hide behavior
diff --git a/packages/layerchart/package.json b/packages/layerchart/package.json
index 9ba92eb33..cb7366f92 100644
--- a/packages/layerchart/package.json
+++ b/packages/layerchart/package.json
@@ -63,7 +63,7 @@
"rehype-slug": "^6.0.0",
"shapefile": "^0.6.6",
"solar-calculator": "^0.3.0",
- "svelte": "^5.19.9",
+ "svelte": "5.19.4",
"svelte-check": "^4.1.4",
"svelte-json-tree": "^2.2.0",
"svelte-ux": "^0.90.0",
diff --git a/packages/layerchart/src/lib/components/tooltip/TooltipContext.svelte b/packages/layerchart/src/lib/components/tooltip/TooltipContext.svelte
index 5ac927f55..9ad6b4a0f 100644
--- a/packages/layerchart/src/lib/components/tooltip/TooltipContext.svelte
+++ b/packages/layerchart/src/lib/components/tooltip/TooltipContext.svelte
@@ -101,7 +101,7 @@
/** Similar to d3-selection's raise, re-insert the e.target as the last child of its parent, so to be the top-most element */
export let raiseTarget = false;
- /** Lock tooltip (keep open, do not update on mouse movement). Allows for kicking on tooltip */
+ /** Lock tooltip (keep open, do not update on mouse movement). Allows for clicking on tooltip */
export let locked = false;
/** quadtree search radius
@@ -124,6 +124,10 @@
});
setTooltipContext(tooltip);
+ /** Delay in ms before hiding tooltip */
+ export let hideDelay = 0;
+
+ let isHoveringTooltip = false;
let hideTimeoutId: NodeJS.Timeout;
$: bisectX = bisector((d: any) => {
@@ -175,7 +179,9 @@
function showTooltip(e: PointerEvent, tooltipData?: any) {
// Cancel hiding tooltip if from previous event loop
- clearTimeout(hideTimeoutId);
+ if (hideTimeoutId) {
+ clearTimeout(hideTimeoutId);
+ }
if (locked) {
// Ignore (keep current position / data)
@@ -294,9 +300,12 @@
}
// Wait an event loop tick in case `showTooltip` is called immediately on another element, to allow tweeneing (ex. moving between bands/bars)
+ // Additional hideDelay can be configured to extend this delay further
hideTimeoutId = setTimeout(() => {
- $tooltip = { ...$tooltip, data: null };
- });
+ if (!isHoveringTooltip) {
+ $tooltip = { ...$tooltip, data: null };
+ }
+ }, hideDelay);
}
let quadtree: Quadtree<[number, number]>;
@@ -401,9 +410,19 @@
'TooltipContext absolute touch-none',
debug && triggerPointerEvents && 'bg-danger/10 outline outline-danger'
)}
- on:pointerenter={triggerPointerEvents ? showTooltip : undefined}
+ on:pointerenter={(e) => {
+ isHoveringTooltip = true;
+ if (triggerPointerEvents) {
+ showTooltip(e);
+ }
+ }}
on:pointermove={triggerPointerEvents ? showTooltip : undefined}
- on:pointerleave={triggerPointerEvents ? hideTooltip : undefined}
+ on:pointerleave={(e) => {
+ isHoveringTooltip = false;
+ if (triggerPointerEvents) {
+ hideTooltip();
+ }
+ }}
on:click={(e) => {
if (triggerPointerEvents) {
onclick(e, { data: $tooltip?.data });
diff --git a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte
index 5f94d1798..d39efca8a 100644
--- a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte
+++ b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte
@@ -860,6 +860,43 @@
+
Fixed tooltip below chart with hide delay
+
+
+
+
+
+
+
+ {format(x(data), PeriodType.Day)}
+
+
+
+ {#each series as s}
+ {@const valueAccessor = accessor(s.value ?? s.key)}
+ {@const value = valueAccessor(data)}
+
+ {format(value)}
+
+ {/each}
+
+
+
+
+
+
+
Brushing
diff --git a/packages/layerchart/src/routes/docs/components/Tooltip/+page.ts b/packages/layerchart/src/routes/docs/components/Tooltip/+page.ts
index 517b9e35d..4f53cbfce 100644
--- a/packages/layerchart/src/routes/docs/components/Tooltip/+page.ts
+++ b/packages/layerchart/src/routes/docs/components/Tooltip/+page.ts
@@ -27,6 +27,7 @@ export async function load() {
],
'Multiple instances',
'Maintain within chart container, window/viewport, or overflow outside',
+ 'Configurable hide delay to prevent accidental hiding when moving to tooltip',
],
related: ['components/TooltipContext', 'components/Highlight'],
},
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 849700b1e..32dc1718c 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -100,7 +100,7 @@ importers:
version: 4.1.0
layercake:
specifier: ^8.4.2
- version: 8.4.2(svelte@5.19.9)(typescript@5.7.3)
+ version: 8.4.2(svelte@5.19.4)(typescript@5.7.3)
lodash-es:
specifier: ^4.17.21
version: 4.17.21
@@ -122,16 +122,16 @@ importers:
version: 3.0.5(rollup@2.79.2)
'@sveltejs/adapter-cloudflare':
specifier: ^5.0.2
- version: 5.0.2(@sveltejs/kit@2.17.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.9)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)))(svelte@5.19.9)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)))(wrangler@3.107.3(@cloudflare/workers-types@4.20250204.0))
+ version: 5.0.2(@sveltejs/kit@2.17.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.4)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)))(svelte@5.19.4)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)))(wrangler@3.107.3(@cloudflare/workers-types@4.20250204.0))
'@sveltejs/kit':
specifier: ^2.17.1
- version: 2.17.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.9)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)))(svelte@5.19.9)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0))
+ version: 2.17.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.4)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)))(svelte@5.19.4)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0))
'@sveltejs/package':
specifier: ^2.3.10
- version: 2.3.10(svelte@5.19.9)(typescript@5.7.3)
+ version: 2.3.10(svelte@5.19.4)(typescript@5.7.3)
'@sveltejs/vite-plugin-svelte':
specifier: ^5.0.3
- version: 5.0.3(svelte@5.19.9)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0))
+ version: 5.0.3(svelte@5.19.4)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0))
'@svitejs/changesets-changelog-github-compact':
specifier: ^1.2.0
version: 1.2.0
@@ -215,7 +215,7 @@ importers:
version: 15.0.6
mdsvex:
specifier: ^0.12.3
- version: 0.12.3(svelte@5.19.9)
+ version: 0.12.3(svelte@5.19.4)
posthog-js:
specifier: ^1.215.5
version: 1.215.5
@@ -224,7 +224,7 @@ importers:
version: 3.4.2
prettier-plugin-svelte:
specifier: ^3.3.3
- version: 3.3.3(prettier@3.4.2)(svelte@5.19.9)
+ version: 3.3.3(prettier@3.4.2)(svelte@5.19.4)
prism-svelte:
specifier: ^0.5.0
version: 0.5.0
@@ -241,20 +241,20 @@ importers:
specifier: ^0.3.0
version: 0.3.0
svelte:
- specifier: ^5.19.9
- version: 5.19.9
+ specifier: 5.19.4
+ version: 5.19.4
svelte-check:
specifier: ^4.1.4
- version: 4.1.4(picomatch@4.0.2)(svelte@5.19.9)(typescript@5.7.3)
+ version: 4.1.4(picomatch@4.0.2)(svelte@5.19.4)(typescript@5.7.3)
svelte-json-tree:
specifier: ^2.2.0
- version: 2.2.0(svelte@5.19.9)
+ version: 2.2.0(svelte@5.19.4)
svelte-ux:
specifier: ^0.90.0
- version: 0.90.0(postcss-load-config@6.0.1(jiti@2.4.2)(postcss@8.4.49)(yaml@2.7.0))(postcss@8.4.49)(svelte@5.19.9)
+ version: 0.90.0(postcss-load-config@6.0.1(jiti@2.4.2)(postcss@8.4.49)(yaml@2.7.0))(postcss@8.4.49)(svelte@5.19.4)
svelte2tsx:
specifier: ^0.7.34
- version: 0.7.34(svelte@5.19.9)(typescript@5.7.3)
+ version: 0.7.34(svelte@5.19.4)(typescript@5.7.3)
tailwindcss:
specifier: ^3.4.16
version: 3.4.16
@@ -2398,8 +2398,8 @@ packages:
resolution: {integrity: sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==}
engines: {node: '>=16'}
- svelte@5.19.9:
- resolution: {integrity: sha512-860s752/ZZxHIsii31ELkdKBOCeAuDsfb/AGUXJyQyzUVLRSt4oqEw/BV5+2+mNg8mbqmD3OK+vMvwWMPM6f8A==}
+ svelte@5.19.4:
+ resolution: {integrity: sha512-pzWvFQdvfEfT4Ll/JriAtcG7qmWjcL+x/NSl9Q+FPje5SXukYNp9kcufZ27ydauLLE/dwYMz9XRC8kiwTZmfDA==}
engines: {node: '>=18'}
tailwind-merge@2.5.4:
@@ -3274,17 +3274,17 @@ snapshots:
'@rollup/rollup-win32-x64-msvc@4.34.4':
optional: true
- '@sveltejs/adapter-cloudflare@5.0.2(@sveltejs/kit@2.17.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.9)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)))(svelte@5.19.9)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)))(wrangler@3.107.3(@cloudflare/workers-types@4.20250204.0))':
+ '@sveltejs/adapter-cloudflare@5.0.2(@sveltejs/kit@2.17.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.4)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)))(svelte@5.19.4)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)))(wrangler@3.107.3(@cloudflare/workers-types@4.20250204.0))':
dependencies:
'@cloudflare/workers-types': 4.20250204.0
- '@sveltejs/kit': 2.17.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.9)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)))(svelte@5.19.9)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0))
+ '@sveltejs/kit': 2.17.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.4)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)))(svelte@5.19.4)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0))
esbuild: 0.24.2
worktop: 0.8.0-next.18
wrangler: 3.107.3(@cloudflare/workers-types@4.20250204.0)
- '@sveltejs/kit@2.17.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.9)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)))(svelte@5.19.9)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0))':
+ '@sveltejs/kit@2.17.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.4)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)))(svelte@5.19.4)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0))':
dependencies:
- '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.19.9)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0))
+ '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.19.4)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0))
'@types/cookie': 0.6.0
cookie: 0.6.0
devalue: 5.1.1
@@ -3296,37 +3296,37 @@ snapshots:
sade: 1.8.1
set-cookie-parser: 2.7.1
sirv: 3.0.0
- svelte: 5.19.9
+ svelte: 5.19.4
vite: 6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)
- '@sveltejs/package@2.3.10(svelte@5.19.9)(typescript@5.7.3)':
+ '@sveltejs/package@2.3.10(svelte@5.19.4)(typescript@5.7.3)':
dependencies:
chokidar: 4.0.3
kleur: 4.1.5
sade: 1.8.1
semver: 7.7.1
- svelte: 5.19.9
- svelte2tsx: 0.7.34(svelte@5.19.9)(typescript@5.7.3)
+ svelte: 5.19.4
+ svelte2tsx: 0.7.34(svelte@5.19.4)(typescript@5.7.3)
transitivePeerDependencies:
- typescript
- '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.9)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)))(svelte@5.19.9)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0))':
+ '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.4)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)))(svelte@5.19.4)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0))':
dependencies:
- '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.19.9)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0))
+ '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.19.4)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0))
debug: 4.4.0
- svelte: 5.19.9
+ svelte: 5.19.4
vite: 6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)
transitivePeerDependencies:
- supports-color
- '@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.9)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0))':
+ '@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.4)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0))':
dependencies:
- '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.9)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)))(svelte@5.19.9)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0))
+ '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.4)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)))(svelte@5.19.4)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0))
debug: 4.4.0
deepmerge: 4.3.1
kleur: 4.1.5
magic-string: 0.30.17
- svelte: 5.19.9
+ svelte: 5.19.4
vite: 6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0)
vitefu: 1.0.5(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(yaml@2.7.0))
transitivePeerDependencies:
@@ -4127,13 +4127,13 @@ snapshots:
kleur@4.1.5: {}
- layercake@8.4.2(svelte@5.19.9)(typescript@5.7.3):
+ layercake@8.4.2(svelte@5.19.4)(typescript@5.7.3):
dependencies:
d3-array: 3.2.4
d3-color: 3.1.0
d3-scale: 4.0.2
d3-shape: 3.2.0
- svelte: 5.19.9
+ svelte: 5.19.4
typescript: 5.7.3
lilconfig@3.1.3: {}
@@ -4178,12 +4178,12 @@ snapshots:
mdn-data@2.0.30: {}
- mdsvex@0.12.3(svelte@5.19.9):
+ mdsvex@0.12.3(svelte@5.19.4):
dependencies:
'@types/unist': 2.0.11
prism-svelte: 0.4.7
prismjs: 1.29.0
- svelte: 5.19.9
+ svelte: 5.19.4
vfile-message: 2.0.4
merge2@1.4.1: {}
@@ -4420,10 +4420,10 @@ snapshots:
preact@10.25.4: {}
- prettier-plugin-svelte@3.3.3(prettier@3.4.2)(svelte@5.19.9):
+ prettier-plugin-svelte@3.3.3(prettier@3.4.2)(svelte@5.19.4):
dependencies:
prettier: 3.4.2
- svelte: 5.19.9
+ svelte: 5.19.4
prettier@2.8.8: {}
@@ -4679,21 +4679,21 @@ snapshots:
- stylus
- sugarss
- svelte-check@4.1.4(picomatch@4.0.2)(svelte@5.19.9)(typescript@5.7.3):
+ svelte-check@4.1.4(picomatch@4.0.2)(svelte@5.19.4)(typescript@5.7.3):
dependencies:
'@jridgewell/trace-mapping': 0.3.25
chokidar: 4.0.3
fdir: 6.4.3(picomatch@4.0.2)
picocolors: 1.1.1
sade: 1.8.1
- svelte: 5.19.9
+ svelte: 5.19.4
typescript: 5.7.3
transitivePeerDependencies:
- picomatch
- svelte-json-tree@2.2.0(svelte@5.19.9):
+ svelte-json-tree@2.2.0(svelte@5.19.4):
dependencies:
- svelte: 5.19.9
+ svelte: 5.19.4
svelte-preprocess@6.0.3(postcss-load-config@6.0.1(jiti@2.4.2)(postcss@8.4.49)(yaml@2.7.0))(postcss@8.4.49)(svelte@4.2.19)(typescript@5.7.3):
dependencies:
@@ -4703,7 +4703,7 @@ snapshots:
postcss-load-config: 6.0.1(jiti@2.4.2)(postcss@8.4.49)(yaml@2.7.0)
typescript: 5.7.3
- svelte-ux@0.90.0(postcss-load-config@6.0.1(jiti@2.4.2)(postcss@8.4.49)(yaml@2.7.0))(postcss@8.4.49)(svelte@5.19.9):
+ svelte-ux@0.90.0(postcss-load-config@6.0.1(jiti@2.4.2)(postcss@8.4.49)(yaml@2.7.0))(postcss@8.4.49)(svelte@5.19.4):
dependencies:
'@floating-ui/dom': 1.6.13
'@fortawesome/fontawesome-common-types': 6.7.2
@@ -4725,7 +4725,7 @@ snapshots:
prism-themes: 1.9.0
prismjs: 1.29.0
sveld: 0.22.0(postcss-load-config@6.0.1(jiti@2.4.2)(postcss@8.4.49)(yaml@2.7.0))(postcss@8.4.49)
- svelte: 5.19.9
+ svelte: 5.19.4
tailwind-merge: 2.6.0
zod: 3.24.1
transitivePeerDependencies:
@@ -4740,11 +4740,11 @@ snapshots:
- sugarss
- ts-node
- svelte2tsx@0.7.34(svelte@5.19.9)(typescript@5.7.3):
+ svelte2tsx@0.7.34(svelte@5.19.4)(typescript@5.7.3):
dependencies:
dedent-js: 1.0.1
pascal-case: 3.1.2
- svelte: 5.19.9
+ svelte: 5.19.4
typescript: 5.7.3
svelte@4.2.19:
@@ -4764,7 +4764,7 @@ snapshots:
magic-string: 0.30.17
periscopic: 3.1.0
- svelte@5.19.9:
+ svelte@5.19.4:
dependencies:
'@ampproject/remapping': 2.3.0
'@jridgewell/sourcemap-codec': 1.5.0