Skip to content

Commit 7241b19

Browse files
mishig25claude
andauthored
refactor(kit): migrate components to Svelte 5 runes syntax (#795)
Migrated all 110 src/ components with `migrate()` from svelte/compiler ($props/$state/$derived, event attributes, snippets), then hand-finished: - tooltip action rewritten from the removed class API (new Component/$set/ $destroy) to mount/unmount with reactive $state props, in a .svelte.ts module. This FIXES docstring parameter tooltips, which have been silently broken since #792 (`new Tooltip()` throws on Svelte 5 components; hover handlers swallowed the error). Verified against the Svelte 4 baseline. - FrameworkContent, InferenceApi, TokenizersLanguageContent intentionally stay in legacy syntax: their named slots collide with same-named props, which snippets cannot express; mixing legacy and runes is supported. - svelte/legacy shims (preventDefault/stopPropagation/handlers) replaced with plain event handlers; component prop types moved from constructor signatures to `Component<...>`. - `state_referenced_locally` warnings silenced in onwarn: initial-value capture matches the previous Svelte 4 semantics (doc pages pass static props), and they'd flood every downstream doc build log. Verified: svelte-check 0 errors; accelerate e2e output equivalent to the Svelte 4 baseline (identical metadata/links/ids, known whitespace-only diffs); hub-docs build (268 pages) byte-identical on all compared dimensions vs pre-migration; browser tests pass (hydration, SPA nav, shorthand URLs, HfOptions tabs, docstring tooltips mount/unmount). Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 707e116 commit 7241b19

111 files changed

Lines changed: 1085 additions & 510 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

kit/src/lib/Added.svelte

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
<script lang="ts">
22
import Tip from "./Tip.svelte";
33
4-
export let version: string;
4+
interface Props {
5+
version: string;
6+
children?: import("svelte").Snippet;
7+
}
8+
9+
let { version, children }: Props = $props();
510
</script>
611

712
<Tip>
813
<p class="font-medium">Added in {version}</p>
9-
<slot />
14+
{@render children?.()}
1015
</Tip>

kit/src/lib/Changed.svelte

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
<script lang="ts">
22
import Tip from "./Tip.svelte";
33
4-
export let version: string;
4+
interface Props {
5+
version: string;
6+
children?: import("svelte").Snippet;
7+
}
8+
9+
let { version, children }: Props = $props();
510
</script>
611

712
<Tip>
813
<p class="font-medium">Changed in {version}</p>
9-
<slot />
14+
{@render children?.()}
1015
</Tip>

kit/src/lib/CodeBlock.svelte

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
<script>
1+
<script lang="ts">
22
import CopyButton from "./CopyButton.svelte";
3-
let hideCopyButton = true;
4-
export let code = "";
5-
export let highlighted = "";
6-
export let lang = "";
7-
export let wrap = false;
8-
export let classNames = "";
3+
let hideCopyButton = $state(true);
4+
interface Props {
5+
code?: string;
6+
highlighted?: string;
7+
lang?: string;
8+
wrap?: boolean;
9+
classNames?: string;
10+
}
11+
12+
let { code = "", highlighted = "", lang = "", wrap = false, classNames = "" }: Props = $props();
913
1014
function handleMouseOver() {
1115
hideCopyButton = false;
@@ -17,10 +21,10 @@
1721

1822
<div
1923
class="code-block relative {classNames}"
20-
on:mouseover={handleMouseOver}
21-
on:focus={handleMouseOver}
22-
on:mouseout={handleMouseOut}
23-
on:blur={handleMouseOut}
24+
onmouseover={handleMouseOver}
25+
onfocus={handleMouseOver}
26+
onmouseout={handleMouseOut}
27+
onblur={handleMouseOut}
2428
>
2529
<div class="absolute top-2.5 right-4">
2630
<CopyButton

kit/src/lib/CodeBlockFw.svelte

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,20 @@
33
import CopyButton from "./CopyButton.svelte";
44
import FrameworkSwitch from "./FrameworkSwitch.svelte";
55
6-
export let group1: { id: string; code: string; highlighted: string };
7-
export let group2: { id: string; code: string; highlighted: string };
8-
export let lang = "";
9-
export let wrap = false;
6+
interface Props {
7+
group1: { id: string; code: string; highlighted: string };
8+
group2: { id: string; code: string; highlighted: string };
9+
lang?: string;
10+
wrap?: boolean;
11+
}
12+
13+
let { group1, group2, lang = "", wrap = false }: Props = $props();
1014
1115
const ids = [group1.id, group2.id];
1216
const storeKey = ids.join("-");
1317
const group = getGroupStore(storeKey);
1418
15-
let hideCopyButton = true;
19+
let hideCopyButton = $state(true);
1620
1721
function handleMouseOver() {
1822
hideCopyButton = false;
@@ -24,10 +28,13 @@
2428

2529
<div
2630
class="code-block relative"
27-
on:mouseover={handleMouseOver}
28-
on:focus={handleMouseOver}
29-
on:mouseout={handleMouseOut}
30-
on:focus={handleMouseOut}
31+
onmouseover={handleMouseOver}
32+
onfocus={() => {
33+
// preserved from the svelte 4 version, which bound focus to both handlers
34+
handleMouseOver();
35+
handleMouseOut();
36+
}}
37+
onmouseout={handleMouseOut}
3138
>
3239
{#if $group === "group1"}
3340
<div class="absolute top-2.5 right-4">

kit/src/lib/ColabDropdown.svelte

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@
22
import Dropdown from "./Dropdown.svelte";
33
import DropdownEntry from "./DropdownEntry.svelte";
44
5-
export let options: { label: string; value: string }[] = [];
6-
export let classNames = "";
5+
interface Props {
6+
options?: { label: string; value: string }[];
7+
classNames?: string;
8+
children?: import("svelte").Snippet;
9+
}
10+
11+
let { options = [], classNames = "", children }: Props = $props();
712
813
function onClick(url: string) {
914
window.open(url);
@@ -12,23 +17,27 @@
1217

1318
<div class={classNames}>
1419
<Dropdown btnLabel="" classNames="colab-dropdown" noBtnClass useDeprecatedJS={false}>
15-
<slot slot="button">
16-
<img
17-
alt="Open In Colab"
18-
class="!m-0"
19-
src="https://colab.research.google.com/assets/colab-badge.svg"
20-
/>
21-
</slot>
22-
<slot slot="menu">
23-
{#each options as { label, value }}
24-
<DropdownEntry
25-
classNames="text-sm !no-underline"
26-
iconClassNames="text-gray-500"
27-
{label}
28-
onClick={() => onClick(value)}
29-
useDeprecatedJS={false}
20+
{#snippet button()}
21+
{#if children}{@render children()}{:else}
22+
<img
23+
alt="Open In Colab"
24+
class="!m-0"
25+
src="https://colab.research.google.com/assets/colab-badge.svg"
3026
/>
31-
{/each}
32-
</slot>
27+
{/if}
28+
{/snippet}
29+
{#snippet menu()}
30+
{#if children}{@render children()}{:else}
31+
{#each options as { label, value }}
32+
<DropdownEntry
33+
classNames="text-sm !no-underline"
34+
iconClassNames="text-gray-500"
35+
{label}
36+
onClick={() => onClick(value)}
37+
useDeprecatedJS={false}
38+
/>
39+
{/each}
40+
{/if}
41+
{/snippet}
3342
</Dropdown>
3443
</div>

kit/src/lib/CopyButton.svelte

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@
55
import IconCopy from "./IconCopy.svelte";
66
import Tooltip from "./Tooltip.svelte";
77
8-
export let classNames = "";
9-
export let label = "";
10-
export let style: "button" | "button-clear" | "text" = "text";
11-
export let title = "";
12-
export let value: string;
8+
interface Props {
9+
classNames?: string;
10+
label?: string;
11+
style?: "button" | "button-clear" | "text";
12+
title?: string;
13+
value: string;
14+
}
15+
16+
let { classNames = "", label = "", style = "text", title = "", value }: Props = $props();
1317
14-
let isSuccess = false;
18+
let isSuccess = $state(false);
1519
let timeout: any;
1620
1721
onDestroy(() => {
@@ -41,7 +45,7 @@
4145
{!isSuccess && ['button-clear', 'text'].includes(style) ? 'text-gray-600' : ''}
4246
{isSuccess ? 'text-green-500' : ''}
4347
"
44-
on:click={handleClick}
48+
onclick={handleClick}
4549
title={title || label || "Copy to clipboard"}
4650
type="button"
4751
>

kit/src/lib/CopyLLMTxtMenu.svelte

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,19 @@
1010
import IconMCP from "./IconMCP.svelte";
1111
import IconHuggingChat from "./IconHuggingChat.svelte";
1212
13-
export let label = "Copy page";
14-
export let markdownDescription = "Copy page as Markdown for LLMs";
15-
export let containerClass = "";
16-
export let containerStyle = "";
13+
interface Props {
14+
label?: string;
15+
markdownDescription?: string;
16+
containerClass?: string;
17+
containerStyle?: string;
18+
}
19+
20+
let {
21+
label = "Copy page",
22+
markdownDescription = "Copy page as Markdown for LLMs",
23+
containerClass = "",
24+
containerStyle = "",
25+
}: Props = $props();
1726
1827
const isClient = typeof window !== "undefined";
1928
const hasDocument = typeof document !== "undefined";
@@ -28,11 +37,11 @@
2837
const SOURCE_URL_MD = SOURCE_URL.endsWith(".md") ? SOURCE_URL : SOURCE_URL + ".md";
2938
let encodedPrompt: string | null = null;
3039
31-
let open = false;
32-
let copied = false;
33-
let triggerEl: HTMLDivElement | null = null;
34-
let menuEl: HTMLDivElement | null = null;
35-
let menuStyle = "";
40+
let open = $state(false);
41+
let copied = $state(false);
42+
let triggerEl: HTMLDivElement | null = $state(null);
43+
let menuEl: HTMLDivElement | null = $state(null);
44+
let menuStyle = $state("");
3645
let closeTimeout: ReturnType<typeof setTimeout> | null = null;
3746
let sourceMarkdown: string | null = null;
3847
let sourceFetchPromise: Promise<string> | null = null;
@@ -204,10 +213,10 @@
204213
</script>
205214

206215
<svelte:window
207-
on:mousedown={handleWindowPointer}
208-
on:keydown={handleWindowKeydown}
209-
on:resize={handleWindowResize}
210-
on:scroll={handleWindowScroll}
216+
onmousedown={handleWindowPointer}
217+
onkeydown={handleWindowKeydown}
218+
onresize={handleWindowResize}
219+
onscroll={handleWindowScroll}
211220
/>
212221

213222
<div
@@ -218,7 +227,7 @@
218227
>
219228
<div bind:this={triggerEl} class="inline-flex rounded-md max-sm:rounded-sm">
220229
<button
221-
on:click={copyMarkdown}
230+
onclick={copyMarkdown}
222231
class="inline-flex items-center gap-1 h-7 max-sm:h-7 px-2 max-sm:px-1.5 text-sm font-medium text-gray-800 border border-r-0 rounded-l-md max-sm:rounded-l-sm border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800"
223232
aria-live="polite"
224233
>
@@ -230,7 +239,7 @@
230239
<span>{copied ? "Copied" : label}</span>
231240
</button>
232241
<button
233-
on:click={toggleMenu}
242+
onclick={toggleMenu}
234243
class="inline-flex items-center justify-center w-6 max-sm:w-5 h-7 max-sm:h-7 disabled:pointer-events-none text-sm text-gray-500 hover:text-gray-700 dark:hover:text-white rounded-r-md max-sm:rounded-r-sm border border-l transition border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800"
235244
aria-haspopup="menu"
236245
aria-expanded={open}
@@ -249,7 +258,7 @@
249258
class="fixed inset-0 z-40"
250259
aria-hidden="true"
251260
style="background: transparent;"
252-
on:click={closeMenu}
261+
onclick={closeMenu}
253262
></div>
254263
<div
255264
bind:this={menuEl}
@@ -260,7 +269,7 @@
260269
>
261270
<button
262271
role="menuitem"
263-
on:click={() => {
272+
onclick={() => {
264273
copyMarkdown();
265274
closeMenu();
266275
}}
@@ -284,7 +293,7 @@
284293
href={SOURCE_URL_MD}
285294
target="_blank"
286295
rel="noopener noreferrer"
287-
on:click={closeMenu}
296+
onclick={closeMenu}
288297
class="{baseMenuItemClass} no-underline!"
289298
>
290299
<div class="border border-gray-200 dark:border-gray-850 rounded-lg p-1.5">
@@ -305,7 +314,7 @@
305314
href={option.buildUrl()}
306315
target="_blank"
307316
rel="noopener noreferrer"
308-
on:click={closeMenu}
317+
onclick={closeMenu}
309318
class="{baseMenuItemClass} no-underline!"
310319
>
311320
<div class="border border-gray-200 dark:border-gray-850 rounded-lg p-1.5">
Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,29 @@
11
<script lang="ts">
22
import DocNotebookDropdown from "./DocNotebookDropdown.svelte";
33
4-
export let chapter: number;
5-
export let notebooks: { label: string; value: string }[] = [];
6-
export let classNames = "";
7-
export let askForHelpUrl = `https://discuss.huggingface.co/t/chapter-${chapter}-questions`;
4+
interface Props {
5+
chapter: number;
6+
notebooks?: { label: string; value: string }[];
7+
classNames?: string;
8+
askForHelpUrl?: any;
9+
}
10+
11+
let {
12+
chapter,
13+
notebooks = [],
14+
classNames = "",
15+
askForHelpUrl = `https://discuss.huggingface.co/t/chapter-${chapter}-questions`,
16+
}: Props = $props();
817
</script>
918

1019
<DocNotebookDropdown options={notebooks} {classNames}>
11-
<svelte:fragment slot="alwaysVisible">
20+
{#snippet alwaysVisible()}
1221
<a href={askForHelpUrl} target="_blank">
1322
<img
1423
alt="Ask a Question"
1524
class="!m-0"
1625
src="https://img.shields.io/badge/Ask%20a%20question-ffcb4c.svg?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgLTEgMTA0IDEwNiI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOiMyMzFmMjA7fS5jbHMtMntmaWxsOiNmZmY5YWU7fS5jbHMtM3tmaWxsOiMwMGFlZWY7fS5jbHMtNHtmaWxsOiMwMGE5NGY7fS5jbHMtNXtmaWxsOiNmMTVkMjI7fS5jbHMtNntmaWxsOiNlMzFiMjM7fTwvc3R5bGU+PC9kZWZzPjx0aXRsZT5EaXNjb3Vyc2VfbG9nbzwvdGl0bGU+PGcgaWQ9IkxheWVyXzIiPjxnIGlkPSJMYXllcl8zIj48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik01MS44NywwQzIzLjcxLDAsMCwyMi44MywwLDUxYzAsLjkxLDAsNTIuODEsMCw1Mi44MWw1MS44Ni0uMDVjMjguMTYsMCw1MS0yMy43MSw1MS01MS44N1M4MCwwLDUxLjg3LDBaIi8+PHBhdGggY2xhc3M9ImNscy0yIiBkPSJNNTIuMzcsMTkuNzRBMzEuNjIsMzEuNjIsMCwwLDAsMjQuNTgsNjYuNDFsLTUuNzIsMTguNEwzOS40LDgwLjE3YTMxLjYxLDMxLjYxLDAsMSwwLDEzLTYwLjQzWiIvPjxwYXRoIGNsYXNzPSJjbHMtMyIgZD0iTTc3LjQ1LDMyLjEyYTMxLjYsMzEuNiwwLDAsMS0zOC4wNSw0OEwxOC44Niw4NC44MmwyMC45MS0yLjQ3QTMxLjYsMzEuNiwwLDAsMCw3Ny40NSwzMi4xMloiLz48cGF0aCBjbGFzcz0iY2xzLTQiIGQ9Ik03MS42MywyNi4yOUEzMS42LDMxLjYsMCwwLDEsMzguOCw3OEwxOC44Niw4NC44MiwzOS40LDgwLjE3QTMxLjYsMzEuNiwwLDAsMCw3MS42MywyNi4yOVoiLz48cGF0aCBjbGFzcz0iY2xzLTUiIGQ9Ik0yNi40Nyw2Ny4xMWEzMS42MSwzMS42MSwwLDAsMSw1MS0zNUEzMS42MSwzMS42MSwwLDAsMCwyNC41OCw2Ni40MWwtNS43MiwxOC40WiIvPjxwYXRoIGNsYXNzPSJjbHMtNiIgZD0iTTI0LjU4LDY2LjQxQTMxLjYxLDMxLjYxLDAsMCwxLDcxLjYzLDI2LjI5YTMxLjYxLDMxLjYxLDAsMCwwLTQ5LDM5LjYzbC0zLjc2LDE4LjlaIi8+PC9nPjwvZz48L3N2Zz4="
1726
/>
1827
</a>
19-
</svelte:fragment>
28+
{/snippet}
2029
</DocNotebookDropdown>

kit/src/lib/Deprecated.svelte

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
<script lang="ts">
22
import Tip from "./Tip.svelte";
33
4-
export let version: string;
4+
interface Props {
5+
version: string;
6+
children?: import("svelte").Snippet;
7+
}
8+
9+
let { version, children }: Props = $props();
510
</script>
611

712
<Tip warning>
813
<p class="font-medium">Deprecated in {version}</p>
9-
<slot />
14+
{@render children?.()}
1015
</Tip>

0 commit comments

Comments
 (0)