From 6cd4f8abbecf3c84cd0decca7d590293388e9834 Mon Sep 17 00:00:00 2001 From: Scott Rhamy Date: Thu, 1 Jan 2026 12:31:04 -0500 Subject: [PATCH 1/5] view-transitions - supports user-prefers-reduced motion - seen on clicking image link to load chart example. --- docs/src/app.css | 8 ++++++++ docs/src/lib/components/Example.svelte | 12 ++++++++++++ docs/src/lib/components/ExampleScreenshot.svelte | 8 +++++++- docs/src/lib/page-transitions.ts | 16 ++++++++++++++++ docs/src/routes/docs/+layout.svelte | 4 ++++ 5 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 docs/src/lib/page-transitions.ts diff --git a/docs/src/app.css b/docs/src/app.css index ddd9d4408..fcadc8033 100644 --- a/docs/src/app.css +++ b/docs/src/app.css @@ -168,3 +168,11 @@ code[data-line-numbers] > [data-line]::before { } } } + +/* Disable view transitions for reduced motion */ +@media (prefers-reduced-motion: reduce) { + ::view-transition-old(root), + ::view-transition-new(root) { + animation: none; + } +} diff --git a/docs/src/lib/components/Example.svelte b/docs/src/lib/components/Example.svelte index 74d98d438..95374a069 100644 --- a/docs/src/lib/components/Example.svelte +++ b/docs/src/lib/components/Example.svelte @@ -71,6 +71,17 @@ let ref = $state(null); let data = $derived(ref?.data); + // Ensure component name is always resolved consistently + const resolvedComponent = $derived(component ?? page.params.name ?? ''); + // Only set view-transition-name on detail pages (when page.params.example matches) + // This prevents conflicts with ExampleScreenshot on listing pages + const isDetailPage = $derived(page.params.example === name); + const viewTransitionName = $derived( + isDetailPage && resolvedComponent && name + ? `lc-${String(resolvedComponent)}-${String(name)}` + : undefined + ); + let canResize = $derived.by(() => { // Prop if (typeof noResize === 'boolean') { @@ -107,6 +118,7 @@ )} bind:this={containerEl} style:width={containerWidth ? `${containerWidth}px` : undefined} + style:view-transition-name={viewTransitionName} > diff --git a/docs/src/lib/components/ExampleScreenshot.svelte b/docs/src/lib/components/ExampleScreenshot.svelte index eb968ed93..235f5630c 100644 --- a/docs/src/lib/components/ExampleScreenshot.svelte +++ b/docs/src/lib/components/ExampleScreenshot.svelte @@ -16,10 +16,15 @@ } = $props(); const basePath = $derived(`/screenshots/${component}/${example}`); + const viewTransitionName = $derived(`lc-${component}-${example}`); const sizes = [ { width: '240w', light: '@sm:hidden dark:hidden', dark: 'dark:block dark:@sm:hidden' }, - { width: '400w', light: '@sm:block @lg:hidden dark:hidden', dark: 'dark:@sm:block dark:@lg:hidden' }, + { + width: '400w', + light: '@sm:block @lg:hidden dark:hidden', + dark: 'dark:@sm:block dark:@lg:hidden' + }, { width: '800w', light: '@lg:block dark:hidden', dark: 'dark:@lg:block' } ]; @@ -33,6 +38,7 @@ aspect === 'screenshot' && 'aspect-8/3', // roughly 800x300 for many cartesian background && 'bg-surface-100 dark:bg-surface-200' )} + style:view-transition-name={viewTransitionName} > {#each ['light', 'dark'] as mode} {#each sizes as size} diff --git a/docs/src/lib/page-transitions.ts b/docs/src/lib/page-transitions.ts new file mode 100644 index 000000000..60f5f163f --- /dev/null +++ b/docs/src/lib/page-transitions.ts @@ -0,0 +1,16 @@ +import { onNavigate } from '$app/navigation'; + +export const preparePageTransition = () => { + onNavigate((navigation) => { + if (!document.startViewTransition) { + return; + } + + return new Promise((resolve) => { + document.startViewTransition(async () => { + resolve(); + await navigation.complete; + }); + }); + }); +}; diff --git a/docs/src/routes/docs/+layout.svelte b/docs/src/routes/docs/+layout.svelte index d82010ea3..49fcc0c0c 100644 --- a/docs/src/routes/docs/+layout.svelte +++ b/docs/src/routes/docs/+layout.svelte @@ -19,6 +19,7 @@ import { page } from '$app/state'; import { examples } from '$lib/context.js'; import DocsMenu from '$lib/components/DocsMenu.svelte'; + import { preparePageTransition } from '$lib/page-transitions'; import favicon from '$lib/assets/favicon.svg'; import LucideAlignLeft from '~icons/lucide/align-left'; @@ -39,6 +40,9 @@ let { data, children } = $props(); + // View transition for navigation + preparePageTransition(); + // Set examples context for all /docs pages // Child layouts (like docs/components/[name]) can override with merged data const examplesContext = { From fab3e4d0341320919f74e12480fd722591dc50e0 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 2 Jan 2026 11:30:42 -0500 Subject: [PATCH 2/5] Add page transitions from home page as well --- docs/src/routes/+layout.svelte | 4 ++++ docs/src/routes/docs/+layout.svelte | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/src/routes/+layout.svelte b/docs/src/routes/+layout.svelte index 03633a5fe..eeb2880ac 100644 --- a/docs/src/routes/+layout.svelte +++ b/docs/src/routes/+layout.svelte @@ -6,6 +6,7 @@ import { dev } from '$app/environment'; import { page } from '$app/state'; + import { preparePageTransition } from '$lib/page-transitions'; import '@fontsource-variable/inter'; import '../app.css'; @@ -51,6 +52,9 @@ }; } }); + + // View transition for navigation + preparePageTransition(); {@render children()} diff --git a/docs/src/routes/docs/+layout.svelte b/docs/src/routes/docs/+layout.svelte index 49fcc0c0c..d82010ea3 100644 --- a/docs/src/routes/docs/+layout.svelte +++ b/docs/src/routes/docs/+layout.svelte @@ -19,7 +19,6 @@ import { page } from '$app/state'; import { examples } from '$lib/context.js'; import DocsMenu from '$lib/components/DocsMenu.svelte'; - import { preparePageTransition } from '$lib/page-transitions'; import favicon from '$lib/assets/favicon.svg'; import LucideAlignLeft from '~icons/lucide/align-left'; @@ -40,9 +39,6 @@ let { data, children } = $props(); - // View transition for navigation - preparePageTransition(); - // Set examples context for all /docs pages // Child layouts (like docs/components/[name]) can override with merged data const examplesContext = { From c02219e866ff513901bf4aa17d1f6fbb44554811 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 2 Jan 2026 11:32:00 -0500 Subject: [PATCH 3/5] Simplify viewTransitionName --- docs/src/lib/components/Example.svelte | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/src/lib/components/Example.svelte b/docs/src/lib/components/Example.svelte index e6642448b..35bcdbc74 100644 --- a/docs/src/lib/components/Example.svelte +++ b/docs/src/lib/components/Example.svelte @@ -104,9 +104,7 @@ // This prevents conflicts with ExampleScreenshot on listing pages const isDetailPage = $derived(page.params.example === name); const viewTransitionName = $derived( - isDetailPage && resolvedComponent && name - ? `lc-${String(resolvedComponent)}-${String(name)}` - : undefined + isDetailPage && resolvedComponent && name ? `lc-${resolvedComponent}-${name}` : undefined ); let canResize = $derived.by(() => { From 61cfa1d062e8007d5abca5b8a0bd7a5b4bd949b3 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 2 Jan 2026 11:43:52 -0500 Subject: [PATCH 4/5] Improve initial highlighter loading (fix "Loading..." always showing on first use) --- docs/src/lib/components/Code.svelte | 42 +++++++++++--------- packages/layerchart/src/lib/docs/Code.svelte | 21 +++++----- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/docs/src/lib/components/Code.svelte b/docs/src/lib/components/Code.svelte index 98af9c8d9..fbf2b5d03 100644 --- a/docs/src/lib/components/Code.svelte +++ b/docs/src/lib/components/Code.svelte @@ -1,10 +1,14 @@ @@ -81,24 +85,24 @@ {#if source}
 				
-					{#await highlighter}
-						
Loading...
- {:then h} + {#if highlighter} - {@html h.codeToHtml(sourceStr, { - lang: language, - themes: { - light: 'github-light-default', - dark: 'github-dark-default' - }, - meta: highlight ? { __raw: `{${highlight}}` } : undefined, - transformers: highlight ? [transformerMetaHighlight()] : undefined - })} - {:catch error} -
Error loading code highlighting: {error.message}
- {/await} - -
+ {@html highlighter.codeToHtml( + sourceStr, + { + lang: language, + themes: { + light: 'github-light-default', + dark: 'github-dark-default' + }, + meta: highlight ? { __raw: `{${highlight}}` } : undefined, + transformers: highlight ? [transformerMetaHighlight()] : undefined + } + )} + {:else} +
Loading...
+ {/if} +
{#if copyButton !== false} diff --git a/packages/layerchart/src/lib/docs/Code.svelte b/packages/layerchart/src/lib/docs/Code.svelte index 5651de976..eed427e13 100644 --- a/packages/layerchart/src/lib/docs/Code.svelte +++ b/packages/layerchart/src/lib/docs/Code.svelte @@ -1,9 +1,13 @@ @@ -37,20 +41,17 @@ {#if source}
       
-        {#await highlighter}
-          
Loading...
- {:then h} - {@html h.codeToHtml(source, { + {#if highlighter} + {@html highlighter.codeToHtml(source, { lang: language, themes: { light: 'github-light-default', dark: 'github-dark-default', }, })} - {:catch error} -
Error loading code highlighting: {error.message}
- {/await} - + {:else} +
Loading...
+ {/if}
From 5012fec280fa0e717f7d7d6e7f7b594f09dd5cd7 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 2 Jan 2026 11:52:40 -0500 Subject: [PATCH 5/5] Use `github-light-default` instead of `github-light` for markdown code blocks to match Code --- docs/src/lib/markdown/config/pretty-code.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/lib/markdown/config/pretty-code.js b/docs/src/lib/markdown/config/pretty-code.js index 11795de20..df2e8c9d5 100644 --- a/docs/src/lib/markdown/config/pretty-code.js +++ b/docs/src/lib/markdown/config/pretty-code.js @@ -6,8 +6,8 @@ import { shikiDiffTransformer } from '../transformers/shiki-diff.js'; */ export const prettyCodeOptions = { theme: { - light: 'github-light', - dark: 'github-dark' + light: 'github-light-default', + dark: 'github-dark-default' }, keepBackground: false, defaultLang: {