diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 9acc6de3f..cb004fcf5 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: - node-version: [18.x] + node-version: [20.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 000000000..0598ad131 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2023 [these people](https://github.com/sveltejs/learn.svelte.dev/graphs/contributors) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index d99fc947c..8866c4475 100644 --- a/README.md +++ b/README.md @@ -6,21 +6,21 @@ A soup-to-nuts interactive tutorial on how to build apps with Svelte. This repo uses [pnpm](https://pnpm.io/). -## Running the app +## Developing the app -First, run `node scripts/create-common-bundle`. This packages up everything that's needed to run a SvelteKit app (Vite, Esbuild, SvelteKit, Svelte compiler etc) which can subsequently be unpacked on a server to create and run and instance of a SvelteKit application (which powers the output window of the tutorial). +First, run `node scripts/create-common-bundle`. This packages up everything that's needed to run a SvelteKit app (Vite, esbuild, SvelteKit, Svelte compiler, etc.) which can subsequently be unpacked on a server to create and run an instance of a SvelteKit application (which powers the output window of the tutorial). Then, run `dev`: -The next steps depend on whether you want to run this locally in filesystem mode, or in WebContainer mode. For now, it works with filesystem mode only locally. In future, it will run both locally and on the web (using [WebContainers](https://blog.stackblitz.com/posts/introducing-webcontainers/)). +```bash +node scripts/create-common-bundle +pnpm dev +``` -### Local/filesystem mode +To build for production and run locally: -1. add an `.env` file with `PUBLIC_USE_FILESYSTEM=true` in it -2. Run the app locally with `pnpm dev` or `pnpm build && pnpm preview`. - -### WebContainer mode - -1. if an `.env` file exists, modify it so there's `PUBLIC_USE_FILESYSTEM=` in it -2. Run the app locally with `pnpm dev` or `pnpm build && pnpm preview`. +```bash +pnpm build +pnpm preview +``` ## Creating new tutorials @@ -28,4 +28,4 @@ Tutorials live inside `content`. Each tutorial consists of a `README.md`, which ## Bumping tutorial dependencies -Bump the dependency (for example Svelte) in both the root and the `content/common` `package.json`. In the root do `pnpm i` (to update `pnpm-lock.yaml`), in `content/common` do `npm i` (to update `package-lock.json`). After deployment things might be out of date because Vercel caches things, redeploy without cache in that case. +Bump the dependency (for example Svelte) in both the root and the `content/common` `package.json`. In the root do `pnpm i` (to update `pnpm-lock.yaml`), in `content/common` do `npm i` (to update `package-lock.json`). \ No newline at end of file diff --git a/backend/+server.js b/backend/+server.js deleted file mode 100644 index 951581de2..000000000 --- a/backend/+server.js +++ /dev/null @@ -1,14 +0,0 @@ -import { json } from '@sveltejs/kit'; -import { create } from './apps'; - -/** @type {import('./$types').RequestHandler} */ -export async function POST({ request }) { - return json( - await create({ - files: await request.json() - }), - { - status: 201 // should this be a 200? - } - ); -} diff --git a/backend/README.md b/backend/README.md deleted file mode 100644 index 39de3f70c..000000000 --- a/backend/README.md +++ /dev/null @@ -1 +0,0 @@ -This used to live in src/routes/backend, but it makes it impossible to use with edge functions. Keeping it here in case we need it in future. diff --git a/backend/[id]/+server.js b/backend/[id]/+server.js deleted file mode 100644 index 918ddfefd..000000000 --- a/backend/[id]/+server.js +++ /dev/null @@ -1,17 +0,0 @@ -import { clear, update } from '../apps'; - -/** @type {import('./$types').RequestHandler} */ -export async function PUT({ url, request, params }) { - const { id } = params; - const files = await request.json(); - - if (url.searchParams.has('reset')) { - clear({ id, files }); - } - - update({ id, files }); - - return new Response(undefined, { - status: 201 - }); -} diff --git a/backend/apps.js b/backend/apps.js deleted file mode 100644 index 80b0669d8..000000000 --- a/backend/apps.js +++ /dev/null @@ -1,208 +0,0 @@ -import fs from 'node:fs'; -import path from 'node:path'; -import { spawn } from 'node:child_process'; -import { createRequire } from 'node:module'; -import * as ports from 'port-authority'; -import { broadcast, ready } from './ws'; - -/** - * @typedef {{ - * process: import('child_process').ChildProcess, - * filenames: string[] - * }} App */ - -fs.rmSync('.apps', { recursive: true, force: true }); -fs.mkdirSync('.apps', { recursive: true }); - -// poor man's HMR, pending https://github.com/vitejs/vite/issues/7887 -// @ts-expect-error -if (globalThis.__apps) { - globalThis.__apps.forEach((app) => { - app.process.kill(); - }); -} - -const require = createRequire(import.meta.url); -const vite_pkg_file = require.resolve('vite/package.json'); -const vite_pkg = JSON.parse(fs.readFileSync(vite_pkg_file, 'utf-8')); -const vite = path.resolve(vite_pkg_file, '..', vite_pkg.bin['vite']); - -/** @type {Map} */ -const apps = new Map(); -globalThis.__apps = apps; - -const hooks_src = `/** @type {import('@sveltejs/kit').Handle} */ -export async function handle({ event, resolve }) { - const response = await resolve(event); - - response.headers.set('cross-origin-opener-policy', 'same-origin'); - response.headers.set('cross-origin-embedder-policy', 'require-corp'); - response.headers.set('cross-origin-resource-policy', 'cross-origin'); - - return response; -}`; - -/** - * @param {{ - * files: import('$lib/types').FileStub[] - * }} options - */ -export async function create({ files }) { - const id = String(Date.now()); - const filenames = write_files(id, files); - - // TODO this enables embedding on cross-origin sites, which is - // necessary for the JSNation talk, but will currently break if an app - // already has a src/hooks.server.js file (though it could be worked - // around easily enough if necessary) - if (!files.find((stub) => stub.name === '/src/hooks.server.js')) { - fs.writeFileSync(`.apps/${id}/src/hooks.server.js`, hooks_src); - } - - const port = await ports.find(3001); - - apps.set(id, { - process: launch(id, String(port)), - filenames - }); - - await ports.waitUntilBusy(port); - - await ready; - - return { - id, - port - }; -} - -/** - * @param {{ - * id: string; - * files: import('$lib/types').FileStub[] - * }} options - */ -export function clear({ id, files }) { - const app = apps.get(id); - - if (!app) { - throw new Error(`app ${id} does not exist`); - } - - const dir = `.apps/${id}`; - const old_filenames = new Set(app.filenames); - - /** @type {string[]} */ - const filenames = []; - - for (const file of files) { - if (file.type === 'file') { - filenames.push(file.name); - old_filenames.delete(file.name); - } - } - - for (const file of old_filenames) { - if (fs.existsSync(dir + file)) { - fs.unlinkSync(dir + file); - } - } - - app.filenames = filenames; -} - -/** - * @param {{ - * id: string; - * files: import('$lib/types').FileStub[] - * }} options - */ -export function update({ id, files }) { - if (!apps.has(id)) { - throw new Error(`app ${id} does not exist`); - } - - write_files(id, files); -} - -/** - * @param {{ id: string }} options - */ -export function destroy({ id }) { - const dir = `.apps/${id}`; - - fs.rmSync(dir, { recursive: true, force: true }); - - apps.get(id)?.process.kill(); - apps.delete(id); -} - -/** - * @param {string} id - * @param {string} port - */ -function launch(id, port) { - const cwd = `.apps/${id}`; - - const process = spawn('node', [vite, 'dev', '--port', port], { - cwd - }); - - process.stdout.on('data', (data) => { - broadcast({ id, data: data.toString(), type: 'stdout' }); - }); - - process.stderr.on('data', (data) => { - broadcast({ id, data: data.toString(), type: 'stderr' }); - }); - - return process; -} - -/** - * - * @param {string} file - * @param {string | Buffer} contents - */ -function write_if_changed(file, contents) { - if (typeof contents === 'string' && fs.existsSync(file)) { - const existing = fs.readFileSync(file, 'utf-8'); - if (contents === existing) return; - } - - fs.mkdirSync(path.dirname(file), { recursive: true }); - fs.writeFileSync(file, contents); -} - -/** - * - * @param {string} id - * @param {import('$lib/types').FileStub[]} files - */ -function write_files(id, files) { - const dir = `.apps/${id}`; - - /** @type {string[]} */ - const filenames = []; - - for (const file of files) { - if (file.type === 'file') { - filenames.push(file.name); - - const dest = `${dir}/${file.name}`; - let content = file.text ? file.contents : Buffer.from(file.contents, 'base64'); - - if (file.name === '/src/app.html' && typeof content === 'string') { - // TODO handle case where config.kit.files.template is different - content = content.replace( - '', - '' - ); - } - - write_if_changed(dest, content); - } - } - - return filenames; -} diff --git a/backend/destroy/+server.js b/backend/destroy/+server.js deleted file mode 100644 index ad9c89efd..000000000 --- a/backend/destroy/+server.js +++ /dev/null @@ -1,14 +0,0 @@ -import { destroy } from '../apps'; - -// this is implemented as a POST handler because it is -// triggered by `navigator.sendBeacon` rather than `fetch` - -/** @type {import('./$types').RequestHandler} */ -export function POST({ url }) { - const id = /** @type {string} */ (url.searchParams.get('id')); - destroy({ id }); - - return new Response(undefined, { - status: 204 - }); -} diff --git a/backend/ws.js b/backend/ws.js deleted file mode 100644 index e02317c0d..000000000 --- a/backend/ws.js +++ /dev/null @@ -1,33 +0,0 @@ -// import './websocket.js'; -import { WebSocketServer } from 'ws'; - -// poor man's HMR, pending https://github.com/vitejs/vite/issues/7887 -// @ts-expect-error -if (globalThis.__wss) globalThis.__wss.close(); - -const wss = new WebSocketServer({ port: 4567 }); -globalThis.__wss = wss; - -/** @type {Set} */ -const connections = new Set(); - -wss.on('connection', (ws) => { - connections.add(ws); - - ws.on('close', () => { - connections.delete(ws); - }); -}); - -export const ready = new Promise((fulfil) => { - wss.on('listening', () => { - fulfil(undefined); - }); -}); - -/** @param {any} data */ -export function broadcast(data) { - for (const connection of connections) { - connection.send(JSON.stringify(data)); - } -} diff --git a/content/tutorial/01-svelte/01-introduction/01-welcome-to-svelte/README.md b/content/tutorial/01-svelte/01-introduction/01-welcome-to-svelte/README.md index 14105cdf0..0701a6901 100644 --- a/content/tutorial/01-svelte/01-introduction/01-welcome-to-svelte/README.md +++ b/content/tutorial/01-svelte/01-introduction/01-welcome-to-svelte/README.md @@ -20,9 +20,9 @@ You can build your entire app with Svelte (for example, using an application fra This tutorial is split into four main parts: -- [Welcome to Svelte](/tutorial/welcome-to-svelte) (you are here) -- [Introduction to SvelteKit](/tutorial/introducing-sveltekit) +- [Basic Svelte](/tutorial/welcome-to-svelte) (you are here) - [Advanced Svelte](/tutorial/tweens) +- [Basic SvelteKit](/tutorial/introducing-sveltekit) - [Advanced SvelteKit](/tutorial/optional-params) Each section will present an exercise designed to illustrate a feature. Later exercises build on the knowledge gained in earlier ones, so it's recommended that you go from start to finish. If necessary, you can navigate via the menu above. diff --git a/content/tutorial/01-svelte/01-introduction/03-dynamic-attributes/README.md b/content/tutorial/01-svelte/01-introduction/03-dynamic-attributes/README.md index e03524b1a..6c325239f 100644 --- a/content/tutorial/01-svelte/01-introduction/03-dynamic-attributes/README.md +++ b/content/tutorial/01-svelte/01-introduction/03-dynamic-attributes/README.md @@ -32,5 +32,5 @@ It's not uncommon to have an attribute where the name and value are the same, li ```svelte /// file: App.svelte -A man dances. +{name} dances. ``` diff --git a/content/tutorial/03-advanced-svelte/11-special-tags/02-html-tags/README.md b/content/tutorial/01-svelte/01-introduction/06-html-tags/README.md similarity index 60% rename from content/tutorial/03-advanced-svelte/11-special-tags/02-html-tags/README.md rename to content/tutorial/01-svelte/01-introduction/06-html-tags/README.md index 914e76bbf..801b22a1d 100644 --- a/content/tutorial/03-advanced-svelte/11-special-tags/02-html-tags/README.md +++ b/content/tutorial/01-svelte/01-introduction/06-html-tags/README.md @@ -13,4 +13,4 @@ In Svelte, you do this with the special `{@html ...}` tag:

{+++@html+++ string}

``` -> **Warning!** Svelte doesn't perform any sanitization of the expression inside `{@html ...}` before it gets inserted into the DOM. In other words, if you use this feature it's critical that you manually escape HTML that comes from sources you don't trust, otherwise you risk exposing your users to Cross-Site Scripting (XSS) attacks. +> **Warning!** Svelte doesn't perform any sanitization of the expression inside `{@html ...}` before it gets inserted into the DOM. This isn't an issue if the content is something you trust like an article you wrote yourself. However if it's some untrusted user content, e.g. a comment on an article, then it's critical that you manually escape it, otherwise you risk exposing your users to Cross-Site Scripting (XSS) attacks. diff --git a/content/tutorial/03-advanced-svelte/11-special-tags/02-html-tags/app-a/src/lib/App.svelte b/content/tutorial/01-svelte/01-introduction/06-html-tags/app-a/src/lib/App.svelte similarity index 100% rename from content/tutorial/03-advanced-svelte/11-special-tags/02-html-tags/app-a/src/lib/App.svelte rename to content/tutorial/01-svelte/01-introduction/06-html-tags/app-a/src/lib/App.svelte diff --git a/content/tutorial/03-advanced-svelte/11-special-tags/02-html-tags/app-b/src/lib/App.svelte b/content/tutorial/01-svelte/01-introduction/06-html-tags/app-b/src/lib/App.svelte similarity index 100% rename from content/tutorial/03-advanced-svelte/11-special-tags/02-html-tags/app-b/src/lib/App.svelte rename to content/tutorial/01-svelte/01-introduction/06-html-tags/app-b/src/lib/App.svelte diff --git a/content/tutorial/01-svelte/02-reactivity/02-reactive-declarations/README.md b/content/tutorial/01-svelte/02-reactivity/02-reactive-declarations/README.md index 16fb5dfb1..0ef6f276f 100644 --- a/content/tutorial/01-svelte/02-reactivity/02-reactive-declarations/README.md +++ b/content/tutorial/01-svelte/02-reactivity/02-reactive-declarations/README.md @@ -12,6 +12,8 @@ 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: @@ -24,3 +26,5 @@ Let's use `doubled` in our markup: ``` 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/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/README.md b/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/README.md index 74e3a581f..49e0654ab 100644 --- a/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/README.md +++ b/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/README.md @@ -38,8 +38,9 @@ A simple rule of thumb: the name of the updated variable must appear on the left ```js /// no-file +const obj = { foo: { bar: 1 } }; const foo = obj.foo; -foo.bar = 'baz'; +foo.bar = 2; ``` ...won't trigger reactivity on `obj.foo.bar`, unless you follow it up with `obj = obj`. diff --git a/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/app-a/src/lib/App.svelte b/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/app-a/src/lib/App.svelte index 77d176923..ab6ef7074 100644 --- a/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/app-a/src/lib/App.svelte +++ b/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/app-a/src/lib/App.svelte @@ -5,7 +5,7 @@ numbers.push(numbers.length + 1); } - $: sum = numbers.reduce((t, n) => t + n, 0); + $: sum = numbers.reduce((total, currentNumber) => total + currentNumber, 0);

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

diff --git a/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/app-b/src/lib/App.svelte b/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/app-b/src/lib/App.svelte index d15f58c4d..730ae8cc7 100644 --- a/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/app-b/src/lib/App.svelte +++ b/content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/app-b/src/lib/App.svelte @@ -5,7 +5,7 @@ numbers = [...numbers, numbers.length + 1]; } - $: sum = numbers.reduce((t, n) => t + n, 0); + $: sum = numbers.reduce((total, currentNumber) => total + currentNumber, 0);

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

diff --git a/content/tutorial/01-svelte/03-props/03-spread-props/app-a/src/lib/App.svelte b/content/tutorial/01-svelte/03-props/03-spread-props/app-a/src/lib/App.svelte index 4fb555240..2d5d7123b 100644 --- a/content/tutorial/01-svelte/03-props/03-spread-props/app-a/src/lib/App.svelte +++ b/content/tutorial/01-svelte/03-props/03-spread-props/app-a/src/lib/App.svelte @@ -4,7 +4,7 @@ const pkg = { name: 'svelte', speed: 'blazing', - version: 3, + version: 4, website: 'https://svelte.dev' }; diff --git a/content/tutorial/01-svelte/03-props/03-spread-props/app-b/src/lib/App.svelte b/content/tutorial/01-svelte/03-props/03-spread-props/app-b/src/lib/App.svelte index 5934bdabf..3ded4fd56 100644 --- a/content/tutorial/01-svelte/03-props/03-spread-props/app-b/src/lib/App.svelte +++ b/content/tutorial/01-svelte/03-props/03-spread-props/app-b/src/lib/App.svelte @@ -4,7 +4,7 @@ const pkg = { name: 'svelte', speed: 'blazing', - version: 3, + version: 4, website: 'https://svelte.dev' }; diff --git a/content/tutorial/01-svelte/04-logic/01-if-blocks/README.md b/content/tutorial/01-svelte/04-logic/01-if-blocks/README.md index 810bc08dd..845b4ab99 100644 --- a/content/tutorial/01-svelte/04-logic/01-if-blocks/README.md +++ b/content/tutorial/01-svelte/04-logic/01-if-blocks/README.md @@ -4,21 +4,18 @@ title: If blocks HTML doesn't have a way of expressing _logic_, like conditionals and loops. Svelte does. -To conditionally render some markup, we wrap it in an `if` block: +To conditionally render some markup, we wrap it in an `if` block. Let's add some text that appears when `count` is greater than `10`: ```svelte /// file: App.svelte -+++{#if user.loggedIn}+++ - -+++{/if}+++ + -+++{#if !user.loggedIn}+++ - -+++{/if}+++ ++++{#if count > 10} +

{count} is greater than 10

+{/if}+++ ``` -Try it — update the component, and click on the buttons. +Try it — update the component, and click on the button. diff --git a/content/tutorial/01-svelte/04-logic/01-if-blocks/app-a/src/lib/App.svelte b/content/tutorial/01-svelte/04-logic/01-if-blocks/app-a/src/lib/App.svelte index b955f6d0d..bb0ebe43a 100644 --- a/content/tutorial/01-svelte/04-logic/01-if-blocks/app-a/src/lib/App.svelte +++ b/content/tutorial/01-svelte/04-logic/01-if-blocks/app-a/src/lib/App.svelte @@ -1,15 +1,12 @@ - - - diff --git a/content/tutorial/01-svelte/04-logic/01-if-blocks/app-b/src/lib/App.svelte b/content/tutorial/01-svelte/04-logic/01-if-blocks/app-b/src/lib/App.svelte index 08f672877..6f6ab28d2 100644 --- a/content/tutorial/01-svelte/04-logic/01-if-blocks/app-b/src/lib/App.svelte +++ b/content/tutorial/01-svelte/04-logic/01-if-blocks/app-b/src/lib/App.svelte @@ -1,19 +1,16 @@ -{#if user.loggedIn} - -{/if} + -{#if !user.loggedIn} - -{/if} +{#if count > 10} +

{count} is greater than 10

+{/if} \ No newline at end of file diff --git a/content/tutorial/01-svelte/04-logic/02-else-blocks/README.md b/content/tutorial/01-svelte/04-logic/02-else-blocks/README.md index 0dde395e4..f342c1188 100644 --- a/content/tutorial/01-svelte/04-logic/02-else-blocks/README.md +++ b/content/tutorial/01-svelte/04-logic/02-else-blocks/README.md @@ -2,18 +2,14 @@ title: Else blocks --- -Since the two conditions — `if user.loggedIn` and `if !user.loggedIn` — are mutually exclusive, we can simplify this component slightly by using an `else` block: +Just like in JavaScript, an `if` block can have an `else` block: ```svelte /// file: App.svelte -{#if user.loggedIn} - -+++{:else}+++ - +{#if count > 10} +

{count} is greater than 10

++++{:else} +

{count} is between 0 and 10

+++ {/if} ``` diff --git a/content/tutorial/01-svelte/04-logic/02-else-blocks/app-a/src/lib/App.svelte b/content/tutorial/01-svelte/04-logic/02-else-blocks/app-a/src/lib/App.svelte deleted file mode 100644 index 08f672877..000000000 --- a/content/tutorial/01-svelte/04-logic/02-else-blocks/app-a/src/lib/App.svelte +++ /dev/null @@ -1,19 +0,0 @@ - - -{#if user.loggedIn} - -{/if} - -{#if !user.loggedIn} - -{/if} diff --git a/content/tutorial/01-svelte/04-logic/02-else-blocks/app-b/src/lib/App.svelte b/content/tutorial/01-svelte/04-logic/02-else-blocks/app-b/src/lib/App.svelte index 8e3195685..d82dadb10 100644 --- a/content/tutorial/01-svelte/04-logic/02-else-blocks/app-b/src/lib/App.svelte +++ b/content/tutorial/01-svelte/04-logic/02-else-blocks/app-b/src/lib/App.svelte @@ -1,17 +1,18 @@ -{#if user.loggedIn} - + + +{#if count > 10} +

{count} is greater than 10

{:else} - -{/if} +

{count} is between 0 and 10

+{/if} \ No newline at end of file diff --git a/content/tutorial/01-svelte/04-logic/03-else-if-blocks/README.md b/content/tutorial/01-svelte/04-logic/03-else-if-blocks/README.md index ae5cf0a31..22ea202a9 100644 --- a/content/tutorial/01-svelte/04-logic/03-else-if-blocks/README.md +++ b/content/tutorial/01-svelte/04-logic/03-else-if-blocks/README.md @@ -6,11 +6,11 @@ Multiple conditions can be 'chained' together with `else if`: ```svelte /// file: App.svelte -{#if x > 10} -

{x} is greater than 10

-{:+++else if+++ x < 5} -

{x} is less than 5

+{#if count > 10} +

{count} is greater than 10

++++{:else if count < 5} +

{count} is less than 5

+++ {:else} -

{x} is between 5 and 10

+

{count} is between +++5+++ and 10

{/if} ``` diff --git a/content/tutorial/01-svelte/04-logic/03-else-if-blocks/app-a/src/lib/App.svelte b/content/tutorial/01-svelte/04-logic/03-else-if-blocks/app-a/src/lib/App.svelte deleted file mode 100644 index 205f8a437..000000000 --- a/content/tutorial/01-svelte/04-logic/03-else-if-blocks/app-a/src/lib/App.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - - - -{#if x > 10} -

{x} is greater than 10

-{:else} - {#if x < 5} -

{x} is less than 5

- {:else} -

{x} is between 5 and 10

- {/if} -{/if} \ No newline at end of file diff --git a/content/tutorial/01-svelte/04-logic/03-else-if-blocks/app-b/src/lib/App.svelte b/content/tutorial/01-svelte/04-logic/03-else-if-blocks/app-b/src/lib/App.svelte index a9b86fa92..0f52805e6 100644 --- a/content/tutorial/01-svelte/04-logic/03-else-if-blocks/app-b/src/lib/App.svelte +++ b/content/tutorial/01-svelte/04-logic/03-else-if-blocks/app-b/src/lib/App.svelte @@ -1,13 +1,20 @@ - + -{#if x > 10} -

{x} is greater than 10

-{:else if x < 5} -

{x} is less than 5

+{#if count > 10} +

{count} is greater than 10

+{:else if count < 5} +

{count} is less than 5

{:else} -

{x} is between 5 and 10

+

{count} is between 5 and 10

{/if} \ No newline at end of file diff --git a/content/tutorial/01-svelte/04-logic/04-each-blocks/README.md b/content/tutorial/01-svelte/04-logic/04-each-blocks/README.md index a098d9e75..3011cbb8f 100644 --- a/content/tutorial/01-svelte/04-logic/04-each-blocks/README.md +++ b/content/tutorial/01-svelte/04-logic/04-each-blocks/README.md @@ -2,34 +2,54 @@ title: Each blocks --- -If you need to loop over lists of data, use an `each` block: +When building user interfaces you'll often find yourself working with lists of data. In this exercise, we've repeated the ` +++{/each}+++ - + ``` -> The expression (`cats`, 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 array or array-like object (i.e. it has a `length` property). You can loop over generic iterables with `each [...iterable]`. -You can get the current _index_ as a second argument, like so: +Now we need to use the `color` variable in place of `"red"`: ```svelte /// file: App.svelte -{#each cats as cat+++, i}+++ -
  • - - +++{i + 1}:+++ {cat.name} - -
  • -{/each} +
    + {#each colors as color} + + {/each} +
    ``` -If you prefer, you can use destructuring — `each cats as { id, name }` — and replace `cat.id` and `cat.name` with `id` and `name`. +You can get the current _index_ as a second argument, like so: + +```svelte +/// file: App.svelte +
    + {#each colors as color, +++i}+++ + + {/each} +
    +``` diff --git a/content/tutorial/01-svelte/04-logic/04-each-blocks/app-a/src/lib/App.svelte b/content/tutorial/01-svelte/04-logic/04-each-blocks/app-a/src/lib/App.svelte index 501254eb1..e469ed718 100644 --- a/content/tutorial/01-svelte/04-logic/04-each-blocks/app-a/src/lib/App.svelte +++ b/content/tutorial/01-svelte/04-logic/04-each-blocks/app-a/src/lib/App.svelte @@ -1,28 +1,63 @@ -

    The Famous Cats of YouTube

    - - +

    Pick a colour

    + +
    + + + + + + + + + + + +
    + + \ No newline at end of file diff --git a/content/tutorial/01-svelte/04-logic/04-each-blocks/app-b/src/lib/App.svelte b/content/tutorial/01-svelte/04-logic/04-each-blocks/app-b/src/lib/App.svelte index 7d5d7187a..468d57b50 100644 --- a/content/tutorial/01-svelte/04-logic/04-each-blocks/app-b/src/lib/App.svelte +++ b/content/tutorial/01-svelte/04-logic/04-each-blocks/app-b/src/lib/App.svelte @@ -1,28 +1,45 @@ -

    The Famous Cats of YouTube

    +

    Pick a colour

    - + + + \ No newline at end of file diff --git a/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/README.md b/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/README.md index 2a63b3bb8..a87e34367 100644 --- a/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/README.md +++ b/content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/README.md @@ -2,13 +2,18 @@ title: Keyed each blocks --- -By default, when you modify the value of an `each` block, it will add and remove items at the _end_ of the block, and update any values that have changed. That might not be what you want. +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. Click the 'Remove first thing' button a few times, and notice what happens: It removes the first `` component, but the _last_ DOM node. Then it updates the `name` value in the remaining DOM nodes, but not the emoji, which in `Thing.svelte` is fixed when the component is created. +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. + +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. Instead, we'd like to remove only the first `` component and its DOM node, and leave the others unaffected. -To do that, we specify a unique identifier (or "key") for the `each` block: +To do that, we specify a unique identifier (or "key") for each iteration of the `each` block: ```svelte /// file: App.svelte @@ -17,6 +22,6 @@ To do that, we specify a unique identifier (or "key") for the `each` block: {/each} ``` -Here, `(thing.id)` is the _key_, which tells Svelte how to figure out which DOM node to change when the component updates. +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/content/tutorial/01-svelte/04-logic/06-await-blocks/README.md b/content/tutorial/01-svelte/04-logic/06-await-blocks/README.md index 4cd0b0ee1..37f5871b8 100644 --- a/content/tutorial/01-svelte/04-logic/06-await-blocks/README.md +++ b/content/tutorial/01-svelte/04-logic/06-await-blocks/README.md @@ -6,13 +6,13 @@ Most web applications have to deal with asynchronous data at some point. Svelte ```svelte /// file: App.svelte -{#await promise} ++++{#await promise}+++

    ...waiting

    -{:then number} ++++{:then number}

    The number is {number}

    {:catch error}

    {error.message}

    -{/await} +{/await}+++ ``` > Only the most recent `promise` is considered, meaning you don't need to worry about race conditions. @@ -20,7 +20,7 @@ Most web applications have to deal with asynchronous data at some point. Svelte If you know that your promise can't reject, you can omit the `catch` block. You can also omit the first block if you don't want to show anything until the promise resolves: ```svelte -/// file: App.svelte +/// no-file {#await promise then number}

    The number is {number}

    {/await} diff --git a/content/tutorial/01-svelte/04-logic/06-await-blocks/app-a/src/lib/App.svelte b/content/tutorial/01-svelte/04-logic/06-await-blocks/app-a/src/lib/App.svelte index 7af6f29b5..a3030a8b3 100644 --- a/content/tutorial/01-svelte/04-logic/06-await-blocks/app-a/src/lib/App.svelte +++ b/content/tutorial/01-svelte/04-logic/06-await-blocks/app-a/src/lib/App.svelte @@ -1,16 +1,5 @@
    - The mouse position is {m.x} x {m.y} + The pointer is at {m.x} x {m.y}
    diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-b/src/lib/App.svelte b/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-b/src/lib/App.svelte deleted file mode 100644 index ccfaad4c2..000000000 --- a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-b/src/lib/App.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - -{@html marked(value)} - - + ``` In cases like these, where the names match, we can also use a shorthand form: ```svelte /// file: App.svelte - + ``` This applies to all bindings, not just textareas. diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/.bin/marked b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/.bin/marked similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/.bin/marked rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/.bin/marked diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/LICENSE.md b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/LICENSE.md similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/LICENSE.md rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/LICENSE.md diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/README.md b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/README.md similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/README.md rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/README.md diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/bin/marked.js b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/bin/marked.js similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/bin/marked.js rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/bin/marked.js diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/lib/marked.cjs b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/lib/marked.cjs similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/lib/marked.cjs rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/lib/marked.cjs diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/lib/marked.esm.js b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/lib/marked.esm.js similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/lib/marked.esm.js rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/lib/marked.esm.js diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/lib/marked.umd.js b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/lib/marked.umd.js similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/lib/marked.umd.js rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/lib/marked.umd.js diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/man/marked.1 b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/man/marked.1 similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/man/marked.1 rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/man/marked.1 diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/man/marked.1.txt b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/man/marked.1.txt similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/man/marked.1.txt rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/man/marked.1.txt diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/marked.min.js b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/marked.min.js similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/marked.min.js rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/marked.min.js diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/package.json b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/package.json similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/package.json rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/package.json diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/Lexer.js b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/Lexer.js similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/Lexer.js rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/Lexer.js diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/Parser.js b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/Parser.js similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/Parser.js rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/Parser.js diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/Renderer.js b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/Renderer.js similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/Renderer.js rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/Renderer.js diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/Slugger.js b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/Slugger.js similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/Slugger.js rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/Slugger.js diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/TextRenderer.js b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/TextRenderer.js similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/TextRenderer.js rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/TextRenderer.js diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/Tokenizer.js b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/Tokenizer.js similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/Tokenizer.js rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/Tokenizer.js diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/defaults.js b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/defaults.js similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/defaults.js rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/defaults.js diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/helpers.js b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/helpers.js similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/helpers.js rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/helpers.js diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/marked.js b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/marked.js similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/marked.js rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/marked.js diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/rules.js b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/rules.js similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/node_modules/marked/src/rules.js rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/node_modules/marked/src/rules.js diff --git a/content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/package.json b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/package.json similarity index 100% rename from content/tutorial/01-svelte/06-bindings/05-textarea-inputs/app-a/package.json rename to content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/package.json diff --git a/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/src/lib/App.svelte b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/src/lib/App.svelte new file mode 100644 index 000000000..8672d898f --- /dev/null +++ b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-a/src/lib/App.svelte @@ -0,0 +1,27 @@ + + +
    + input + + + output +
    {@html marked(value)}
    +
    + + diff --git a/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-b/src/lib/App.svelte b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-b/src/lib/App.svelte new file mode 100644 index 000000000..27e2ef0fe --- /dev/null +++ b/content/tutorial/01-svelte/06-bindings/07-textarea-inputs/app-b/src/lib/App.svelte @@ -0,0 +1,27 @@ + + +
    + input + + + output +
    {@html marked(value)}
    +
    + + diff --git a/content/tutorial/01-svelte/07-lifecycle/01-onmount/README.md b/content/tutorial/01-svelte/07-lifecycle/01-onmount/README.md index 4a1cfa630..4195b5c69 100644 --- a/content/tutorial/01-svelte/07-lifecycle/01-onmount/README.md +++ b/content/tutorial/01-svelte/07-lifecycle/01-onmount/README.md @@ -2,30 +2,55 @@ title: onMount --- -> The images in this exercise don't currently work. You can switch to the old tutorial instead: https://svelte.dev/tutorial/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. -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. +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`: -The one you'll use most frequently is `onMount`, which runs after the component is first rendered to the DOM. +```svelte +/// file: App.svelte + +``` -We'll add an `onMount` handler that loads some data over the network: +Then, add a callback that runs when the component mounts: ```svelte /// file: App.svelte ``` -> It's recommended to put the `fetch` in `onMount` rather than at the top level of the ` -

    Photo album

    - -
    - {#each photos as photo} -
    - {photo.title} -
    {photo.title}
    -
    - {:else} - -

    loading...

    - {/each} -
    + diff --git a/content/tutorial/01-svelte/07-lifecycle/01-onmount/app-a/src/lib/gradient.js b/content/tutorial/01-svelte/07-lifecycle/01-onmount/app-a/src/lib/gradient.js new file mode 100644 index 000000000..f0d28f351 --- /dev/null +++ b/content/tutorial/01-svelte/07-lifecycle/01-onmount/app-a/src/lib/gradient.js @@ -0,0 +1,21 @@ +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/content/tutorial/01-svelte/07-lifecycle/01-onmount/app-a/src/lib/svelte-logo-mask.svg b/content/tutorial/01-svelte/07-lifecycle/01-onmount/app-a/src/lib/svelte-logo-mask.svg new file mode 100644 index 000000000..8572d3da6 --- /dev/null +++ b/content/tutorial/01-svelte/07-lifecycle/01-onmount/app-a/src/lib/svelte-logo-mask.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/content/tutorial/01-svelte/07-lifecycle/01-onmount/app-b/src/lib/App.svelte b/content/tutorial/01-svelte/07-lifecycle/01-onmount/app-b/src/lib/App.svelte index c074739b0..1ee550fbc 100644 --- a/content/tutorial/01-svelte/07-lifecycle/01-onmount/app-b/src/lib/App.svelte +++ b/content/tutorial/01-svelte/07-lifecycle/01-onmount/app-b/src/lib/App.svelte @@ -1,44 +1,38 @@ -

    Photo album

    - -
    - {#each photos as photo} -
    - {photo.title} -
    {photo.title}
    -
    - {:else} - -

    loading...

    - {/each} -
    + diff --git a/content/tutorial/01-svelte/07-lifecycle/02-ondestroy/README.md b/content/tutorial/01-svelte/07-lifecycle/02-ondestroy/README.md deleted file mode 100644 index 67e0a05ff..000000000 --- a/content/tutorial/01-svelte/07-lifecycle/02-ondestroy/README.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: onDestroy ---- - -To run code when your component is destroyed, use `onDestroy`. - -For example, we can add a `setInterval` function when our component initialises, and clean it up when it's no longer relevant. Doing so prevents memory leaks. - -```svelte -/// file: Timer.svelte - -``` - -While it's important to call lifecycle functions during the component's initialisation, it doesn't matter _where_ you call them from. So if we wanted, we could abstract the interval logic into a helper function in `utils.js`... - -```js -/// no-file -import { onDestroy } from 'svelte'; - -export function onInterval(callback, milliseconds) { - const interval = setInterval(callback, milliseconds); - - onDestroy(() => { - clearInterval(interval); - }); -} -``` - -...and import it into our component: - -```svelte -/// no-file - -``` - -Open and close the timer a few times and make sure the counter keeps ticking and the CPU load increases. This is due to a memory leak as the previous timers are not deleted. Don't forget to refresh the page before solving the example. diff --git a/content/tutorial/01-svelte/07-lifecycle/02-ondestroy/app-a/src/lib/App.svelte b/content/tutorial/01-svelte/07-lifecycle/02-ondestroy/app-a/src/lib/App.svelte deleted file mode 100644 index 50c2425bf..000000000 --- a/content/tutorial/01-svelte/07-lifecycle/02-ondestroy/app-a/src/lib/App.svelte +++ /dev/null @@ -1,23 +0,0 @@ - - -
    - -

    - The Timer component has been open for - {seconds} - {seconds === 1 ? 'second' : 'seconds'} -

    - {#if open} - - {/if} -
    diff --git a/content/tutorial/01-svelte/07-lifecycle/02-ondestroy/app-a/src/lib/Timer.svelte b/content/tutorial/01-svelte/07-lifecycle/02-ondestroy/app-a/src/lib/Timer.svelte deleted file mode 100644 index 1e745e6aa..000000000 --- a/content/tutorial/01-svelte/07-lifecycle/02-ondestroy/app-a/src/lib/Timer.svelte +++ /dev/null @@ -1,17 +0,0 @@ - - -

    This component executes a callback every {interval}ms

    - - diff --git a/content/tutorial/01-svelte/07-lifecycle/02-ondestroy/app-a/src/lib/utils.js b/content/tutorial/01-svelte/07-lifecycle/02-ondestroy/app-a/src/lib/utils.js deleted file mode 100644 index e46039fc3..000000000 --- a/content/tutorial/01-svelte/07-lifecycle/02-ondestroy/app-a/src/lib/utils.js +++ /dev/null @@ -1,9 +0,0 @@ -import { onDestroy } from 'svelte'; - -export function onInterval(callback, milliseconds) { - const interval = setInterval(callback, milliseconds); - - onDestroy(() => { - // Fix the memory leak here - }); -} diff --git a/content/tutorial/01-svelte/07-lifecycle/02-ondestroy/app-b/src/lib/utils.js b/content/tutorial/01-svelte/07-lifecycle/02-ondestroy/app-b/src/lib/utils.js deleted file mode 100644 index 42423ff32..000000000 --- a/content/tutorial/01-svelte/07-lifecycle/02-ondestroy/app-b/src/lib/utils.js +++ /dev/null @@ -1,9 +0,0 @@ -import { onDestroy } from 'svelte'; - -export function onInterval(callback, milliseconds) { - const interval = setInterval(callback, milliseconds); - - onDestroy(() => { - clearInterval(interval); - }); -} diff --git a/content/tutorial/01-svelte/07-lifecycle/03-update/README.md b/content/tutorial/01-svelte/07-lifecycle/02-update/README.md similarity index 76% rename from content/tutorial/01-svelte/07-lifecycle/03-update/README.md rename to content/tutorial/01-svelte/07-lifecycle/02-update/README.md index 2df6d34f7..b126e5beb 100644 --- a/content/tutorial/01-svelte/07-lifecycle/03-update/README.md +++ b/content/tutorial/01-svelte/07-lifecycle/02-update/README.md @@ -11,14 +11,19 @@ This [Eliza](https://en.wikipedia.org/wiki/ELIZA) chatbot is annoying to use, be ```js /// file: App.svelte let div; -let autoscroll; ++++let autoscroll = false;+++ beforeUpdate(() => { - autoscroll = div && div.offsetHeight + div.scrollTop > div.scrollHeight - 20; ++++ if (div) { + const scrollableDistance = div.scrollHeight - div.offsetHeight; + autoscroll = div.scrollTop > scrollableDistance - 20; + }+++ }); afterUpdate(() => { - if (autoscroll) div.scrollTo(0, div.scrollHeight); ++++ if (autoscroll) { + div.scrollTo(0, div.scrollHeight); + }+++ }); ``` diff --git a/content/tutorial/01-svelte/07-lifecycle/03-update/app-a/node_modules/.package-lock.json b/content/tutorial/01-svelte/07-lifecycle/02-update/app-a/node_modules/.package-lock.json similarity index 100% rename from content/tutorial/01-svelte/07-lifecycle/03-update/app-a/node_modules/.package-lock.json rename to content/tutorial/01-svelte/07-lifecycle/02-update/app-a/node_modules/.package-lock.json diff --git a/content/tutorial/01-svelte/07-lifecycle/03-update/app-a/node_modules/elizabot/.eslintrc.json b/content/tutorial/01-svelte/07-lifecycle/02-update/app-a/node_modules/elizabot/.eslintrc.json similarity index 100% rename from content/tutorial/01-svelte/07-lifecycle/03-update/app-a/node_modules/elizabot/.eslintrc.json rename to content/tutorial/01-svelte/07-lifecycle/02-update/app-a/node_modules/elizabot/.eslintrc.json diff --git a/content/tutorial/01-svelte/07-lifecycle/03-update/app-a/node_modules/elizabot/README.md b/content/tutorial/01-svelte/07-lifecycle/02-update/app-a/node_modules/elizabot/README.md similarity index 100% rename from content/tutorial/01-svelte/07-lifecycle/03-update/app-a/node_modules/elizabot/README.md rename to content/tutorial/01-svelte/07-lifecycle/02-update/app-a/node_modules/elizabot/README.md diff --git a/content/tutorial/01-svelte/07-lifecycle/03-update/app-a/node_modules/elizabot/elizabot.js b/content/tutorial/01-svelte/07-lifecycle/02-update/app-a/node_modules/elizabot/elizabot.js similarity index 100% rename from content/tutorial/01-svelte/07-lifecycle/03-update/app-a/node_modules/elizabot/elizabot.js rename to content/tutorial/01-svelte/07-lifecycle/02-update/app-a/node_modules/elizabot/elizabot.js diff --git a/content/tutorial/01-svelte/07-lifecycle/03-update/app-a/node_modules/elizabot/elizadata.js b/content/tutorial/01-svelte/07-lifecycle/02-update/app-a/node_modules/elizabot/elizadata.js similarity index 100% rename from content/tutorial/01-svelte/07-lifecycle/03-update/app-a/node_modules/elizabot/elizadata.js rename to content/tutorial/01-svelte/07-lifecycle/02-update/app-a/node_modules/elizabot/elizadata.js diff --git a/content/tutorial/01-svelte/07-lifecycle/03-update/app-a/node_modules/elizabot/package.json b/content/tutorial/01-svelte/07-lifecycle/02-update/app-a/node_modules/elizabot/package.json similarity index 100% rename from content/tutorial/01-svelte/07-lifecycle/03-update/app-a/node_modules/elizabot/package.json rename to content/tutorial/01-svelte/07-lifecycle/02-update/app-a/node_modules/elizabot/package.json diff --git a/content/tutorial/01-svelte/07-lifecycle/03-update/app-a/package-lock.json b/content/tutorial/01-svelte/07-lifecycle/02-update/app-a/package-lock.json similarity index 100% rename from content/tutorial/01-svelte/07-lifecycle/03-update/app-a/package-lock.json rename to content/tutorial/01-svelte/07-lifecycle/02-update/app-a/package-lock.json diff --git a/content/tutorial/01-svelte/07-lifecycle/03-update/app-a/package.json b/content/tutorial/01-svelte/07-lifecycle/02-update/app-a/package.json similarity index 100% rename from content/tutorial/01-svelte/07-lifecycle/03-update/app-a/package.json rename to content/tutorial/01-svelte/07-lifecycle/02-update/app-a/package.json diff --git a/content/tutorial/01-svelte/07-lifecycle/02-update/app-a/src/lib/App.svelte b/content/tutorial/01-svelte/07-lifecycle/02-update/app-a/src/lib/App.svelte new file mode 100644 index 000000000..03d237aca --- /dev/null +++ b/content/tutorial/01-svelte/07-lifecycle/02-update/app-a/src/lib/App.svelte @@ -0,0 +1,169 @@ + + +
    +
    +
    +
    +

    Eliza

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

    Eliza

    + +
    + {eliza.getInitial()} +
    +
    + + {#each comments as comment} +
    + {comment.text} +
    + {/each} +
    + + +
    +
    + + diff --git a/content/tutorial/01-svelte/07-lifecycle/04-tick/README.md b/content/tutorial/01-svelte/07-lifecycle/03-tick/README.md similarity index 89% rename from content/tutorial/01-svelte/07-lifecycle/04-tick/README.md rename to content/tutorial/01-svelte/07-lifecycle/03-tick/README.md index 391e0955c..78226bf14 100644 --- a/content/tutorial/01-svelte/07-lifecycle/04-tick/README.md +++ b/content/tutorial/01-svelte/07-lifecycle/03-tick/README.md @@ -10,14 +10,16 @@ You can see that behaviour in this example. Select a range of text and hit the t ```js /// file: App.svelte -import { tick } from 'svelte'; ++++import { tick } from 'svelte';+++ + +let text = `Select some text and hit the tab key to toggle uppercase`; ``` ...and running it immediately before we set `this.selectionStart` and `this.selectionEnd` at the end of `handleKeydown`: ```js /// file: App.svelte -await tick(); ++++await tick();+++ this.selectionStart = selectionStart; this.selectionEnd = selectionEnd; ``` diff --git a/content/tutorial/01-svelte/07-lifecycle/04-tick/app-a/src/lib/App.svelte b/content/tutorial/01-svelte/07-lifecycle/03-tick/app-a/src/lib/App.svelte similarity index 79% rename from content/tutorial/01-svelte/07-lifecycle/04-tick/app-a/src/lib/App.svelte rename to content/tutorial/01-svelte/07-lifecycle/03-tick/app-a/src/lib/App.svelte index cc5bf4172..e2c2e5569 100644 --- a/content/tutorial/01-svelte/07-lifecycle/04-tick/app-a/src/lib/App.svelte +++ b/content/tutorial/01-svelte/07-lifecycle/03-tick/app-a/src/lib/App.svelte @@ -6,15 +6,8 @@ event.preventDefault(); - const { - selectionStart, - selectionEnd, - value - } = this; - const selection = value.slice( - selectionStart, - selectionEnd - ); + const { selectionStart, selectionEnd, value } = this; + const selection = value.slice(selectionStart, selectionEnd); const replacement = /[a-z]/.test(selection) ? selection.toUpperCase() @@ -34,11 +27,12 @@ diff --git a/content/tutorial/01-svelte/07-lifecycle/04-tick/app-b/src/lib/App.svelte b/content/tutorial/01-svelte/07-lifecycle/03-tick/app-b/src/lib/App.svelte similarity index 79% rename from content/tutorial/01-svelte/07-lifecycle/04-tick/app-b/src/lib/App.svelte rename to content/tutorial/01-svelte/07-lifecycle/03-tick/app-b/src/lib/App.svelte index 78b7092dc..c9a32a85a 100644 --- a/content/tutorial/01-svelte/07-lifecycle/04-tick/app-b/src/lib/App.svelte +++ b/content/tutorial/01-svelte/07-lifecycle/03-tick/app-b/src/lib/App.svelte @@ -8,15 +8,8 @@ event.preventDefault(); - const { - selectionStart, - selectionEnd, - value - } = this; - const selection = value.slice( - selectionStart, - selectionEnd - ); + const { selectionStart, selectionEnd, value } = this; + const selection = value.slice(selectionStart, selectionEnd); const replacement = /[a-z]/.test(selection) ? selection.toUpperCase() @@ -36,11 +29,12 @@ diff --git a/content/tutorial/01-svelte/07-lifecycle/03-update/app-a/src/lib/App.svelte b/content/tutorial/01-svelte/07-lifecycle/03-update/app-a/src/lib/App.svelte deleted file mode 100644 index 90dc11739..000000000 --- a/content/tutorial/01-svelte/07-lifecycle/03-update/app-a/src/lib/App.svelte +++ /dev/null @@ -1,115 +0,0 @@ - - -
    -

    Eliza

    - -
    - {#each comments as comment} -
    - {comment.text} -
    - {/each} -
    - - -
    - - diff --git a/content/tutorial/01-svelte/07-lifecycle/03-update/app-b/src/lib/App.svelte b/content/tutorial/01-svelte/07-lifecycle/03-update/app-b/src/lib/App.svelte deleted file mode 100644 index 961ee4f52..000000000 --- a/content/tutorial/01-svelte/07-lifecycle/03-update/app-b/src/lib/App.svelte +++ /dev/null @@ -1,119 +0,0 @@ - - -
    -

    Eliza

    - -
    - {#each comments as comment} -
    - {comment.text} -
    - {/each} -
    - - -
    - - diff --git a/content/tutorial/01-svelte/08-stores/01-writable-stores/README.md b/content/tutorial/01-svelte/08-stores/01-writable-stores/README.md index ac437f966..60a705adb 100644 --- a/content/tutorial/01-svelte/08-stores/01-writable-stores/README.md +++ b/content/tutorial/01-svelte/08-stores/01-writable-stores/README.md @@ -13,7 +13,7 @@ Now, in `Incrementer.svelte`, wire up the `+` button: ```js /// file: Incrementer.svelte function increment() { - count.update((n) => n + 1); + +++count.update((n) => n + 1);+++ } ``` @@ -24,6 +24,6 @@ Finally, in `Resetter.svelte`, implement `reset`: ```js /// file: Resetter.svelte function reset() { - count.set(0); + +++count.set(0);+++ } ``` diff --git a/content/tutorial/01-svelte/08-stores/01-writable-stores/app-a/src/lib/Decrementer.svelte b/content/tutorial/01-svelte/08-stores/01-writable-stores/app-a/src/lib/Decrementer.svelte index 049f8aeb4..ea6636414 100644 --- a/content/tutorial/01-svelte/08-stores/01-writable-stores/app-a/src/lib/Decrementer.svelte +++ b/content/tutorial/01-svelte/08-stores/01-writable-stores/app-a/src/lib/Decrementer.svelte @@ -6,4 +6,6 @@ } - + diff --git a/content/tutorial/01-svelte/08-stores/01-writable-stores/app-a/src/lib/Incrementer.svelte b/content/tutorial/01-svelte/08-stores/01-writable-stores/app-a/src/lib/Incrementer.svelte index bfce8f2ea..f32b3ef8a 100644 --- a/content/tutorial/01-svelte/08-stores/01-writable-stores/app-a/src/lib/Incrementer.svelte +++ b/content/tutorial/01-svelte/08-stores/01-writable-stores/app-a/src/lib/Incrementer.svelte @@ -6,4 +6,6 @@ } - + diff --git a/content/tutorial/01-svelte/08-stores/01-writable-stores/app-a/src/lib/Resetter.svelte b/content/tutorial/01-svelte/08-stores/01-writable-stores/app-a/src/lib/Resetter.svelte index 88f0b975d..707652d57 100644 --- a/content/tutorial/01-svelte/08-stores/01-writable-stores/app-a/src/lib/Resetter.svelte +++ b/content/tutorial/01-svelte/08-stores/01-writable-stores/app-a/src/lib/Resetter.svelte @@ -6,4 +6,6 @@ } - + diff --git a/content/tutorial/01-svelte/08-stores/01-writable-stores/app-b/src/lib/Decrementer.svelte b/content/tutorial/01-svelte/08-stores/01-writable-stores/app-b/src/lib/Decrementer.svelte index 596ba4bba..245373cd9 100644 --- a/content/tutorial/01-svelte/08-stores/01-writable-stores/app-b/src/lib/Decrementer.svelte +++ b/content/tutorial/01-svelte/08-stores/01-writable-stores/app-b/src/lib/Decrementer.svelte @@ -6,4 +6,6 @@ } - + diff --git a/content/tutorial/01-svelte/08-stores/01-writable-stores/app-b/src/lib/Incrementer.svelte b/content/tutorial/01-svelte/08-stores/01-writable-stores/app-b/src/lib/Incrementer.svelte index 1fb7dea3c..e91f7acbc 100644 --- a/content/tutorial/01-svelte/08-stores/01-writable-stores/app-b/src/lib/Incrementer.svelte +++ b/content/tutorial/01-svelte/08-stores/01-writable-stores/app-b/src/lib/Incrementer.svelte @@ -6,4 +6,6 @@ } - + diff --git a/content/tutorial/01-svelte/08-stores/01-writable-stores/app-b/src/lib/Resetter.svelte b/content/tutorial/01-svelte/08-stores/01-writable-stores/app-b/src/lib/Resetter.svelte index 9c8809961..db790215d 100644 --- a/content/tutorial/01-svelte/08-stores/01-writable-stores/app-b/src/lib/Resetter.svelte +++ b/content/tutorial/01-svelte/08-stores/01-writable-stores/app-b/src/lib/Resetter.svelte @@ -6,4 +6,6 @@ } - + diff --git a/content/tutorial/01-svelte/08-stores/02-auto-subscriptions/README.md b/content/tutorial/01-svelte/08-stores/02-auto-subscriptions/README.md index 6f4967fab..2ac0aa131 100644 --- a/content/tutorial/01-svelte/08-stores/02-auto-subscriptions/README.md +++ b/content/tutorial/01-svelte/08-stores/02-auto-subscriptions/README.md @@ -15,7 +15,7 @@ Start by declaring `unsubscribe` in `App.svelte`: > Calling a `subscribe` method returns an `unsubscribe` function. -You now declared `unsubscribe`, but it still needs to be called, for example through the `onDestroy` [lifecycle hook](/tutorial/ondestroy): +You now declared `unsubscribe`, but it still needs to be called, for example through the `onDestroy` lifecycle hook: ```svelte /// file: App.svelte diff --git a/content/tutorial/01-svelte/08-stores/02-auto-subscriptions/app-a/src/lib/App.svelte b/content/tutorial/01-svelte/08-stores/02-auto-subscriptions/app-a/src/lib/App.svelte deleted file mode 100644 index a4d9b16dc..000000000 --- a/content/tutorial/01-svelte/08-stores/02-auto-subscriptions/app-a/src/lib/App.svelte +++ /dev/null @@ -1,18 +0,0 @@ - - -

    The count is {count_value}

    - - - - diff --git a/content/tutorial/01-svelte/08-stores/02-auto-subscriptions/app-a/src/lib/Decrementer.svelte b/content/tutorial/01-svelte/08-stores/02-auto-subscriptions/app-a/src/lib/Decrementer.svelte deleted file mode 100644 index 596ba4bba..000000000 --- a/content/tutorial/01-svelte/08-stores/02-auto-subscriptions/app-a/src/lib/Decrementer.svelte +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/content/tutorial/01-svelte/08-stores/02-auto-subscriptions/app-a/src/lib/Incrementer.svelte b/content/tutorial/01-svelte/08-stores/02-auto-subscriptions/app-a/src/lib/Incrementer.svelte deleted file mode 100644 index 1fb7dea3c..000000000 --- a/content/tutorial/01-svelte/08-stores/02-auto-subscriptions/app-a/src/lib/Incrementer.svelte +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/content/tutorial/01-svelte/08-stores/02-auto-subscriptions/app-a/src/lib/Resetter.svelte b/content/tutorial/01-svelte/08-stores/02-auto-subscriptions/app-a/src/lib/Resetter.svelte deleted file mode 100644 index 9c8809961..000000000 --- a/content/tutorial/01-svelte/08-stores/02-auto-subscriptions/app-a/src/lib/Resetter.svelte +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/content/tutorial/01-svelte/08-stores/02-auto-subscriptions/app-a/src/lib/stores.js b/content/tutorial/01-svelte/08-stores/02-auto-subscriptions/app-a/src/lib/stores.js deleted file mode 100644 index d432d339e..000000000 --- a/content/tutorial/01-svelte/08-stores/02-auto-subscriptions/app-a/src/lib/stores.js +++ /dev/null @@ -1,3 +0,0 @@ -import { writable } from 'svelte/store'; - -export const count = writable(0); diff --git a/content/tutorial/01-svelte/08-stores/03-readable-stores/README.md b/content/tutorial/01-svelte/08-stores/03-readable-stores/README.md index 0f6d1dbee..b15e7d6ae 100644 --- a/content/tutorial/01-svelte/08-stores/03-readable-stores/README.md +++ b/content/tutorial/01-svelte/08-stores/03-readable-stores/README.md @@ -8,13 +8,13 @@ Open `stores.js`. The first argument to `readable` is an initial value, which ca ```js /// file: stores.js -export const time = readable(new Date(), function start(set) { - const interval = setInterval(() => { +export const time = readable(+++new Date()+++, function start(set) { ++++ const interval = setInterval(() => { set(new Date()); - }, 1000); + }, 1000);+++ return function stop() { - clearInterval(interval); + +++clearInterval(interval);+++ }; }); ``` diff --git a/content/tutorial/01-svelte/08-stores/03-readable-stores/app-a/src/lib/stores.js b/content/tutorial/01-svelte/08-stores/03-readable-stores/app-a/src/lib/stores.js index ec0a749d7..934e9896e 100644 --- a/content/tutorial/01-svelte/08-stores/03-readable-stores/app-a/src/lib/stores.js +++ b/content/tutorial/01-svelte/08-stores/03-readable-stores/app-a/src/lib/stores.js @@ -1,7 +1,9 @@ import { readable } from 'svelte/store'; export const time = readable(null, function start(set) { - // implementation goes here + // setup code goes here - return function stop() {}; + return function stop() { + // teardown code goes here + }; }); diff --git a/content/tutorial/01-svelte/08-stores/04-derived-stores/README.md b/content/tutorial/01-svelte/08-stores/04-derived-stores/README.md index d96a3cf5f..b858ab471 100644 --- a/content/tutorial/01-svelte/08-stores/04-derived-stores/README.md +++ b/content/tutorial/01-svelte/08-stores/04-derived-stores/README.md @@ -8,8 +8,8 @@ You can create a store whose value is based on the value of one or more _other_ /// file: stores.js export const elapsed = derived( time, - ($time) => Math.round(($time - start) / 1000) + ($time) => +++Math.round(($time - start) / 1000)+++ ); ``` -> It's possible to derive a store from multiple inputs, and to explicitly `set` a value instead of returning it (which is useful for deriving values asynchronously). Consult the [API reference](https://svelte.dev/docs#run-time-svelte-store-derived) for more information. +> It's possible to derive a store from multiple input stores, and to explicitly `set` a value instead of returning it (which is useful for deriving values asynchronously). Consult the [API reference](https://svelte.dev/docs#run-time-svelte-store-derived) for more information. diff --git a/content/tutorial/01-svelte/08-stores/06-store-bindings/README.md b/content/tutorial/01-svelte/08-stores/06-store-bindings/README.md index ea16d03c9..f0fdcde9b 100644 --- a/content/tutorial/01-svelte/08-stores/06-store-bindings/README.md +++ b/content/tutorial/01-svelte/08-stores/06-store-bindings/README.md @@ -13,11 +13,11 @@ In this example we're exporting a writable store `name` and a derived store `gre Changing the input value will now update `name` and all its dependents. -We can also assign directly to store values inside a component. Add a ` ``` diff --git a/content/tutorial/01-svelte/08-stores/06-store-bindings/app-a/src/lib/App.svelte b/content/tutorial/01-svelte/08-stores/06-store-bindings/app-a/src/lib/App.svelte index ede9beab3..d251e450c 100644 --- a/content/tutorial/01-svelte/08-stores/06-store-bindings/app-a/src/lib/App.svelte +++ b/content/tutorial/01-svelte/08-stores/06-store-bindings/app-a/src/lib/App.svelte @@ -4,3 +4,7 @@

    {$greeting}

    + + \ No newline at end of file diff --git a/content/tutorial/01-svelte/08-stores/06-store-bindings/app-b/src/lib/App.svelte b/content/tutorial/01-svelte/08-stores/06-store-bindings/app-b/src/lib/App.svelte index 6ca9bf8a6..f40dd6b85 100644 --- a/content/tutorial/01-svelte/08-stores/06-store-bindings/app-b/src/lib/App.svelte +++ b/content/tutorial/01-svelte/08-stores/06-store-bindings/app-b/src/lib/App.svelte @@ -5,6 +5,6 @@

    {$greeting}

    - diff --git a/content/tutorial/01-svelte/common/src/routes/+error.svelte b/content/tutorial/01-svelte/common/src/routes/+error.svelte index 930ccfd10..7e25aa26e 100644 --- a/content/tutorial/01-svelte/common/src/routes/+error.svelte +++ b/content/tutorial/01-svelte/common/src/routes/+error.svelte @@ -11,12 +11,10 @@ code {$page.status}

    - -
    {$page.error?.stack || ''}
    {/if} diff --git a/content/tutorial/01-svelte/meta.json b/content/tutorial/01-svelte/meta.json index 55c38c336..0f82ec454 100644 --- a/content/tutorial/01-svelte/meta.json +++ b/content/tutorial/01-svelte/meta.json @@ -1,5 +1,5 @@ { - "title": "Welcome to Svelte", + "title": "Basic Svelte", "scope": { "prefix": "/src/lib/", "name": "src" diff --git a/content/tutorial/03-advanced-svelte/01-motion/01-tweens/README.md b/content/tutorial/02-advanced-svelte/01-motion/01-tweens/README.md similarity index 91% rename from content/tutorial/03-advanced-svelte/01-motion/01-tweens/README.md rename to content/tutorial/02-advanced-svelte/01-motion/01-tweens/README.md index dcdd41fc7..68f96f811 100644 --- a/content/tutorial/03-advanced-svelte/01-motion/01-tweens/README.md +++ b/content/tutorial/02-advanced-svelte/01-motion/01-tweens/README.md @@ -2,11 +2,11 @@ title: Tweens --- -Now that we've covered the basics of SvelteKit, it's time to learn some advanced Svelte techniques, starting with _motion_. +Now that we've covered the basics, it's time to learn some advanced Svelte techniques, starting with _motion_. Setting values and watching the DOM update automatically is cool. Know what's even cooler? Tweening those values. Svelte includes tools to help you build slick user interfaces that use animation to communicate changes. -Let's start by changing the `progress` store to a `tweened` value: +Let's start by changing the `progress` store to a `tweened` store: ```svelte /// file: App.svelte diff --git a/content/tutorial/03-advanced-svelte/01-motion/01-tweens/app-a/src/lib/App.svelte b/content/tutorial/02-advanced-svelte/01-motion/01-tweens/app-a/src/lib/App.svelte similarity index 91% rename from content/tutorial/03-advanced-svelte/01-motion/01-tweens/app-a/src/lib/App.svelte rename to content/tutorial/02-advanced-svelte/01-motion/01-tweens/app-a/src/lib/App.svelte index f0b3b7058..f0d3d3d1c 100644 --- a/content/tutorial/03-advanced-svelte/01-motion/01-tweens/app-a/src/lib/App.svelte +++ b/content/tutorial/02-advanced-svelte/01-motion/01-tweens/app-a/src/lib/App.svelte @@ -4,7 +4,7 @@ const progress = writable(0); - + + + + {/each} + + + \ No newline at end of file diff --git a/content/tutorial/02-advanced-svelte/02-transitions/09-deferred-transitions/app-a/src/lib/remove.svg b/content/tutorial/02-advanced-svelte/02-transitions/09-deferred-transitions/app-a/src/lib/remove.svg new file mode 100644 index 000000000..434ab0956 --- /dev/null +++ b/content/tutorial/02-advanced-svelte/02-transitions/09-deferred-transitions/app-a/src/lib/remove.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/content/tutorial/03-advanced-svelte/02-transitions/09-deferred-transitions/app-a/src/lib/todos.js b/content/tutorial/02-advanced-svelte/02-transitions/09-deferred-transitions/app-a/src/lib/todos.js similarity index 100% rename from content/tutorial/03-advanced-svelte/02-transitions/09-deferred-transitions/app-a/src/lib/todos.js rename to content/tutorial/02-advanced-svelte/02-transitions/09-deferred-transitions/app-a/src/lib/todos.js diff --git a/content/tutorial/03-advanced-svelte/02-transitions/09-deferred-transitions/app-a/src/lib/transition.js b/content/tutorial/02-advanced-svelte/02-transitions/09-deferred-transitions/app-a/src/lib/transition.js similarity index 100% rename from content/tutorial/03-advanced-svelte/02-transitions/09-deferred-transitions/app-a/src/lib/transition.js rename to content/tutorial/02-advanced-svelte/02-transitions/09-deferred-transitions/app-a/src/lib/transition.js diff --git a/content/tutorial/02-advanced-svelte/02-transitions/09-deferred-transitions/app-b/src/lib/TodoList.svelte b/content/tutorial/02-advanced-svelte/02-transitions/09-deferred-transitions/app-b/src/lib/TodoList.svelte new file mode 100644 index 000000000..680de1fd9 --- /dev/null +++ b/content/tutorial/02-advanced-svelte/02-transitions/09-deferred-transitions/app-b/src/lib/TodoList.svelte @@ -0,0 +1,44 @@ + + +
      + {#each $store.filter((todo) => todo.done === done) as todo (todo.id)} +
    • + +
    • + {/each} +
    + + \ No newline at end of file diff --git a/content/tutorial/03-advanced-svelte/02-transitions/meta.json b/content/tutorial/02-advanced-svelte/02-transitions/meta.json similarity index 100% rename from content/tutorial/03-advanced-svelte/02-transitions/meta.json rename to content/tutorial/02-advanced-svelte/02-transitions/meta.json diff --git a/content/tutorial/03-advanced-svelte/03-animations/01-animate/README.md b/content/tutorial/02-advanced-svelte/03-animations/01-animate/README.md similarity index 93% rename from content/tutorial/03-advanced-svelte/03-animations/01-animate/README.md rename to content/tutorial/02-advanced-svelte/03-animations/01-animate/README.md index 69cb3a625..53f0221a1 100644 --- a/content/tutorial/03-advanced-svelte/03-animations/01-animate/README.md +++ b/content/tutorial/02-advanced-svelte/03-animations/01-animate/README.md @@ -15,15 +15,16 @@ First, import the `flip` function — flip stands for ['First, Last, Invert, Pla import { send, receive } from './transition.js'; export let store; - export let filter; + export let done; ``` -Then add it to the `