diff --git a/apps/svelte.dev/content/tutorial/01-svelte/01-introduction/01-welcome-to-svelte/index.md b/apps/svelte.dev/content/tutorial/01-svelte/01-introduction/01-welcome-to-svelte/index.md index 0701a69017..5ece7b41e5 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/01-introduction/01-welcome-to-svelte/index.md +++ b/apps/svelte.dev/content/tutorial/01-svelte/01-introduction/01-welcome-to-svelte/index.md @@ -4,7 +4,7 @@ title: Welcome to Svelte Welcome to the Svelte tutorial! This will teach you everything you need to know to easily build web applications of all sizes, with high performance and a small footprint. -You can also consult the [API docs](https://svelte.dev/docs) and the [examples](https://svelte.dev/examples), or — if you're impatient to start hacking on your machine locally — create a project with `npm init svelte`. +You can also consult the [API docs](https://svelte.dev/docs) and visit the [playground](https://svelte.dev/playground), or — if you're impatient to start hacking on your machine locally — create a project with `npx sv create`. ## What is Svelte? @@ -12,7 +12,7 @@ Svelte is a tool for building web applications. Like other user interface framew These components are _compiled_ into small, efficient JavaScript modules that eliminate overhead traditionally associated with UI frameworks. -You can build your entire app with Svelte (for example, using an application framework like [SvelteKit](https://kit.svelte.dev), which this tutorial will cover), or you can add it incrementally to an existing codebase. You can also ship components as standalone packages that work anywhere. +You can build your entire app with Svelte (for example, using an application framework like [SvelteKit](/docs/kit), which this tutorial will cover), or you can add it incrementally to an existing codebase. You can also ship components as standalone packages that work anywhere. ## How to use this tutorial diff --git a/apps/svelte.dev/content/tutorial/01-svelte/01-introduction/03-dynamic-attributes/index.md b/apps/svelte.dev/content/tutorial/01-svelte/01-introduction/03-dynamic-attributes/index.md index 6c325239f9..4431f52e84 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/01-introduction/03-dynamic-attributes/index.md +++ b/apps/svelte.dev/content/tutorial/01-svelte/01-introduction/03-dynamic-attributes/index.md @@ -13,7 +13,9 @@ Our image is missing a `src` — let's add one: That's better. But if you hover over the `` in the editor, Svelte is giving us a warning: -> A11y: <img> element should have an alt attribute +``` +`` element should have an alt attribute +``` When building web apps, it's important to make sure that they're _accessible_ to the broadest possible userbase, including people with (for example) impaired vision or motion, or people without powerful hardware or good internet connections. Accessibility (shortened to a11y) isn't always easy to get right, but Svelte will help by warning you if you write inaccessible markup. diff --git a/apps/svelte.dev/content/tutorial/01-svelte/01-introduction/05-nested-components/index.md b/apps/svelte.dev/content/tutorial/01-svelte/01-introduction/05-nested-components/index.md index ee310890b2..9da965ae17 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/01-introduction/05-nested-components/index.md +++ b/apps/svelte.dev/content/tutorial/01-svelte/01-introduction/05-nested-components/index.md @@ -23,4 +23,4 @@ Add a ` - diff --git a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/01-reactive-assignments/+assets/app-b/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/01-state/+assets/app-b/src/lib/App.svelte similarity index 69% rename from apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/01-reactive-assignments/+assets/app-b/src/lib/App.svelte rename to apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/01-state/+assets/app-b/src/lib/App.svelte index bb0ebe43a6..c06f091e12 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/01-reactive-assignments/+assets/app-b/src/lib/App.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/01-state/+assets/app-b/src/lib/App.svelte @@ -1,12 +1,12 @@ - diff --git a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/01-state/index.md b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/01-state/index.md new file mode 100644 index 0000000000..3c474a1d98 --- /dev/null +++ b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/01-state/index.md @@ -0,0 +1,23 @@ +--- +title: State +--- + +At the heart of Svelte is a powerful system of _reactivity_ for keeping the DOM in sync with your application state — for example, in response to an event. + +Make the `count` declaration reactive by wrapping the value with `$state(...)`: + +```js +/// file: App.svelte +let count = +++$state(0)+++; +``` + +This is called a _rune_, and it's how you tell Svelte that `count` isn't an ordinary variable. Runes look like functions, but they're not — when you use Svelte, they're part of the language itself. + +All that's left is to implement `increment`: + +```js +/// file: App.svelte +function increment() { + +++count += 1;+++ +} +``` diff --git a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/02-deep-state/+assets/app-a/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/02-deep-state/+assets/app-a/src/lib/App.svelte new file mode 100644 index 0000000000..de6b623115 --- /dev/null +++ b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/02-deep-state/+assets/app-a/src/lib/App.svelte @@ -0,0 +1,13 @@ + + +

{numbers.join(' + ')} = ...

+ + diff --git a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/02-deep-state/+assets/app-b/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/02-deep-state/+assets/app-b/src/lib/App.svelte new file mode 100644 index 0000000000..70af57b629 --- /dev/null +++ b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/02-deep-state/+assets/app-b/src/lib/App.svelte @@ -0,0 +1,13 @@ + + +

{numbers.join(' + ')} = ...

+ + diff --git a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/02-deep-state/index.md b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/02-deep-state/index.md new file mode 100644 index 0000000000..74d752fc8d --- /dev/null +++ b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/02-deep-state/index.md @@ -0,0 +1,32 @@ +--- +title: Deep state +--- + +As we saw in the previous exercise, state reacts to _reassignments_. But it also reacts to _mutations_ — we call this _deep reactivity_. + +Make `numbers` a reactive array: + +```js +/// file: App.svelte +let numbers = +++$state([1, 2, 3, 4])+++; +``` + +Now, when we change the array... + +```js +/// file: App.svelte +function addNumber() { + +++numbers[numbers.length] = numbers.length + 1;+++ +} +``` + +...the component updates. Or better still, we can `push` to the array instead: + +```js +/// file: App.svelte +function addNumber() { + +++numbers.push(numbers.length + 1);+++ +} +``` + +> Deep reactivity is implemented using [proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy), and mutations to the proxy do not affect the original object. diff --git a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/02-reactive-declarations/+assets/app-b/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/02-reactive-declarations/+assets/app-b/src/lib/App.svelte deleted file mode 100644 index c48f0c7f3c..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/02-reactive-declarations/+assets/app-b/src/lib/App.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - - - -

{count} doubled is {doubled}

diff --git a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/02-reactive-declarations/index.md b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/02-reactive-declarations/index.md deleted file mode 100644 index 0ef6f276fe..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/02-reactive-declarations/index.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: Declarations ---- - -Svelte automatically updates the DOM when your component's state changes. Often, some parts of a component's state need to be computed from _other_ parts (such as a `fullname` derived from a `firstname` and a `lastname`), and recomputed whenever they change. - -For these, we have _reactive declarations_. They look like this: - -```js -/// file: App.svelte -let count = 0; -+++$: doubled = count * 2;+++ -``` - -If a reactive statement consists entirely of an assignment to an undeclared variable, Svelte will inject a `let` declaration on your behalf. - -> Don't worry if this looks a little alien. It's [valid](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label) (if unconventional) JavaScript, which Svelte interprets to mean 're-run this code whenever any of the referenced values change'. Once you get used to it, there's no going back. - -Let's use `doubled` in our markup: - -```svelte -/// file: App.svelte - - -+++

{count} doubled is {doubled}

+++ -``` - -Of course, you could just write `{count * 2}` in the markup instead — you don't have to use reactive values. Reactive values become particularly valuable (no pun intended) when you need to reference them multiple times, or you have values that depend on _other_ reactive values. - -> Note that reactive declarations and statements will run after other script code and before component markup is rendered. diff --git a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/03-derived-state/+assets/app-b/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/03-derived-state/+assets/app-b/src/lib/App.svelte new file mode 100644 index 0000000000..57b2fcafcd --- /dev/null +++ b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/03-derived-state/+assets/app-b/src/lib/App.svelte @@ -0,0 +1,14 @@ + + +

{numbers.join(' + ')} = {total}

+ + diff --git a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/03-derived-state/index.md b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/03-derived-state/index.md new file mode 100644 index 0000000000..f64ce67dc2 --- /dev/null +++ b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/03-derived-state/index.md @@ -0,0 +1,20 @@ +--- +title: Derived state +--- + +Often, you will need to _derive_ state from other state. For this, we have the `$derived` rune: + +```js +/// file: App.svelte +let numbers = $state([1, 2, 3, 4]); ++++let total = $derived(numbers.reduce((t, n) => t + n, 0));+++ +``` + +We can now use this in our markup: + +```svelte +/// file: App.svelte +

{numbers.join(' + ')} = +++{total}+++

+``` + +The expression inside the `$derived` declaration will be re-evaluated whenever its dependencies (in this case, just `numbers`) are updated. Unlike normal state, derived state is read-only. diff --git a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/03-reactive-statements/+assets/app-a/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/03-reactive-statements/+assets/app-a/src/lib/App.svelte deleted file mode 100644 index 6d78f949e1..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/03-reactive-statements/+assets/app-a/src/lib/App.svelte +++ /dev/null @@ -1,12 +0,0 @@ - - - diff --git a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/03-reactive-statements/+assets/app-b/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/03-reactive-statements/+assets/app-b/src/lib/App.svelte deleted file mode 100644 index aecc9d2ce9..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/03-reactive-statements/+assets/app-b/src/lib/App.svelte +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/03-reactive-statements/index.md b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/03-reactive-statements/index.md deleted file mode 100644 index 9ee6f4f89b..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/03-reactive-statements/index.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: Statements ---- - -We're not limited to declaring reactive _values_ — we can also run arbitrary _statements_ reactively. For example, we can log the value of `count` whenever it changes: - -```js -/// file: App.svelte -let count = 0; - -+++$: console.log(`the count is ${count}`);+++ -``` - -You can easily group statements together with a block: - -```js -/// file: App.svelte -$: +++{+++ - console.log(`the count is ${count}`); - console.log(`this will also be logged whenever count changes`); -+++}+++ -``` - -You can even put the `$:` in front of things like `if` blocks: - -```js -/// file: App.svelte -$: +++if (count >= 10)+++ { - alert('count is dangerously high!'); - count = 0; -} -``` diff --git a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/04-effects/+assets/app-a/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/04-effects/+assets/app-a/src/lib/App.svelte new file mode 100644 index 0000000000..63afd0c6df --- /dev/null +++ b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/04-effects/+assets/app-a/src/lib/App.svelte @@ -0,0 +1,9 @@ + + + + + +

elapsed: {elapsed}

diff --git a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/04-effects/+assets/app-b/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/04-effects/+assets/app-b/src/lib/App.svelte new file mode 100644 index 0000000000..f57a073268 --- /dev/null +++ b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/04-effects/+assets/app-b/src/lib/App.svelte @@ -0,0 +1,19 @@ + + + + + +

elapsed: {elapsed}

diff --git a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/04-effects/index.md b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/04-effects/index.md new file mode 100644 index 0000000000..6a33a6d84b --- /dev/null +++ b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/04-effects/index.md @@ -0,0 +1,48 @@ +--- +title: Effects +--- + +So far we've talked about reactivity in terms of state. But that's only half of the equation — state is only reactive if something is _reacting_ to it, otherwise it's just a sparkling variable. + +The thing that reacts is called an _effect_. You've already encountered effects — the ones that Svelte creates on your behalf to update the DOM in response to state changes — but you can also create your own with the `$effect` rune. + +> Most of the time, you shouldn't. `$effect` is best thought of as an escape hatch, rather than something to use frequently. If you can put your side effects in an [event handler](dom-events), for example, that's almost always preferable. + +Let's say we want to use `setInterval` to keep track of how long the component has been mounted. Create the effect: + +```svelte +/// file: App.svelte + +``` + +Click the 'speed up' button a few times and notice that `elapsed` ticks up faster, because we're calling `setInterval` each time `interval` gets smaller. + +If we then click the 'slow down' button... well, it doesn't work. That's because we're not clearing out the old intervals when the effect updates. We can fix that by returning a cleanup function: + +```js +/// file: App.svelte +$effect(() => { + +++const id =+++ setInterval(() => { + elapsed += 1; + }, interval); + ++++ return () => { + clearInterval(id); + };+++ +}); +``` + +The cleanup function is called immediately before the effect function re-runs when `interval` changes, and also when the component is destroyed. + +If the effect function doesn't read any state when it runs, it will only run once, when the component mounts. + +> Effects do not run during server-side rendering. diff --git a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/+assets/app-a/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/+assets/app-a/src/lib/App.svelte deleted file mode 100644 index ab6ef7074c..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/+assets/app-a/src/lib/App.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - -

{numbers.join(' + ')} = {sum}

- - diff --git a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/+assets/app-b/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/+assets/app-b/src/lib/App.svelte deleted file mode 100644 index 730ae8cc7a..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/+assets/app-b/src/lib/App.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - -

{numbers.join(' + ')} = {sum}

- - diff --git a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/index.md b/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/index.md deleted file mode 100644 index 49e0654ab5..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: Updating arrays and objects ---- - -Because Svelte's reactivity is triggered by assignments, using array methods like `push` and `splice` won't automatically cause updates. For example, clicking the 'Add a number' button doesn't currently do anything, even though we're calling `numbers.push(...)` inside `addNumber`. - -One way to fix that is to add an assignment that would otherwise be redundant: - -```js -/// file: App.svelte -function addNumber() { - numbers.push(numbers.length + 1); - +++numbers = numbers;+++ -} -``` - -But there's a more idiomatic solution: - -```js -/// file: App.svelte -function addNumber() { - numbers = +++[...numbers, numbers.length + 1];+++ -} -``` - -You can use similar patterns to replace `pop`, `shift`, `unshift` and `splice`. - -Assignments to _properties_ of arrays and objects — e.g. `obj.foo += 1` or `array[i] = x` — work the same way as assignments to the values themselves. - -```js -/// file: App.svelte -function addNumber() { - numbers[numbers.length] = numbers.length + 1; -} -``` - -A simple rule of thumb: the name of the updated variable must appear on the left hand side of the assignment. For example this... - -```js -/// no-file -const obj = { foo: { bar: 1 } }; -const foo = obj.foo; -foo.bar = 2; -``` - -...won't trigger reactivity on `obj.foo.bar`, unless you follow it up with `obj = obj`. diff --git a/apps/svelte.dev/content/tutorial/01-svelte/03-props/01-declaring-props/+assets/app-a/src/lib/Nested.svelte b/apps/svelte.dev/content/tutorial/01-svelte/03-props/01-declaring-props/+assets/app-a/src/lib/Nested.svelte index 141cae3230..5b1d9142a9 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/03-props/01-declaring-props/+assets/app-a/src/lib/Nested.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/03-props/01-declaring-props/+assets/app-a/src/lib/Nested.svelte @@ -1,5 +1,5 @@

The answer is {answer}

diff --git a/apps/svelte.dev/content/tutorial/01-svelte/03-props/01-declaring-props/+assets/app-b/src/lib/Nested.svelte b/apps/svelte.dev/content/tutorial/01-svelte/03-props/01-declaring-props/+assets/app-b/src/lib/Nested.svelte index 7267c0edea..5b229b0c15 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/03-props/01-declaring-props/+assets/app-b/src/lib/Nested.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/03-props/01-declaring-props/+assets/app-b/src/lib/Nested.svelte @@ -1,5 +1,5 @@

The answer is {answer}

diff --git a/apps/svelte.dev/content/tutorial/01-svelte/03-props/01-declaring-props/index.md b/apps/svelte.dev/content/tutorial/01-svelte/03-props/01-declaring-props/index.md index ac9a711a0b..828f722fc9 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/03-props/01-declaring-props/index.md +++ b/apps/svelte.dev/content/tutorial/01-svelte/03-props/01-declaring-props/index.md @@ -4,13 +4,11 @@ title: Declaring props So far, we've dealt exclusively with internal state — that is to say, the values are only accessible within a given component. -In any real application, you'll need to pass data from one component down to its children. To do that, we need to declare _properties_, generally shortened to 'props'. In Svelte, we do that with the `export` keyword. Edit the `Nested.svelte` component: +In any real application, you'll need to pass data from one component down to its children. To do that, we need to declare _properties_, generally shortened to 'props'. In Svelte, we do that with the `$props` rune. Edit the `Nested.svelte` component: ```svelte /// file: Nested.svelte ``` - -> Just like `$:`, this may feel a little weird at first. That's not how `export` normally works in JavaScript modules! Just roll with it for now — it'll soon become second nature. diff --git a/apps/svelte.dev/content/tutorial/01-svelte/03-props/02-default-values/+assets/app-a/src/lib/Nested.svelte b/apps/svelte.dev/content/tutorial/01-svelte/03-props/02-default-values/+assets/app-a/src/lib/Nested.svelte index 7267c0edea..5b229b0c15 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/03-props/02-default-values/+assets/app-a/src/lib/Nested.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/03-props/02-default-values/+assets/app-a/src/lib/Nested.svelte @@ -1,5 +1,5 @@

The answer is {answer}

diff --git a/apps/svelte.dev/content/tutorial/01-svelte/03-props/02-default-values/+assets/app-b/src/lib/Nested.svelte b/apps/svelte.dev/content/tutorial/01-svelte/03-props/02-default-values/+assets/app-b/src/lib/Nested.svelte index 3efe9ccb75..218a6a7c69 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/03-props/02-default-values/+assets/app-b/src/lib/Nested.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/03-props/02-default-values/+assets/app-b/src/lib/Nested.svelte @@ -1,5 +1,5 @@

The answer is {answer}

diff --git a/apps/svelte.dev/content/tutorial/01-svelte/03-props/02-default-values/index.md b/apps/svelte.dev/content/tutorial/01-svelte/03-props/02-default-values/index.md index 2306e80c5b..4b73e68420 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/03-props/02-default-values/index.md +++ b/apps/svelte.dev/content/tutorial/01-svelte/03-props/02-default-values/index.md @@ -7,7 +7,7 @@ We can easily specify default values for props in `Nested.svelte`: ```svelte /// file: Nested.svelte ``` diff --git a/apps/svelte.dev/content/tutorial/01-svelte/03-props/03-spread-props/+assets/app-a/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/03-props/03-spread-props/+assets/app-a/src/lib/App.svelte index 2d5d7123bb..78a192988c 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/03-props/03-spread-props/+assets/app-a/src/lib/App.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/03-props/03-spread-props/+assets/app-a/src/lib/App.svelte @@ -3,14 +3,14 @@ const pkg = { name: 'svelte', - speed: 'blazing', - version: 4, + version: 5, + description: 'blazing fast', website: 'https://svelte.dev' }; diff --git a/apps/svelte.dev/content/tutorial/01-svelte/03-props/03-spread-props/+assets/app-a/src/lib/PackageInfo.svelte b/apps/svelte.dev/content/tutorial/01-svelte/03-props/03-spread-props/+assets/app-a/src/lib/PackageInfo.svelte index 51a30b8fa9..a23b82d622 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/03-props/03-spread-props/+assets/app-a/src/lib/PackageInfo.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/03-props/03-spread-props/+assets/app-a/src/lib/PackageInfo.svelte @@ -1,13 +1,8 @@

- The {name} package is {speed} fast. Download version {version} from - npm and learn more here + The {name} package is {description}. Download version {version} from + npm and learn more here

diff --git a/apps/svelte.dev/content/tutorial/01-svelte/03-props/03-spread-props/+assets/app-b/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/03-props/03-spread-props/+assets/app-b/src/lib/App.svelte index 3ded4fd565..dbf374d600 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/03-props/03-spread-props/+assets/app-b/src/lib/App.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/03-props/03-spread-props/+assets/app-b/src/lib/App.svelte @@ -3,8 +3,8 @@ const pkg = { name: 'svelte', - speed: 'blazing', - version: 4, + version: 5, + description: 'blazing fast', website: 'https://svelte.dev' }; diff --git a/apps/svelte.dev/content/tutorial/01-svelte/03-props/03-spread-props/index.md b/apps/svelte.dev/content/tutorial/01-svelte/03-props/03-spread-props/index.md index 557ee29618..0b389f3539 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/03-props/03-spread-props/index.md +++ b/apps/svelte.dev/content/tutorial/01-svelte/03-props/03-spread-props/index.md @@ -2,16 +2,16 @@ title: Spread props --- -In this exercise, we've forgotten to specify the `version` prop expected by `PackageInfo.svelte`, meaning it shows 'version undefined'. +In this exercise, we've forgotten to pass the `name` prop expected by `PackageInfo.svelte`, meaning the `` element is empty and the npm link is broken. -We _could_ fix it by adding the `version` prop... +We _could_ fix it by adding the prop... ```svelte /// file: App.svelte ``` @@ -23,4 +23,14 @@ We _could_ fix it by adding the `version` prop... ``` -> Conversely, if you need to reference all the props that were passed into a component, including ones that weren't declared with `export`, you can do so by accessing `$$props` directly. It's not generally recommended, as it's difficult for Svelte to optimise, but it's useful in rare cases. +> Conversely, you can get an object containing all the props that were passed into a component using a rest property... +> +> ```js +> let { name, ...stuff } = $props(); +> ``` +> +> ...or by skipping [destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) altogether: +> +> ```js +> let stuff = $props(); +> ``` diff --git a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/01-if-blocks/+assets/app-a/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/01-if-blocks/+assets/app-a/src/lib/App.svelte index bb0ebe43a6..c06f091e12 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/01-if-blocks/+assets/app-a/src/lib/App.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/01-if-blocks/+assets/app-a/src/lib/App.svelte @@ -1,12 +1,12 @@ - diff --git a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/01-if-blocks/+assets/app-b/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/01-if-blocks/+assets/app-b/src/lib/App.svelte index 6f6ab28d24..837591f7d5 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/01-if-blocks/+assets/app-b/src/lib/App.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/01-if-blocks/+assets/app-b/src/lib/App.svelte @@ -1,16 +1,16 @@ - {#if count > 10}

{count} is greater than 10

-{/if} \ No newline at end of file +{/if} diff --git a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/01-if-blocks/index.md b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/01-if-blocks/index.md index 845b4ab99d..30a2c2e4e3 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/01-if-blocks/index.md +++ b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/01-if-blocks/index.md @@ -8,7 +8,7 @@ To conditionally render some markup, we wrap it in an `if` block. Let's add some ```svelte /// file: App.svelte - @@ -18,4 +18,4 @@ To conditionally render some markup, we wrap it in an `if` block. Let's add some {/if}+++ ``` -Try it — update the component, and click on the button. +Try it — update the component, and click on the button a few times. diff --git a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/02-else-blocks/+assets/app-b/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/02-else-blocks/+assets/app-b/src/lib/App.svelte index d82dadb10f..828f78c865 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/02-else-blocks/+assets/app-b/src/lib/App.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/02-else-blocks/+assets/app-b/src/lib/App.svelte @@ -1,12 +1,12 @@ - @@ -15,4 +15,4 @@

{count} is greater than 10

{:else}

{count} is between 0 and 10

-{/if} \ No newline at end of file +{/if} diff --git a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/02-else-blocks/index.md b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/02-else-blocks/index.md index f342c11889..52cfc5564e 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/02-else-blocks/index.md +++ b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/02-else-blocks/index.md @@ -13,4 +13,4 @@ Just like in JavaScript, an `if` block can have an `else` block: {/if} ``` -> A `#` character always indicates a _block opening_ tag. A `/` character always indicates a _block closing_ tag. A `:` character, as in `{:else}`, indicates a _block continuation_ tag. Don't worry — you've already learned almost all the syntax Svelte adds to HTML. +`{#...}` opens a block. `{/...}` closes a block. `{:...}` _continues_ a block. Congratulations — you've already learned almost all the syntax Svelte adds to HTML. diff --git a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/03-else-if-blocks/+assets/app-b/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/03-else-if-blocks/+assets/app-b/src/lib/App.svelte index 0f52805e61..e0f7ca88f2 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/03-else-if-blocks/+assets/app-b/src/lib/App.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/03-else-if-blocks/+assets/app-b/src/lib/App.svelte @@ -1,12 +1,12 @@ - @@ -17,4 +17,4 @@

{count} is less than 5

{:else}

{count} is between 5 and 10

-{/if} \ No newline at end of file +{/if} diff --git a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/04-each-blocks/+assets/app-a/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/04-each-blocks/+assets/app-a/src/lib/App.svelte index e469ed7181..f2425672ac 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/04-each-blocks/+assets/app-a/src/lib/App.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/04-each-blocks/+assets/app-a/src/lib/App.svelte @@ -1,30 +1,30 @@

Pick a colour

@@ -60,4 +60,4 @@ filter: none; box-shadow: inset 3px 3px 4px rgba(0,0,0,0.2); } - \ No newline at end of file + diff --git a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/04-each-blocks/+assets/app-b/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/04-each-blocks/+assets/app-b/src/lib/App.svelte index 468d57b501..b9db99609c 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/04-each-blocks/+assets/app-b/src/lib/App.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/04-each-blocks/+assets/app-b/src/lib/App.svelte @@ -1,6 +1,6 @@

Pick a colour

@@ -8,10 +8,10 @@
{#each colors as color, i} {/each}
@@ -42,4 +42,4 @@ filter: none; box-shadow: inset 3px 3px 4px rgba(0,0,0,0.2); } - \ No newline at end of file + diff --git a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/04-each-blocks/index.md b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/04-each-blocks/index.md index 3011cbb8f5..d8d5b92a84 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/04-each-blocks/index.md +++ b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/04-each-blocks/index.md @@ -11,16 +11,16 @@ Instead of laboriously copying, pasting and editing, we can get rid of all but t
+++{#each colors as color}+++ +++{/each}+++
``` -> The expression (`colors`, in this case) can be any array or array-like object (i.e. it has a `length` property). You can loop over generic iterables with `each [...iterable]`. +> The expression (`colors`, in this case) can be any iterable or array-like object — in other words, anything that works with [`Array.from`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from). Now we need to use the `color` variable in place of `"red"`: @@ -29,9 +29,9 @@ Now we need to use the `color` variable in place of `"red"`:
{#each colors as color} {/each} @@ -45,9 +45,9 @@ You can get the current _index_ as a second argument, like so:
{#each colors as color, +++i}+++ {/each} diff --git a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/+assets/app-a/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/+assets/app-a/src/lib/App.svelte index 718eb59cab..396ce1b86e 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/+assets/app-a/src/lib/App.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/+assets/app-a/src/lib/App.svelte @@ -1,20 +1,16 @@ - diff --git a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/+assets/app-a/src/lib/Thing.svelte b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/+assets/app-a/src/lib/Thing.svelte index 96f48a8d2b..f1088b5b09 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/+assets/app-a/src/lib/Thing.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/+assets/app-a/src/lib/Thing.svelte @@ -7,12 +7,11 @@ egg: '🥚' }; - // the name is updated whenever the prop value changes... - export let name; + // `name` is updated whenever the prop value changes... + let { name } = $props(); - // ...but the "emoji" variable is fixed upon initialisation - // of the component because it uses `const` instead of `$:` + // ...but `emoji` is fixed upon initialisation const emoji = emojis[name]; -

{emoji} = {name}

\ No newline at end of file +

{emoji} = {name}

diff --git a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/+assets/app-b/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/+assets/app-b/src/lib/App.svelte index 8eaeb9a6f9..d33962dc12 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/+assets/app-b/src/lib/App.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/+assets/app-b/src/lib/App.svelte @@ -1,20 +1,16 @@ - diff --git a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/index.md b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/index.md index a87e34367c..eb219ea593 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/index.md +++ b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/index.md @@ -4,16 +4,18 @@ title: Keyed each blocks By default, when you modify the value of an `each` block, it will add and remove DOM nodes at the _end_ of the block, and update any values that have changed. That might not be what you want. -It's easier to show why than to explain. The `` component sets the emoji as a constant on initialization, but the name is passed in via a prop. +It's easier to show why than to explain. Inside `Thing.svelte`, `name` is a dynamic prop but `emoji` is a constant. Click the 'Remove first thing' button a few times, and notice what happens: 1. It removes the last component. -2. It then updates the `name` value in the remaining DOM nodes, but not the emoji, which is fixed when each `` is created. +2. It then updates the `name` value in the remaining DOM nodes, but not the emoji. -Instead, we'd like to remove only the first `` component and its DOM node, and leave the others unaffected. +> If you're coming from React, this might seem strange, because you're used to the entire component re-rendering when state changes. Svelte works differently: the component 'runs' once, and subsequent updates are 'fine-grained'. This makes things faster and gives you more control. -To do that, we specify a unique identifier (or "key") for each iteration of the `each` block: +One way to fix it would be to make `emoji` a [`$derived`](derived-state) value. But it makes more sense to remove the first `` component altogether than to remove the _last_ one and update all the others. + +To do that, we specify a unique _key_ for each iteration of the `each` block: ```svelte /// file: App.svelte @@ -22,6 +24,4 @@ To do that, we specify a unique identifier (or "key") for each iteration of the {/each} ``` -Here, `(thing.id)` is the _key_, which tells Svelte how to figure out what to update when the values (`name` in this example) change. - > You can use any object as the key, as Svelte uses a `Map` internally — in other words you could do `(thing)` instead of `(thing.id)`. Using a string or number is generally safer, however, since it means identity persists without referential equality, for example when updating with fresh data from an API server. diff --git a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/06-await-blocks/+assets/app-a/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/06-await-blocks/+assets/app-a/src/lib/App.svelte index a3030a8b34..c22595a531 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/06-await-blocks/+assets/app-a/src/lib/App.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/06-await-blocks/+assets/app-a/src/lib/App.svelte @@ -1,15 +1,11 @@ - -

...waiting

+

...rolling

diff --git a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/06-await-blocks/+assets/app-a/src/lib/utils.js b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/06-await-blocks/+assets/app-a/src/lib/utils.js index 5964cb852d..0bc02b4934 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/06-await-blocks/+assets/app-a/src/lib/utils.js +++ b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/06-await-blocks/+assets/app-a/src/lib/utils.js @@ -1,12 +1,15 @@ -export async function getRandomNumber() { - // Fetch a random number between 0 and 100 - // (with a delay, so that we can see it) - const res = await fetch('/random-number'); +export async function roll() { + // Fetch a random number between 0 and 6 + // (with a delay, so that we can see it) + return new Promise((fulfil, reject) => { + setTimeout(() => { + // simulate a flaky network + if (Math.random() < 0.3) { + reject(new Error('Request failed')); + return; + } - if (res.ok) { - return await res.text(); - } else { - // Sometimes the API will fail! - throw new Error('Request failed'); - } -} \ No newline at end of file + fulfil(Math.ceil(Math.random() * 6)); + }, 1000); + }); +} diff --git a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/06-await-blocks/+assets/app-a/src/routes/random-number/+server.js b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/06-await-blocks/+assets/app-a/src/routes/random-number/+server.js deleted file mode 100644 index e051d80bdf..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/06-await-blocks/+assets/app-a/src/routes/random-number/+server.js +++ /dev/null @@ -1,23 +0,0 @@ -export async function GET(req) { - const query = req.url.searchParams; - let min = query.get('min') || '0'; - let max = query.get('max') || '100'; - min = +min; - max = +max; - - // simulate a long delay - await new Promise((res) => setTimeout(res, 1000)); - - // fail sometimes - if (Math.random() < 0.333) { - return new Response(`Failed to generate random number. Please try again`, { - status: 400, - headers: { 'Access-Control-Allow-Origin': '*' } - }); - } - - const num = min + Math.round(Math.random() * (max - min)); - return new Response(String(num), { - headers: { 'Access-Control-Allow-Origin': '*' } - }); -} \ No newline at end of file diff --git a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/06-await-blocks/+assets/app-b/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/06-await-blocks/+assets/app-b/src/lib/App.svelte index c538f17a3b..e74efbe2c8 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/06-await-blocks/+assets/app-b/src/lib/App.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/06-await-blocks/+assets/app-b/src/lib/App.svelte @@ -1,21 +1,17 @@ - {#await promise} -

...waiting

+

...rolling

{:then number} -

The number is {number}

+

you rolled a {number}!

{:catch error}

{error.message}

{/await} diff --git a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/06-await-blocks/index.md b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/06-await-blocks/index.md index 37f5871b89..2ac78a3d6d 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/04-logic/06-await-blocks/index.md +++ b/apps/svelte.dev/content/tutorial/01-svelte/04-logic/06-await-blocks/index.md @@ -7,9 +7,9 @@ Most web applications have to deal with asynchronous data at some point. Svelte ```svelte /// file: App.svelte +++{#await promise}+++ -

...waiting

+

...rolling

+++{:then number} -

The number is {number}

+

you rolled a {number}!

{:catch error}

{error.message}

{/await}+++ @@ -22,6 +22,6 @@ If you know that your promise can't reject, you can omit the `catch` block. You ```svelte /// no-file {#await promise then number} -

The number is {number}

+

you rolled a {number}!

{/await} ``` diff --git a/apps/svelte.dev/content/tutorial/01-svelte/05-events/01-dom-events/+assets/app-a/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/05-events/01-dom-events/+assets/app-a/src/lib/App.svelte index e7ebb525c0..5ba72bd22e 100644 --- a/apps/svelte.dev/content/tutorial/01-svelte/05-events/01-dom-events/+assets/app-a/src/lib/App.svelte +++ b/apps/svelte.dev/content/tutorial/01-svelte/05-events/01-dom-events/+assets/app-a/src/lib/App.svelte @@ -1,14 +1,14 @@
- The pointer is at {m.x} x {m.y} + The pointer is at {Math.round(m.x)} x {Math.round(m.y)}
diff --git a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/01-onmount/+assets/app-a/src/lib/gradient.js b/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/01-onmount/+assets/app-a/src/lib/gradient.js deleted file mode 100644 index f0d28f3519..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/01-onmount/+assets/app-a/src/lib/gradient.js +++ /dev/null @@ -1,21 +0,0 @@ -export function paint(context, t) { - const { width, height } = context.canvas; - const imageData = context.getImageData(0, 0, width, height); - - for (let p = 0; p < imageData.data.length; p += 4) { - const i = p / 4; - const x = i % width; - const y = (i / width) >>> 0; - - const red = 64 + (128 * x) / width + 64 * Math.sin(t / 1000); - const green = 64 + (128 * y) / height + 64 * Math.cos(t / 1000); - const blue = 128; - - imageData.data[p + 0] = red; - imageData.data[p + 1] = green; - imageData.data[p + 2] = blue; - imageData.data[p + 3] = 255; - } - - context.putImageData(imageData, 0, 0); -} \ No newline at end of file diff --git a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/01-onmount/+assets/app-a/src/lib/svelte-logo-mask.svg b/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/01-onmount/+assets/app-a/src/lib/svelte-logo-mask.svg deleted file mode 100644 index 8572d3da6c..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/01-onmount/+assets/app-a/src/lib/svelte-logo-mask.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/01-onmount/+assets/app-b/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/01-onmount/+assets/app-b/src/lib/App.svelte deleted file mode 100644 index 1ee550fbc6..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/01-onmount/+assets/app-b/src/lib/App.svelte +++ /dev/null @@ -1,38 +0,0 @@ - - - - - diff --git a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/01-onmount/index.md b/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/01-onmount/index.md deleted file mode 100644 index 4195b5c693..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/01-onmount/index.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: onMount ---- - -Every component has a _lifecycle_ that starts when it is created, and ends when it is destroyed. There are a handful of functions that allow you to run code at key moments during that lifecycle. The one you'll use most frequently is `onMount`, which runs after the component is first rendered to the DOM. - -In this exercise, we have a `` that we'd like to animate, using the `paint` function in `gradient.js`. Begin by importing the `onMount` function from `svelte`: - -```svelte -/// file: App.svelte - -``` - -Then, add a callback that runs when the component mounts: - -```svelte -/// file: App.svelte - -``` - -> In a [later exercise](bind-this), we'll learn how to get an element reference without using `document.querySelector`. - -So far so good — you should see gently undulating colours in the shape of the Svelte logo. But there's one problem — the loop will continue even after the component has been destroyed. To fix that, we need to return a cleanup function from `onMount`: - -```js -/// file: App.svelte -onMount(() => { - const canvas = document.querySelector('canvas'); - const context = canvas.getContext('2d'); - - +++let frame =+++ requestAnimationFrame(function loop(t) { - +++frame =+++ requestAnimationFrame(loop); - paint(context, t); - }); - -+++ return () => { - cancelAnimationFrame(frame); - };+++ -}); -``` diff --git a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/02-update/+assets/app-a/package-lock.json b/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/02-update/+assets/app-a/package-lock.json deleted file mode 100644 index 7a7aadbb57..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/02-update/+assets/app-a/package-lock.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "~TODO~", - "version": "0.0.1", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "~TODO~", - "version": "0.0.1", - "dependencies": { - "elizabot": "^0.0.3" - } - }, - "node_modules/elizabot": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/elizabot/-/elizabot-0.0.3.tgz", - "integrity": "sha512-giwweEawiOHLS8eMPNtpLJaYxWZIHxtJcoq0NyvtEqVx2pxZ8XX1AXHHx84hUK3Scl8vk4U4lEatG54nsMZo+Q==" - } - }, - "dependencies": { - "elizabot": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/elizabot/-/elizabot-0.0.3.tgz", - "integrity": "sha512-giwweEawiOHLS8eMPNtpLJaYxWZIHxtJcoq0NyvtEqVx2pxZ8XX1AXHHx84hUK3Scl8vk4U4lEatG54nsMZo+Q==" - } - } -} diff --git a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/02-update/+assets/app-a/package.json b/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/02-update/+assets/app-a/package.json deleted file mode 100644 index ff635f4a7c..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/02-update/+assets/app-a/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "~TODO~", - "version": "0.0.1", - "scripts": { - "dev": "./node_modules/vite/bin/vite.js dev", - "build": "./node_modules/vite/bin/vite.js build", - "preview": "./node_modules/vite/bin/vite.js preview" - }, - "dependencies": { - "elizabot": "^0.0.3" - }, - "type": "module" -} diff --git a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/02-update/+assets/app-a/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/02-update/+assets/app-a/src/lib/App.svelte deleted file mode 100644 index 03d237aca3..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/02-update/+assets/app-a/src/lib/App.svelte +++ /dev/null @@ -1,169 +0,0 @@ - - -
-
-
-
-

Eliza

- -
- {eliza.getInitial()} -
-
- - {#each comments as comment} -
- {comment.text} -
- {/each} -
- - -
-
- - diff --git a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/02-update/+assets/app-b/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/02-update/+assets/app-b/src/lib/App.svelte deleted file mode 100644 index c80a29b933..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/02-update/+assets/app-b/src/lib/App.svelte +++ /dev/null @@ -1,174 +0,0 @@ - - -
-
-
-
-

Eliza

- -
- {eliza.getInitial()} -
-
- - {#each comments as comment} -
- {comment.text} -
- {/each} -
- - -
-
- - diff --git a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/02-update/index.md b/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/02-update/index.md deleted file mode 100644 index b126e5beb4..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/02-update/index.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: beforeUpdate and afterUpdate ---- - -The `beforeUpdate` function schedules work to happen immediately before the DOM is updated. `afterUpdate` is its counterpart, used for running code once the DOM is in sync with your data. - -Together, they're useful for doing things imperatively that are difficult to achieve in a purely state-driven way, like updating the scroll position of an element. - -This [Eliza](https://en.wikipedia.org/wiki/ELIZA) chatbot is annoying to use, because you have to keep scrolling the chat window. Let's fix that. - -```js -/// file: App.svelte -let div; -+++let autoscroll = false;+++ - -beforeUpdate(() => { -+++ if (div) { - const scrollableDistance = div.scrollHeight - div.offsetHeight; - autoscroll = div.scrollTop > scrollableDistance - 20; - }+++ -}); - -afterUpdate(() => { -+++ if (autoscroll) { - div.scrollTo(0, div.scrollHeight); - }+++ -}); -``` - -Note that `beforeUpdate` will first run before the component has mounted, so we need to check for the existence of `div` before reading its properties. diff --git a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/03-tick/+assets/app-a/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/03-tick/+assets/app-a/src/lib/App.svelte deleted file mode 100644 index e2c2e55699..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/03-tick/+assets/app-a/src/lib/App.svelte +++ /dev/null @@ -1,38 +0,0 @@ - - - - - diff --git a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/03-tick/+assets/app-b/src/lib/App.svelte b/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/03-tick/+assets/app-b/src/lib/App.svelte deleted file mode 100644 index c9a32a85ad..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/03-tick/+assets/app-b/src/lib/App.svelte +++ /dev/null @@ -1,40 +0,0 @@ - - - - - diff --git a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/03-tick/index.md b/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/03-tick/index.md deleted file mode 100644 index 78226bf14a..0000000000 --- a/apps/svelte.dev/content/tutorial/01-svelte/07-lifecycle/03-tick/index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: tick ---- - -The `tick` function is unlike other lifecycle functions in that you can call it any time, not just when the component first initialises. It returns a promise that resolves as soon as any pending state changes have been applied to the DOM (or immediately, if there are no pending state changes). - -When you update component state in Svelte, it doesn't update the DOM immediately. Instead, it waits until the next _microtask_ to see if there are any other changes that need to be applied, including in other components. Doing so avoids unnecessary work and allows the browser to batch things more effectively. - -You can see that behaviour in this example. Select a range of text and hit the tab key. Because the `