Skip to content

Commit d30e5a0

Browse files
Rich-HarrisRich Harris
and
Rich Harris
authored
Add /// file annotations (#285)
* add clickable file annotations to code blocks * add more file annotations * add no-file * toggle mobile view when clicking annotations * create files from annotations * make all inline file annotations interactive * dont exempt exercises with only one file, its weird --------- Co-authored-by: Rich Harris <[email protected]>
1 parent 1bf38b7 commit d30e5a0

File tree

116 files changed

+448
-161
lines changed

Some content is hidden

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

116 files changed

+448
-161
lines changed

content/tutorial/01-svelte/01-introduction/02-your-first-component/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ A component that just renders some static markup isn't very interesting. Let's a
1111
First, add a script tag to your component and declare a `name` variable:
1212

1313
```svelte
14+
/// file: App.svelte
1415
+++<script>
1516
let name = 'Svelte';
1617
</script>+++
@@ -21,11 +22,13 @@ First, add a script tag to your component and declare a `name` variable:
2122
Then, we can refer to `name` in the markup:
2223

2324
```svelte
25+
/// file: App.svelte
2426
<h1>Hello +++{name}+++!</h1>
2527
```
2628

2729
Inside the curly braces, we can put any JavaScript we want. Try changing `name` to `name.toUpperCase()` for a shoutier greeting.
2830

2931
```svelte
32+
/// file: App.svelte
3033
<h1>Hello {name+++.toUpperCase()+++}!</h1>
3134
```

content/tutorial/01-svelte/01-introduction/03-dynamic-attributes/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Just like you can use curly braces to control text, you can use them to control
77
Our image is missing a `src` — let's add one:
88

99
```svelte
10+
/// file: App.svelte
1011
<img +++src={src}+++ />
1112
```
1213

@@ -19,6 +20,7 @@ When building web apps, it's important to make sure that they're _accessible_ to
1920
In this case, we're missing the `alt` attribute that describes the image for people using screenreaders, or people with slow or flaky internet connections that can't download the image. Let's add one:
2021

2122
```svelte
23+
/// file: App.svelte
2224
<img src={src} +++alt="A man dances."+++ />
2325
```
2426

@@ -29,5 +31,6 @@ We can use curly braces _inside_ attributes. Try changing it to `"{name} dances.
2931
It's not uncommon to have an attribute where the name and value are the same, like `src={src}`. Svelte gives us a convenient shorthand for these cases:
3032

3133
```svelte
34+
/// file: App.svelte
3235
<img +++{src}+++ alt="A man dances." />
3336
```

content/tutorial/01-svelte/01-introduction/04-styling/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ title: Styling
55
Just like in HTML, you can add a `<style>` tag to your component. Let's add some styles to the `<p>` element:
66

77
```svelte
8+
/// file: App.svelte
89
<p>This is a paragraph.</p>
910
1011
<style>

content/tutorial/01-svelte/01-introduction/05-nested-components/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ It would be impractical to put your entire app in a single component. Instead, w
77
Add a `<script>` tag that imports `Nested.svelte`...
88

99
```svelte
10+
/// file: App.svelte
1011
+++<script>
1112
import Nested from './Nested.svelte';
1213
</script>+++
@@ -15,6 +16,7 @@ Add a `<script>` tag that imports `Nested.svelte`...
1516
...and include a `<Nested />` component:
1617

1718
```svelte
19+
/// file: App.svelte
1820
<p>This is a paragraph.</p>
1921
+++<Nested />+++
2022
```

content/tutorial/01-svelte/02-reactivity/01-reactive-assignments/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ At the heart of Svelte is a powerful system of _reactivity_ for keeping the DOM
77
To demonstrate it, we first need to wire up an event handler (we'll learn more about these [later](/tutorial/dom-events)):
88

99
```svelte
10+
/// file: App.svelte
1011
<button +++on:click={increment}+++>
1112
```
1213

1314
Inside the `increment` function, all we need to do is change the value of `count`:
1415

1516
```js
17+
/// file: App.svelte
1618
function increment() {
1719
+++count += 1;+++
1820
}

content/tutorial/01-svelte/02-reactivity/02-reactive-declarations/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Svelte automatically updates the DOM when your component's state changes. Often,
77
For these, we have _reactive declarations_. They look like this:
88

99
```js
10+
/// file: App.svelte
1011
let count = 0;
1112
+++$: doubled = count * 2;+++
1213
```
@@ -16,6 +17,7 @@ let count = 0;
1617
Let's use `doubled` in our markup:
1718

1819
```svelte
20+
/// file: App.svelte
1921
<button>...</button>
2022
2123
+++<p>{count} doubled is {doubled}</p>+++

content/tutorial/01-svelte/02-reactivity/03-reactive-statements/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ title: Statements
55
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:
66

77
```js
8+
/// file: App.svelte
89
let count = 0;
910

1011
+++$: console.log(`the count is ${count}`);+++
@@ -13,6 +14,7 @@ let count = 0;
1314
You can easily group statements together with a block:
1415

1516
```js
17+
/// file: App.svelte
1618
$: +++{+++
1719
console.log(`the count is ${count}`);
1820
alert(`I SAID THE COUNT IS ${count}`);
@@ -22,6 +24,7 @@ $: +++{+++
2224
You can even put the `$:` in front of things like `if` blocks:
2325

2426
```js
27+
/// file: App.svelte
2528
$: +++if (count >= 10)+++ {
2629
alert('count is dangerously high!');
2730
count = 0;

content/tutorial/01-svelte/02-reactivity/04-updating-arrays-and-objects/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Because Svelte's reactivity is triggered by assignments, using array methods lik
77
One way to fix that is to add an assignment that would otherwise be redundant:
88

99
```js
10+
/// file: App.svelte
1011
function addNumber() {
1112
numbers.push(numbers.length + 1);
1213
+++numbers = numbers;+++
@@ -16,6 +17,7 @@ function addNumber() {
1617
But there's a more idiomatic solution:
1718

1819
```js
20+
/// file: App.svelte
1921
function addNumber() {
2022
numbers = +++[...numbers, numbers.length + 1];+++
2123
}
@@ -26,6 +28,7 @@ You can use similar patterns to replace `pop`, `shift`, `unshift` and `splice`.
2628
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.
2729

2830
```js
31+
/// file: App.svelte
2932
function addNumber() {
3033
numbers[numbers.length] = numbers.length + 1;
3134
}
@@ -34,6 +37,7 @@ function addNumber() {
3437
A simple rule of thumb: the name of the updated variable must appear on the left hand side of the assignment. For example this...
3538

3639
```js
40+
/// no-file
3741
const foo = obj.foo;
3842
foo.bar = 'baz';
3943
```

content/tutorial/01-svelte/03-props/01-declaring-props/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ So far, we've dealt exclusively with internal state — that is to say, the valu
77
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:
88

99
```svelte
10+
/// file: Nested.svelte
1011
<script>
1112
+++export+++ let answer;
1213
</script>

content/tutorial/01-svelte/03-props/02-default-values/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ title: Default values
55
We can easily specify default values for props in `Nested.svelte`:
66

77
```svelte
8+
/// file: Nested.svelte
89
<script>
910
export let answer +++= 'a mystery'+++;
1011
</script>
@@ -13,6 +14,7 @@ We can easily specify default values for props in `Nested.svelte`:
1314
If we now add a second component _without_ an `answer` prop, it will fall back to the default:
1415

1516
```svelte
17+
/// file: App.svelte
1618
<Nested answer={42}/>
1719
+++<Nested />+++
1820
```

content/tutorial/01-svelte/03-props/03-spread-props/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ title: Spread props
55
If you have an object of properties, you can 'spread' them onto a component instead of specifying each one:
66

77
```svelte
8+
/// file: App.svelte
89
<PackageInfo +++{...pkg}+++/>
910
```
1011

content/tutorial/01-svelte/04-logic/01-if-blocks/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ HTML doesn't have a way of expressing _logic_, like conditionals and loops. Svel
77
To conditionally render some markup, we wrap it in an `if` block:
88

99
```svelte
10+
/// file: App.svelte
1011
+++{#if user.loggedIn}+++
1112
<button on:click={toggle}>
1213
Log out

content/tutorial/01-svelte/04-logic/02-else-blocks/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ title: Else blocks
55
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:
66

77
```svelte
8+
/// file: App.svelte
89
{#if user.loggedIn}
910
<button on:click={toggle}>
1011
Log out

content/tutorial/01-svelte/04-logic/03-else-if-blocks/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ title: Else-if blocks
55
Multiple conditions can be 'chained' together with `else if`:
66

77
```svelte
8+
/// file: App.svelte
89
{#if x > 10}
910
<p>{x} is greater than 10</p>
1011
{:+++else if+++ 5 > x}

content/tutorial/01-svelte/04-logic/04-each-blocks/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ title: Each blocks
55
If you need to loop over lists of data, use an `each` block:
66

77
```svelte
8+
/// file: App.svelte
89
<ul>
910
+++{#each cats as cat}+++
1011
<li>
@@ -21,6 +22,7 @@ If you need to loop over lists of data, use an `each` block:
2122
You can get the current _index_ as a second argument, like so:
2223

2324
```svelte
25+
/// file: App.svelte
2426
{#each cats as cat+++, i}+++
2527
<li>
2628
<a href="https://www.youtube.com/watch?v={cat.id}">

content/tutorial/01-svelte/04-logic/05-keyed-each-blocks/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Instead, we'd like to remove only the first `<Thing>` component and its DOM node
1111
To do that, we specify a unique identifier (or "key") for the `each` block:
1212

1313
```svelte
14+
/// file: App.svelte
1415
{#each things as thing (+++thing.id+++)}
1516
<Thing name={thing.name}/>
1617
{/each}

content/tutorial/01-svelte/04-logic/06-await-blocks/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ title: Await blocks
55
Most web applications have to deal with asynchronous data at some point. Svelte makes it easy to _await_ the value of [promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises) directly in your markup:
66

77
```svelte
8+
/// file: App.svelte
89
{#await promise}
910
<p>...waiting</p>
1011
{:then number}
@@ -19,6 +20,7 @@ Most web applications have to deal with asynchronous data at some point. Svelte
1920
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:
2021

2122
```svelte
23+
/// file: App.svelte
2224
{#await promise then number}
2325
<p>The number is {number}</p>
2426
{/await}

content/tutorial/01-svelte/05-events/01-dom-events/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ title: DOM events
55
As we've briefly seen already, you can listen to any event on an element with the `on:` directive:
66

77
```svelte
8+
/// file: App.svelte
89
<div +++on:mousemove={handleMousemove}+++>
910
The mouse position is {m.x} x {m.y}
1011
</div>

content/tutorial/01-svelte/05-events/02-inline-handlers/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ title: Inline handlers
55
You can also declare event handlers inline:
66

77
```svelte
8+
/// file: App.svelte
89
<script>
910
let m = { x: 0, y: 0 };
1011

content/tutorial/01-svelte/05-events/03-event-modifiers/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ title: Event modifiers
55
DOM event handlers can have _modifiers_ that alter their behaviour. For example, a handler with a `once` modifier will only run a single time:
66

77
```svelte
8+
/// file: App.svelte
89
<script>
910
function handleClick() {
1011
alert(+++'no more alerts'+++)

content/tutorial/01-svelte/05-events/04-component-events/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ title: Component events
55
Components can also dispatch events. To do so, they must create an event dispatcher. Update `Inner.svelte`:
66

77
```svelte
8+
/// file: Inner.svelte
89
<script>
910
+++import { createEventDispatcher } from 'svelte';+++
1011
@@ -23,6 +24,7 @@ Components can also dispatch events. To do so, they must create an event dispatc
2324
Then, add an `on:message` handler in `App.svelte`:
2425

2526
```svelte
27+
/// file: App.svelte
2628
<Inner +++on:message={handleMessage}+++ />
2729
```
2830

content/tutorial/01-svelte/05-events/05-event-forwarding/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ In this case, we have the same `App.svelte` and `Inner.svelte` as in the [previo
99
One way we _could_ solve the problem is adding `createEventDispatcher` to `Outer.svelte`, listening for the `message` event, and creating a handler for it:
1010

1111
```svelte
12+
/// file: Outer.svelte
1213
<script>
1314
import Inner from './Inner.svelte';
1415
import { createEventDispatcher } from 'svelte';
@@ -26,6 +27,7 @@ One way we _could_ solve the problem is adding `createEventDispatcher` to `Outer
2627
But that's a lot of code to write, so Svelte gives us an equivalent shorthand — an `on:message` event directive without a value means 'forward all `message` events'.
2728

2829
```svelte
30+
/// file: Outer.svelte
2931
<script>
3032
import Inner from './Inner.svelte';
3133
</script>

content/tutorial/01-svelte/05-events/06-dom-event-forwarding/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Event forwarding works for DOM events too.
77
We want to get notified of clicks on our `<BigRedButton>` — to do that, we just need to forward `click` events on the `<button>` element in `BigRedButton.svelte`:
88

99
```svelte
10+
/// file: BigRedButton.svelte
1011
<button +++on:click+++>
1112
Push
1213
</button>

content/tutorial/01-svelte/06-bindings/01-text-inputs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Sometimes it's useful to break that rule. Take the case of the `<input>` element
99
Instead, we can use the `bind:value` directive:
1010

1111
```svelte
12+
/// file: App.svelte
1213
<input bind:value={name}>
1314
```
1415

content/tutorial/01-svelte/06-bindings/02-numeric-inputs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ In the DOM, everything is a string. That's unhelpful when you're dealing with nu
77
With `bind:value`, Svelte takes care of it for you:
88

99
```svelte
10+
/// file: App.svelte
1011
<input type=number bind:value={a} min=0 max=10>
1112
<input type=range bind:value={a} min=0 max=10>
1213
```

content/tutorial/01-svelte/06-bindings/03-checkbox-inputs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ title: Checkbox inputs
55
Checkboxes are used for toggling between states. Instead of binding to `input.value`, we bind to `input.checked`:
66

77
```svelte
8+
/// file: App.svelte
89
<input type=checkbox bind:checked={yes}>
910
```

content/tutorial/01-svelte/06-bindings/04-group-inputs/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,21 @@ If you have multiple inputs relating to the same value, you can use `bind:group`
77
Add `bind:group` to each input:
88

99
```svelte
10+
/// file: App.svelte
1011
<input type=radio bind:group={scoops} name="scoops" value={1}>
1112
```
1213

1314
In this case, we could make the code simpler by moving the checkbox inputs into an `each` block. First, add a `menu` variable to the `<script>` block...
1415

1516
```js
17+
/// file: App.svelte
1618
let menu = ['Cookies and cream', 'Mint choc chip', 'Raspberry ripple'];
1719
```
1820

1921
...then replace the second section:
2022

2123
```svelte
24+
/// file: App.svelte
2225
<h2>Flavours</h2>
2326
2427
{#each menu as flavour}

content/tutorial/01-svelte/06-bindings/05-textarea-inputs/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ title: Textarea inputs
55
The `<textarea>` element behaves similarly to a text input in Svelte — use `bind:value`:
66

77
```svelte
8+
/// file: App.svelte
89
<textarea bind:value={value}></textarea>
910
```
1011

1112
In cases like these, where the names match, we can also use a shorthand form:
1213

1314
```svelte
15+
/// file: App.svelte
1416
<textarea bind:value></textarea>
1517
```
1618

content/tutorial/01-svelte/06-bindings/06-select-bindings/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ title: Select bindings
55
We can also use `bind:value` with `<select>` elements. Update line 32:
66

77
```svelte
8+
/// file: App.svelte
89
<select bind:value={selected} on:change="{() => answer = ''}">
910
```
1011

content/tutorial/01-svelte/06-bindings/07-multiple-select-bindings/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ A select can have a `multiple` attribute, in which case it will populate an arra
77
Returning to our [earlier ice cream example](/tutorial/group-inputs), we can replace the checkboxes with a `<select multiple>`:
88

99
```svelte
10+
/// file: App.svelte
1011
<h2>Flavours</h2>
1112
1213
<select multiple bind:value={flavours}>

content/tutorial/01-svelte/07-lifecycle/01-onmount/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ The one you'll use most frequently is `onMount`, which runs after the component
1111
We'll add an `onMount` handler that loads some data over the network:
1212

1313
```svelte
14+
/// file: App.svelte
1415
<script>
1516
import { onMount } from 'svelte';
1617

0 commit comments

Comments
 (0)