From 67a6f5ee975fb17e1b69b4bb395e3ce175bb1d26 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Thu, 12 Sep 2024 23:38:06 +0200 Subject: [PATCH 1/8] feat: legacy details This adds a details blocks for legacy mode. If one is toggled, all are toggled. Alternative to #80 The idea is to add legacy syntax inline into the documentation at the appropriate places using these notes, and devs can hide those when unchecking the checkbox. The "Reactivity Fundamentals" page shows how this would look like. --- .../03-reactivity-fundamentals.md | 66 +++++++++++++++++++ apps/svelte.dev/src/app.html | 9 +-- .../src/routes/docs/[...path]/+layout.svelte | 1 - .../src/routes/docs/[...path]/+page.svelte | 4 +- packages/site-kit/src/lib/actions/index.ts | 1 + .../src/lib/actions/legacy-details.ts | 38 +++++++++++ .../site-kit/src/lib/docs/DocsContents.svelte | 27 +------- .../site-kit/src/lib/docs/TSToggle.svelte | 48 -------------- .../site-kit/src/lib/docs/TsJsSelect.svelte | 2 +- packages/site-kit/src/lib/docs/index.ts | 1 - packages/site-kit/src/lib/styles/text.css | 13 ++++ 11 files changed, 126 insertions(+), 84 deletions(-) create mode 100644 packages/site-kit/src/lib/actions/legacy-details.ts delete mode 100644 packages/site-kit/src/lib/docs/TSToggle.svelte diff --git a/apps/svelte.dev/content/docs/svelte/01-introduction/03-reactivity-fundamentals.md b/apps/svelte.dev/content/docs/svelte/01-introduction/03-reactivity-fundamentals.md index 0f1c8e0799..ca784c4f4f 100644 --- a/apps/svelte.dev/content/docs/svelte/01-introduction/03-reactivity-fundamentals.md +++ b/apps/svelte.dev/content/docs/svelte/01-introduction/03-reactivity-fundamentals.md @@ -40,6 +40,23 @@ class Todo { } ``` +
+In Svelte 4 / Legacy Mode + +In Svelte 4, state was implicitly reactive if the variable was declared at the top level + +```svelte + + + +``` + +
+ ## `$derived` Derived state is declared with the `$derived` rune: @@ -61,6 +78,27 @@ The expression inside `$derived(...)` should be free of side-effects. Svelte wil As with `$state`, you can mark class fields as `$derived`. +
+In Svelte 4 / Legacy Mode +In Svelte 4, you could use reactive statements for this. + +```svelte + + + + +

{count} doubled is {doubled}

+``` + +This only worked at the top level of a component. + +
+ ## `$effect` To run _side-effects_ when the component is mounted to the DOM, and when values change, we can use the `$effect` rune ([demo](/#H4sIAAAAAAAAE31T24rbMBD9lUG7kAQ2sbdlX7xOYNk_aB_rQhRpbAsU2UiTW0P-vbrYubSlYGzmzMzROTPymdVKo2PFjzMzfIusYB99z14YnfoQuD1qQh-7bmdFQEonrOppVZmKNBI49QthCc-OOOH0LZ-9jxnR6c7eUpOnuv6KeT5JFdcqbvbcBcgDz1jXKGg6ncFyBedYR6IzLrAZwiN5vtSxaJA-EzadfJEjKw11C6GR22-BLH8B_wxdByWpvUYtqqal2XB6RVkG1CoHB6U1WJzbnYFDiwb3aGEdDa3Bm1oH12sQLTcNPp7r56m_00mHocSG97_zd7ICUXonA5fwKbPbkE2ZtMJGGVkEdctzQi4QzSwr9prnFYNk5hpmqVuqPQjNnfOJoMF22lUsrq_UfIN6lfSVyvQ7grB3X2mjMZYO3XO9w-U5iLx42qg29md3BP_ni5P4gy9ikTBlHxjLzAtPDlyYZmRdjAbGq7HprEQ7p64v4LU_guu0kvAkhBim3nMplWl8FreQD-CW20aZR0wq12t-KqDWeBywhvexKC3memmDwlHAv9q4Vo2ZK8KtK0CgX7u9J8wXbzdKv-nRnfF_2baTqlYoWUF2h5efl9-n0O6koAMAAA==)): @@ -86,3 +124,31 @@ To run _side-effects_ when the component is mounted to the DOM, and when values ``` The function passed to `$effect` will run when the component mounts, and will re-run after any changes to the values it reads that were declared with `$state` or `$derived` (including those passed in with `$props`). Re-runs are batched (i.e. changing `color` and `size` in the same moment won't cause two separate runs), and happen after any DOM updates have been applied. + +
+In Svelte 4 / Legacy Mode +In Svelte 4, you could use reactive statements for this. + +```svelte + + + +``` + +This only worked at the top level of a component. + +
diff --git a/apps/svelte.dev/src/app.html b/apps/svelte.dev/src/app.html index 14594cf757..c871dc8e0a 100644 --- a/apps/svelte.dev/src/app.html +++ b/apps/svelte.dev/src/app.html @@ -20,16 +20,13 @@ diff --git a/apps/svelte.dev/src/routes/docs/[...path]/+layout.svelte b/apps/svelte.dev/src/routes/docs/[...path]/+layout.svelte index ea6ef38404..ab2d242e24 100644 --- a/apps/svelte.dev/src/routes/docs/[...path]/+layout.svelte +++ b/apps/svelte.dev/src/routes/docs/[...path]/+layout.svelte @@ -30,7 +30,6 @@ .container { --sidebar-menu-width: 28rem; --sidebar-width: var(--sidebar-menu-width); - --ts-toggle-height: 4.2rem; display: flex; flex-direction: column; diff --git a/apps/svelte.dev/src/routes/docs/[...path]/+page.svelte b/apps/svelte.dev/src/routes/docs/[...path]/+page.svelte index daac75b2bd..48a287dcee 100644 --- a/apps/svelte.dev/src/routes/docs/[...path]/+page.svelte +++ b/apps/svelte.dev/src/routes/docs/[...path]/+page.svelte @@ -1,6 +1,6 @@ -{#if show_ts_toggle} -
- -
-{/if} - diff --git a/packages/site-kit/src/lib/docs/TsJsSelect.svelte b/packages/site-kit/src/lib/docs/TsJsSelect.svelte index fd29ff5ddf..15b2ee6053 100644 --- a/packages/site-kit/src/lib/docs/TsJsSelect.svelte +++ b/packages/site-kit/src/lib/docs/TsJsSelect.svelte @@ -7,7 +7,7 @@ if (browser) { prefers_ts.subscribe((ts) => { - document.body.classList.toggle('prefers-ts', ts); + document.body.classList.toggle('prefers-js', !ts); }); } diff --git a/packages/site-kit/src/lib/docs/index.ts b/packages/site-kit/src/lib/docs/index.ts index f1377163bb..fcff5c2986 100644 --- a/packages/site-kit/src/lib/docs/index.ts +++ b/packages/site-kit/src/lib/docs/index.ts @@ -1,4 +1,3 @@ export { default as DocsContents } from './DocsContents.svelte'; export { default as DocsOnThisPage } from './DocsOnThisPage.svelte'; -export { default as TSToggle } from './TSToggle.svelte'; export { setupDocsHovers } from './hover'; diff --git a/packages/site-kit/src/lib/styles/text.css b/packages/site-kit/src/lib/styles/text.css index 8756bd5609..03f8174164 100644 --- a/packages/site-kit/src/lib/styles/text.css +++ b/packages/site-kit/src/lib/styles/text.css @@ -344,3 +344,16 @@ .text :where(ul ul) { margin-bottom: 0; } + +details.legacy { + background-color: hsla(var(--sk-text-warning-hsl), 0.02); + border-radius: var(--sk-border-radius); + padding: 1rem; + margin: 1rem 0; + & > summary { + color: hsl(var(--sk-text-warning-hsl)); + font-size: 1.4rem; + font-weight: 600; + cursor: pointer; + } +} From 109e6acb7b82dc46fa1c5d94472222696b012b3f Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 24 Sep 2024 14:29:56 -0400 Subject: [PATCH 2/8] fix position when toggling other elements --- .../src/lib/actions/legacy-details.ts | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/packages/site-kit/src/lib/actions/legacy-details.ts b/packages/site-kit/src/lib/actions/legacy-details.ts index 5ecbe026ae..e8e9e93dd4 100644 --- a/packages/site-kit/src/lib/actions/legacy-details.ts +++ b/packages/site-kit/src/lib/actions/legacy-details.ts @@ -8,21 +8,49 @@ export function legacy_details(node: HTMLElement) { let details: NodeListOf; function update() { - details = node.querySelectorAll('details.legacy'); + /** @type {HTMLElement | null} */ + let scroll_parent = node; + + while ((scroll_parent = scroll_parent.parentElement)) { + if (/^(scroll|auto)$/.test(getComputedStyle(scroll_parent).overflowY)) { + break; + } + } + + details = /** @type {NodeListOf} */ node.querySelectorAll('details.legacy'); const show = get(show_legacy); + /** Whether the toggle was initiated by user action or `element.open = !element.open` */ + let secondary = false; + // Add a select to each code block for (const detail of details) { detail.open = show; - detail.addEventListener('toggle', () => { + detail.addEventListener('toggle', (e) => { + if (secondary) return; + secondary = true; + show_legacy.set(detail.open); + const top = detail.getBoundingClientRect().top; + for (const other of details) { if (other !== detail) { other.open = detail.open; } } + + const delta = detail.getBoundingClientRect().top - top; + + if (delta !== 0) { + // whichever element the user interacted with should stay in the same position + scroll_parent.scrollBy(0, delta); + } + + setTimeout(() => { + secondary = false; + }); }); } } From 4d8bc02d1e2f3cbcd02ea0829fc0d8b92a043821 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 24 Sep 2024 14:45:41 -0400 Subject: [PATCH 3/8] prevent flash-of-unopened-content --- apps/svelte.dev/src/app.html | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/svelte.dev/src/app.html b/apps/svelte.dev/src/app.html index c871dc8e0a..192efa0c39 100644 --- a/apps/svelte.dev/src/app.html +++ b/apps/svelte.dev/src/app.html @@ -45,5 +45,13 @@
%sveltekit.body%
+ + From 2cb1479cfed57cde0d37ea94568a44572a68b2f6 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 24 Sep 2024 14:48:13 -0400 Subject: [PATCH 4/8] tweaks --- .../svelte/01-introduction/03-reactivity-fundamentals.md | 6 +++--- packages/site-kit/src/lib/styles/text.css | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/apps/svelte.dev/content/docs/svelte/01-introduction/03-reactivity-fundamentals.md b/apps/svelte.dev/content/docs/svelte/01-introduction/03-reactivity-fundamentals.md index ca784c4f4f..1d165d46ac 100644 --- a/apps/svelte.dev/content/docs/svelte/01-introduction/03-reactivity-fundamentals.md +++ b/apps/svelte.dev/content/docs/svelte/01-introduction/03-reactivity-fundamentals.md @@ -41,7 +41,7 @@ class Todo { ```
-In Svelte 4 / Legacy Mode +Legacy mode In Svelte 4, state was implicitly reactive if the variable was declared at the top level @@ -79,7 +79,7 @@ The expression inside `$derived(...)` should be free of side-effects. Svelte wil As with `$state`, you can mark class fields as `$derived`.
-In Svelte 4 / Legacy Mode +Legacy mode In Svelte 4, you could use reactive statements for this. ```svelte @@ -126,7 +126,7 @@ To run _side-effects_ when the component is mounted to the DOM, and when values The function passed to `$effect` will run when the component mounts, and will re-run after any changes to the values it reads that were declared with `$state` or `$derived` (including those passed in with `$props`). Re-runs are batched (i.e. changing `color` and `size` in the same moment won't cause two separate runs), and happen after any DOM updates have been applied.
-In Svelte 4 / Legacy Mode +Legacy mode In Svelte 4, you could use reactive statements for this. ```svelte diff --git a/packages/site-kit/src/lib/styles/text.css b/packages/site-kit/src/lib/styles/text.css index 03f8174164..d74ef87a0c 100644 --- a/packages/site-kit/src/lib/styles/text.css +++ b/packages/site-kit/src/lib/styles/text.css @@ -356,4 +356,8 @@ details.legacy { font-weight: 600; cursor: pointer; } + + > :last-child { + margin-bottom: 0; + } } From af7305f3d6c872e1e8d8dc611c34e786d4f807c2 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 24 Sep 2024 14:49:52 -0400 Subject: [PATCH 5/8] tweak --- packages/site-kit/src/lib/styles/text.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/site-kit/src/lib/styles/text.css b/packages/site-kit/src/lib/styles/text.css index d74ef87a0c..f67510812b 100644 --- a/packages/site-kit/src/lib/styles/text.css +++ b/packages/site-kit/src/lib/styles/text.css @@ -357,6 +357,10 @@ details.legacy { cursor: pointer; } + &[open] > summary { + margin-bottom: 1.4rem; + } + > :last-child { margin-bottom: 0; } From 35cde8e2bd288a89a8f0b6b413f8420ce0ca53d6 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 24 Sep 2024 14:55:25 -0400 Subject: [PATCH 6/8] old habits die hard --- packages/site-kit/src/lib/actions/legacy-details.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/site-kit/src/lib/actions/legacy-details.ts b/packages/site-kit/src/lib/actions/legacy-details.ts index e8e9e93dd4..e85457530b 100644 --- a/packages/site-kit/src/lib/actions/legacy-details.ts +++ b/packages/site-kit/src/lib/actions/legacy-details.ts @@ -5,11 +5,8 @@ import { get } from 'svelte/store'; const show_legacy = persisted('svelte:show-legacy', true); export function legacy_details(node: HTMLElement) { - let details: NodeListOf; - function update() { - /** @type {HTMLElement | null} */ - let scroll_parent = node; + let scroll_parent: HTMLElement | null = node; while ((scroll_parent = scroll_parent.parentElement)) { if (/^(scroll|auto)$/.test(getComputedStyle(scroll_parent).overflowY)) { @@ -17,7 +14,7 @@ export function legacy_details(node: HTMLElement) { } } - details = /** @type {NodeListOf} */ node.querySelectorAll('details.legacy'); + const details = node.querySelectorAll('details.legacy') as NodeListOf; const show = get(show_legacy); /** Whether the toggle was initiated by user action or `element.open = !element.open` */ @@ -45,7 +42,7 @@ export function legacy_details(node: HTMLElement) { if (delta !== 0) { // whichever element the user interacted with should stay in the same position - scroll_parent.scrollBy(0, delta); + (scroll_parent ?? document.body).scrollBy(0, delta); } setTimeout(() => { From 930b4c366476e76a39ebf40aba1fbd58f9b10722 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 24 Sep 2024 15:00:23 -0400 Subject: [PATCH 7/8] add show all/hide all text --- packages/site-kit/src/lib/styles/text.css | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/site-kit/src/lib/styles/text.css b/packages/site-kit/src/lib/styles/text.css index f67510812b..f4de5ea680 100644 --- a/packages/site-kit/src/lib/styles/text.css +++ b/packages/site-kit/src/lib/styles/text.css @@ -350,15 +350,25 @@ details.legacy { border-radius: var(--sk-border-radius); padding: 1rem; margin: 1rem 0; + & > summary { color: hsl(var(--sk-text-warning-hsl)); font-size: 1.4rem; font-weight: 600; cursor: pointer; + + &::after { + content: 'show all'; + float: right; + } } &[open] > summary { margin-bottom: 1.4rem; + + &::after { + content: 'hide all' + } } > :last-child { From 179bfc80dcfe62bec13335d069baa67fd818b105 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 24 Sep 2024 15:02:53 -0400 Subject: [PATCH 8/8] prettier --- packages/site-kit/src/lib/styles/text.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/site-kit/src/lib/styles/text.css b/packages/site-kit/src/lib/styles/text.css index f4de5ea680..b489111a36 100644 --- a/packages/site-kit/src/lib/styles/text.css +++ b/packages/site-kit/src/lib/styles/text.css @@ -367,7 +367,7 @@ details.legacy { margin-bottom: 1.4rem; &::after { - content: 'hide all' + content: 'hide all'; } }