chore(site-2): Run prettier

pull/8593/head
Puru Vijay 3 years ago
parent 21a0141b8c
commit f3396cfd4c

@ -266,10 +266,7 @@ Similarly to `<svelte:window>`, this element allows you to add listeners to even
As with `<svelte:window>`, this element may only appear the top level of your component and must never be inside a block or element. As with `<svelte:window>`, this element may only appear the top level of your component and must never be inside a block or element.
```svelte ```svelte
<svelte:document <svelte:document on:visibilitychange={handleVisibilityChange} use:someAction />
on:visibilitychange={handleVisibilityChange}
use:someAction
/>
``` ```
You can also bind to the following properties: You can also bind to the following properties:

@ -58,11 +58,11 @@ When constructing a custom element, you can tailor several aspects by defining `
```svelte ```svelte
<svelte:options <svelte:options
customElement={{ customElement={{
tag: "custom-element", tag: 'custom-element',
shadow: "none", shadow: 'none',
props: { props: {
name: { reflect: true, type: "Number", attribute: "element-index" }, name: { reflect: true, type: 'Number', attribute: 'element-index' }
}, }
}} }}
/> />
@ -75,7 +75,7 @@ When constructing a custom element, you can tailor several aspects by defining `
Custom elements can be a useful way to package components for consumption in a non-Svelte app, as they will work with vanilla HTML and JavaScript as well as [most frameworks](https://custom-elements-everywhere.com/). There are, however, some important differences to be aware of: Custom elements can be a useful way to package components for consumption in a non-Svelte app, as they will work with vanilla HTML and JavaScript as well as [most frameworks](https://custom-elements-everywhere.com/). There are, however, some important differences to be aware of:
- Styles are *encapsulated*, rather than merely *scoped* (unless you set `shadow: "none"`). This means that any non-component styles (such as you might have in a `global.css` file) will not apply to the custom element, including styles with the `:global(...)` modifier - Styles are _encapsulated_, rather than merely _scoped_ (unless you set `shadow: "none"`). This means that any non-component styles (such as you might have in a `global.css` file) will not apply to the custom element, including styles with the `:global(...)` modifier
- Instead of being extracted out as a separate .css file, styles are inlined into the component as a JavaScript string - Instead of being extracted out as a separate .css file, styles are inlined into the component as a JavaScript string
- Custom elements are not generally suitable for server-side rendering, as the shadow DOM is invisible until JavaScript loads - Custom elements are not generally suitable for server-side rendering, as the shadow DOM is invisible until JavaScript loads
- In Svelte, slotted content renders _lazily_. In the DOM, it renders _eagerly_. In other words, it will always be created even if the component's `<slot>` element is inside an `{#if ...}` block. Similarly, including a `<slot>` in an `{#each ...}` block will not cause the slotted content to be rendered multiple times - In Svelte, slotted content renders _lazily_. In the DOM, it renders _eagerly_. In other words, it will always be created even if the component's `<slot>` element is inside an `{#if ...}` block. Similarly, including a `<slot>` in an `{#each ...}` block will not cause the slotted content to be rendered multiple times

@ -4,4 +4,4 @@
</script> </script>
<!-- {src} is short for src={src} --> <!-- {src} is short for src={src} -->
<img {src} alt="{name} dancing"> <img {src} alt="{name} dancing" />

@ -7,5 +7,6 @@
</script> </script>
<button on:click={handleClick}> <button on:click={handleClick}>
Clicked {count} {count === 1 ? 'time' : 'times'} Clicked {count}
{count === 1 ? 'time' : 'times'}
</button> </button>

@ -12,5 +12,6 @@
</script> </script>
<button on:click={handleClick}> <button on:click={handleClick}>
Clicked {count} {count === 1 ? 'time' : 'times'} Clicked {count}
{count === 1 ? 'time' : 'times'}
</button> </button>

@ -6,7 +6,7 @@
</script> </script>
<p> <p>
The <code>{name}</code> package is {speed} fast. The <code>{name}</code> package is {speed} fast. Download version {version} from
Download version {version} from <a href="https://www.npmjs.com/package/{name}">npm</a> <a href="https://www.npmjs.com/package/{name}">npm</a>
and <a href={website}>learn more here</a> and <a href={website}>learn more here</a>
</p> </p>

@ -7,13 +7,9 @@
</script> </script>
{#if user.loggedIn} {#if user.loggedIn}
<button on:click={toggle}> <button on:click={toggle}> Log out </button>
Log out
</button>
{/if} {/if}
{#if !user.loggedIn} {#if !user.loggedIn}
<button on:click={toggle}> <button on:click={toggle}> Log in </button>
Log in
</button>
{/if} {/if}

@ -7,11 +7,7 @@
</script> </script>
{#if user.loggedIn} {#if user.loggedIn}
<button on:click={toggle}> <button on:click={toggle}> Log out </button>
Log out
</button>
{:else} {:else}
<button on:click={toggle}> <button on:click={toggle}> Log in </button>
Log in
</button>
{/if} {/if}

@ -14,9 +14,7 @@
} }
</script> </script>
<button on:click={handleClick}> <button on:click={handleClick}> Remove first thing </button>
Remove first thing
</button>
<div style="display: grid; grid-template-columns: 1fr 1fr; grid-gap: 1em"> <div style="display: grid; grid-template-columns: 1fr 1fr; grid-gap: 1em">
<div> <div>

@ -17,9 +17,7 @@
} }
</script> </script>
<button on:click={handleClick}> <button on:click={handleClick}> generate random number </button>
generate random number
</button>
{#await promise} {#await promise}
<p>...waiting</p> <p>...waiting</p>

@ -12,5 +12,8 @@
</div> </div>
<style> <style>
div { width: 100%; height: 100%; } div {
width: 100%;
height: 100%;
}
</style> </style>

@ -2,10 +2,13 @@
let m = { x: 0, y: 0 }; let m = { x: 0, y: 0 };
</script> </script>
<div on:mousemove="{e => m = { x: e.clientX, y: e.clientY }}"> <div on:mousemove={(e) => (m = { x: e.clientX, y: e.clientY })}>
The mouse position is {m.x} x {m.y} The mouse position is {m.x} x {m.y}
</div> </div>
<style> <style>
div { width: 100%; height: 100%; } div {
width: 100%;
height: 100%;
}
</style> </style>

@ -1,9 +1,7 @@
<script> <script>
function handleClick() { function handleClick() {
alert('no more alerts') alert('no more alerts');
} }
</script> </script>
<button on:click|once={handleClick}> <button on:click|once={handleClick}> Click me </button>
Click me
</button>

@ -10,6 +10,4 @@
} }
</script> </script>
<button on:click={sayHello}> <button on:click={sayHello}> Click to say hello </button>
Click to say hello
</button>

@ -10,6 +10,4 @@
} }
</script> </script>
<button on:click={sayHello}> <button on:click={sayHello}> Click to say hello </button>
Click to say hello
</button>

@ -1,6 +1,4 @@
<button on:click> <button on:click> Click me </button>
Click me
</button>
<style> <style>
button { button {

@ -2,5 +2,5 @@
let name = ''; let name = '';
</script> </script>
<input bind:value={name} placeholder="enter your name"> <input bind:value={name} placeholder="enter your name" />
<p>Hello {name || 'stranger'}!</p> <p>Hello {name || 'stranger'}!</p>

@ -4,13 +4,13 @@
</script> </script>
<label> <label>
<input type=number bind:value={a} min=0 max=10> <input type="number" bind:value={a} min="0" max="10" />
<input type=range bind:value={a} min=0 max=10> <input type="range" bind:value={a} min="0" max="10" />
</label> </label>
<label> <label>
<input type=number bind:value={b} min=0 max=10> <input type="number" bind:value={b} min="0" max="10" />
<input type=range bind:value={b} min=0 max=10> <input type="range" bind:value={b} min="0" max="10" />
</label> </label>
<p>{a} + {b} = {a + b}</p> <p>{a} + {b} = {a + b}</p>

@ -3,7 +3,7 @@
</script> </script>
<label> <label>
<input type=checkbox bind:checked={yes}> <input type="checkbox" bind:checked={yes} />
Yes! Send me regular email spam Yes! Send me regular email spam
</label> </label>
@ -13,6 +13,4 @@
<p>You must opt-in to continue. If you're not paying, you're the product.</p> <p>You must opt-in to continue. If you're not paying, you're the product.</p>
{/if} {/if}
<button disabled={!yes}> <button disabled={!yes}> Subscribe </button>
Subscribe
</button>

@ -2,11 +2,7 @@
let scoops = 1; let scoops = 1;
let flavours = ['Mint choc chip']; let flavours = ['Mint choc chip'];
let menu = [ let menu = ['Cookies and cream', 'Mint choc chip', 'Raspberry ripple'];
'Cookies and cream',
'Mint choc chip',
'Raspberry ripple'
];
function join(flavours) { function join(flavours) {
if (flavours.length === 1) return flavours[0]; if (flavours.length === 1) return flavours[0];
@ -17,17 +13,17 @@
<h2>Size</h2> <h2>Size</h2>
<label> <label>
<input type=radio bind:group={scoops} value={1}> <input type="radio" bind:group={scoops} value={1} />
One scoop One scoop
</label> </label>
<label> <label>
<input type=radio bind:group={scoops} value={2}> <input type="radio" bind:group={scoops} value={2} />
Two scoops Two scoops
</label> </label>
<label> <label>
<input type=radio bind:group={scoops} value={3}> <input type="radio" bind:group={scoops} value={3} />
Three scoops Three scoops
</label> </label>
@ -35,7 +31,7 @@
{#each menu as flavour} {#each menu as flavour}
<label> <label>
<input type=checkbox bind:group={flavours} value={flavour}> <input type="checkbox" bind:group={flavours} value={flavour} />
{flavour} {flavour}
</label> </label>
{/each} {/each}
@ -46,7 +42,8 @@
<p>Can't order more flavours than scoops!</p> <p>Can't order more flavours than scoops!</p>
{:else} {:else}
<p> <p>
You ordered {scoops} {scoops === 1 ? 'scoop' : 'scoops'} You ordered {scoops}
{scoops === 1 ? 'scoop' : 'scoops'}
of {join(flavours)} of {join(flavours)}
</p> </p>
{/if} {/if}

@ -3,10 +3,13 @@
let text = `Some words are *italic*, some are **bold**`; let text = `Some words are *italic*, some are **bold**`;
</script> </script>
<textarea bind:value={text}></textarea> <textarea bind:value={text} />
{@html marked(text)} {@html marked(text)}
<style> <style>
textarea { width: 100%; height: 200px; } textarea {
width: 100%;
height: 200px;
}
</style> </style>

@ -13,21 +13,10 @@
</script> </script>
<label for="avatar">Upload a picture:</label> <label for="avatar">Upload a picture:</label>
<input <input accept="image/png, image/jpeg" bind:files id="avatar" name="avatar" type="file" />
accept="image/png, image/jpeg"
bind:files
id="avatar"
name="avatar"
type="file"
/>
<label for="many">Upload multiple files of any type:</label> <label for="many">Upload multiple files of any type:</label>
<input <input bind:files id="many" multiple type="file" />
bind:files
id="many"
multiple
type="file"
/>
{#if files} {#if files}
<h2>Selected files:</h2> <h2>Selected files:</h2>

@ -17,7 +17,7 @@
<h2>Insecurity questions</h2> <h2>Insecurity questions</h2>
<form on:submit|preventDefault={handleSubmit}> <form on:submit|preventDefault={handleSubmit}>
<select bind:value={selected} on:change="{() => answer = ''}"> <select bind:value={selected} on:change={() => (answer = '')}>
{#each questions as question} {#each questions as question}
<option value={question}> <option value={question}>
{question.text} {question.text}
@ -25,15 +25,17 @@
{/each} {/each}
</select> </select>
<input bind:value={answer}> <input bind:value={answer} />
<button disabled={!answer} type=submit> <button disabled={!answer} type="submit"> Submit </button>
Submit
</button>
</form> </form>
<p>selected question {selected ? selected.id : '[waiting...]'}</p> <p>selected question {selected ? selected.id : '[waiting...]'}</p>
<style> <style>
input { display: block; width: 500px; max-width: 100%; } input {
display: block;
width: 500px;
max-width: 100%;
}
</style> </style>

@ -2,11 +2,7 @@
let scoops = 1; let scoops = 1;
let flavours = ['Mint choc chip']; let flavours = ['Mint choc chip'];
let menu = [ let menu = ['Cookies and cream', 'Mint choc chip', 'Raspberry ripple'];
'Cookies and cream',
'Mint choc chip',
'Raspberry ripple'
];
function join(flavours) { function join(flavours) {
if (flavours.length === 1) return flavours[0]; if (flavours.length === 1) return flavours[0];
@ -17,17 +13,17 @@
<h2>Size</h2> <h2>Size</h2>
<label> <label>
<input type=radio bind:group={scoops} value={1}> <input type="radio" bind:group={scoops} value={1} />
One scoop One scoop
</label> </label>
<label> <label>
<input type=radio bind:group={scoops} value={2}> <input type="radio" bind:group={scoops} value={2} />
Two scoops Two scoops
</label> </label>
<label> <label>
<input type=radio bind:group={scoops} value={3}> <input type="radio" bind:group={scoops} value={3} />
Three scoops Three scoops
</label> </label>
@ -47,7 +43,8 @@
<p>Can't order more flavours than scoops!</p> <p>Can't order more flavours than scoops!</p>
{:else} {:else}
<p> <p>
You ordered {scoops} {scoops === 1 ? 'scoop' : 'scoops'} You ordered {scoops}
{scoops === 1 ? 'scoop' : 'scoops'}
of {join(flavours)} of {join(flavours)}
</p> </p>
{/if} {/if}

@ -10,35 +10,24 @@
} }
function clear() { function clear() {
todos = todos.filter(t => !t.done); todos = todos.filter((t) => !t.done);
} }
$: remaining = todos.filter(t => !t.done).length; $: remaining = todos.filter((t) => !t.done).length;
</script> </script>
<h1>Todos</h1> <h1>Todos</h1>
{#each todos as todo} {#each todos as todo}
<div> <div>
<input <input type="checkbox" bind:checked={todo.done} />
type=checkbox
bind:checked={todo.done} <input placeholder="What needs to be done?" bind:value={todo.text} disabled={todo.done} />
>
<input
placeholder="What needs to be done?"
bind:value={todo.text}
disabled={todo.done}
>
</div> </div>
{/each} {/each}
<p>{remaining} remaining</p> <p>{remaining} remaining</p>
<button on:click={add}> <button on:click={add}> Add new </button>
Add new
</button>
<button on:click={clear}> <button on:click={clear}> Clear completed </button>
Clear completed
</button>

@ -14,7 +14,7 @@
// Make the controls visible, but fade out after // Make the controls visible, but fade out after
// 2.5 seconds of inactivity // 2.5 seconds of inactivity
clearTimeout(showControlsTimeout); clearTimeout(showControlsTimeout);
showControlsTimeout = setTimeout(() => showControls = false, 2500); showControlsTimeout = setTimeout(() => (showControls = false), 2500);
showControls = true; showControls = true;
if (!duration) return; // video not loaded yet if (!duration) return; // video not loaded yet
@ -22,7 +22,7 @@
const clientX = e.type === 'touchmove' ? e.touches[0].clientX : e.clientX; const clientX = e.type === 'touchmove' ? e.touches[0].clientX : e.clientX;
const { left, right } = this.getBoundingClientRect(); const { left, right } = this.getBoundingClientRect();
time = duration * (clientX - left) / (right - left); time = (duration * (clientX - left)) / (right - left);
} }
// we can't rely on the built-in click event, because it fires // we can't rely on the built-in click event, because it fires
@ -62,12 +62,13 @@
on:mouseup={handleMouseup} on:mouseup={handleMouseup}
bind:currentTime={time} bind:currentTime={time}
bind:duration bind:duration
bind:paused> bind:paused
>
<track kind="captions" /> <track kind="captions" />
</video> </video>
<div class="controls" style="opacity: {duration && showControls ? 1 : 0}"> <div class="controls" style="opacity: {duration && showControls ? 1 : 0}">
<progress value="{(time / duration) || 0}"/> <progress value={time / duration || 0} />
<div class="info"> <div class="info">
<span class="time">{format(time)}</span> <span class="time">{format(time)}</span>
@ -107,7 +108,9 @@
width: 3em; width: 3em;
} }
.time:last-child { text-align: right } .time:last-child {
text-align: right;
}
progress { progress {
display: block; display: block;

@ -5,8 +5,8 @@
let text = 'edit me'; let text = 'edit me';
</script> </script>
<input type=range bind:value={size}> <input type="range" bind:value={size} />
<input bind:value={text}> <input bind:value={text} />
<p>size: {w}px x {h}px</p> <p>size: {w}px x {h}px</p>
@ -15,6 +15,10 @@
</div> </div>
<style> <style>
input { display: block; } input {
div { display: inline-block; } display: block;
}
div {
display: inline-block;
}
</style> </style>

@ -15,12 +15,12 @@
for (let p = 0; p < imageData.data.length; p += 4) { for (let p = 0; p < imageData.data.length; p += 4) {
const i = p / 4; const i = p / 4;
const x = i % canvas.width; const x = i % canvas.width;
const y = i / canvas.height >>> 0; const y = (i / canvas.height) >>> 0;
const t = window.performance.now(); const t = window.performance.now();
const r = 64 + (128 * x / canvas.width) + (64 * Math.sin(t / 1000)); const r = 64 + (128 * x) / canvas.width + 64 * Math.sin(t / 1000);
const g = 64 + (128 * y / canvas.height) + (64 * Math.cos(t / 1400)); const g = 64 + (128 * y) / canvas.height + 64 * Math.cos(t / 1400);
const b = 128; const b = 128;
imageData.data[p + 0] = r; imageData.data[p + 0] = r;
@ -30,7 +30,7 @@
} }
ctx.putImageData(imageData, 0, 0); ctx.putImageData(imageData, 0, 0);
}()); })();
return () => { return () => {
cancelAnimationFrame(frame); cancelAnimationFrame(frame);
@ -38,11 +38,7 @@
}); });
</script> </script>
<canvas <canvas bind:this={canvas} width={32} height={32} />
bind:this={canvas}
width={32}
height={32}
></canvas>
<style> <style>
canvas { canvas {

@ -5,8 +5,8 @@
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
const select = num => () => value += num; const select = (num) => () => (value += num);
const clear = () => value = ''; const clear = () => (value = '');
const submit = () => dispatch('submit'); const submit = () => dispatch('submit');
</script> </script>
@ -31,10 +31,10 @@
display: grid; display: grid;
grid-template-columns: repeat(3, 5em); grid-template-columns: repeat(3, 5em);
grid-template-rows: repeat(4, 3em); grid-template-rows: repeat(4, 3em);
grid-gap: 0.5em grid-gap: 0.5em;
} }
button { button {
margin: 0 margin: 0;
} }
</style> </style>

@ -14,7 +14,7 @@
<div class="photos"> <div class="photos">
{#each photos as photo} {#each photos as photo}
<figure> <figure>
<img src={photo.thumbnailUrl} alt={photo.title}> <img src={photo.thumbnailUrl} alt={photo.title} />
<figcaption>{photo.title}</figcaption> <figcaption>{photo.title}</figcaption>
</figure> </figure>
{:else} {:else}
@ -31,7 +31,8 @@
grid-gap: 8px; grid-gap: 8px;
} }
figure, img { figure,
img {
width: 100%; width: 100%;
margin: 0; margin: 0;
} }

@ -2,10 +2,11 @@
import { onInterval } from './utils.js'; import { onInterval } from './utils.js';
let seconds = 0; let seconds = 0;
onInterval(() => seconds += 1, 1000); onInterval(() => (seconds += 1), 1000);
</script> </script>
<p> <p>
The page has been open for The page has been open for
{seconds} {seconds === 1 ? 'second' : 'seconds'} {seconds}
{seconds === 1 ? 'second' : 'seconds'}
</p> </p>

@ -6,7 +6,7 @@
let autoscroll; let autoscroll;
beforeUpdate(() => { beforeUpdate(() => {
autoscroll = div && (div.offsetHeight + div.scrollTop) > (div.scrollHeight - 20); autoscroll = div && div.offsetHeight + div.scrollTop > div.scrollHeight - 20;
}); });
afterUpdate(() => { afterUpdate(() => {
@ -15,9 +15,7 @@
const eliza = new Eliza(); const eliza = new Eliza();
let comments = [ let comments = [{ author: 'eliza', text: eliza.getInitial() }];
{ author: 'eliza', text: eliza.getInitial() }
];
function handleKeydown(event) { function handleKeydown(event) {
if (event.key === 'Enter') { if (event.key === 'Enter') {
@ -41,7 +39,9 @@
}); });
setTimeout(() => { setTimeout(() => {
comments = comments.filter(comment => !comment.placeholder).concat({ comments = comments
.filter((comment) => !comment.placeholder)
.concat({
author: 'eliza', author: 'eliza',
text: reply text: reply
}); });
@ -62,7 +62,7 @@
{/each} {/each}
</div> </div>
<input on:keydown={handleKeydown}> <input on:keydown={handleKeydown} />
</div> </div>
<style> <style>
@ -99,7 +99,7 @@
} }
.user span { .user span {
background-color: #0074D9; background-color: #0074d9;
color: white; color: white;
border-radius: 1em 1em 0 1em; border-radius: 1em 1em 0 1em;
} }

@ -11,15 +11,9 @@
const { selectionStart, selectionEnd, value } = this; const { selectionStart, selectionEnd, value } = this;
const selection = value.slice(selectionStart, selectionEnd); const selection = value.slice(selectionStart, selectionEnd);
const replacement = /[a-z]/.test(selection) const replacement = /[a-z]/.test(selection) ? selection.toUpperCase() : selection.toLowerCase();
? selection.toUpperCase()
: selection.toLowerCase();
text = ( text = value.slice(0, selectionStart) + replacement + value.slice(selectionEnd);
value.slice(0, selectionStart) +
replacement +
value.slice(selectionEnd)
);
await tick(); await tick();
this.selectionStart = selectionStart; this.selectionStart = selectionStart;
@ -27,7 +21,7 @@
} }
</script> </script>
<textarea value={text} on:keydown={handleKeydown}></textarea> <textarea value={text} on:keydown={handleKeydown} />
<style> <style>
textarea { textarea {

@ -6,7 +6,7 @@
let countValue; let countValue;
const unsubscribe = count.subscribe(value => { const unsubscribe = count.subscribe((value) => {
countValue = value; countValue = value;
}); });
</script> </script>

@ -2,10 +2,8 @@
import { count } from './stores.js'; import { count } from './stores.js';
function decrement() { function decrement() {
count.update(n => n - 1); count.update((n) => n - 1);
} }
</script> </script>
<button on:click={decrement}> <button on:click={decrement}> - </button>
-
</button>

@ -2,10 +2,8 @@
import { count } from './stores.js'; import { count } from './stores.js';
function increment() { function increment() {
count.update(n => n + 1); count.update((n) => n + 1);
} }
</script> </script>
<button on:click={increment}> <button on:click={increment}> + </button>
+
</button>

@ -6,6 +6,4 @@
} }
</script> </script>
<button on:click={reset}> <button on:click={reset}> reset </button>
reset
</button>

@ -2,10 +2,8 @@
import { count } from './stores.js'; import { count } from './stores.js';
function decrement() { function decrement() {
count.update(n => n - 1); count.update((n) => n - 1);
} }
</script> </script>
<button on:click={decrement}> <button on:click={decrement}> - </button>
-
</button>

@ -2,10 +2,8 @@
import { count } from './stores.js'; import { count } from './stores.js';
function increment() { function increment() {
count.update(n => n + 1); count.update((n) => n + 1);
} }
</script> </script>
<button on:click={increment}> <button on:click={increment}> + </button>
+
</button>

@ -6,6 +6,4 @@
} }
</script> </script>
<button on:click={reset}> <button on:click={reset}> reset </button>
reset
</button>

@ -13,5 +13,6 @@
<p> <p>
This page has been open for This page has been open for
{$elapsed} {$elapsed === 1 ? 'second' : 'seconds'} {$elapsed}
{$elapsed === 1 ? 'second' : 'seconds'}
</p> </p>

@ -8,27 +8,17 @@
}); });
</script> </script>
<progress value={$progress}></progress> <progress value={$progress} />
<button on:click="{() => progress.set(0)}"> <button on:click={() => progress.set(0)}> 0% </button>
0%
</button>
<button on:click="{() => progress.set(0.25)}"> <button on:click={() => progress.set(0.25)}> 25% </button>
25%
</button>
<button on:click="{() => progress.set(0.5)}"> <button on:click={() => progress.set(0.5)}> 50% </button>
50%
</button>
<button on:click="{() => progress.set(0.75)}"> <button on:click={() => progress.set(0.75)}> 75% </button>
75%
</button>
<button on:click="{() => progress.set(1)}"> <button on:click={() => progress.set(1)}> 100% </button>
100%
</button>
<style> <style>
progress { progress {

@ -1,10 +1,13 @@
<script> <script>
import { spring } from 'svelte/motion'; import { spring } from 'svelte/motion';
let coords = spring({ x: 50, y: 50 }, { let coords = spring(
{ x: 50, y: 50 },
{
stiffness: 0.1, stiffness: 0.1,
damping: 0.25 damping: 0.25
}); }
);
let size = spring(10); let size = spring(10);
</script> </script>
@ -12,24 +15,30 @@
<div style="position: absolute; right: 1em;"> <div style="position: absolute; right: 1em;">
<label> <label>
<h3>stiffness ({coords.stiffness})</h3> <h3>stiffness ({coords.stiffness})</h3>
<input bind:value={coords.stiffness} type="range" min="0" max="1" step="0.01"> <input bind:value={coords.stiffness} type="range" min="0" max="1" step="0.01" />
</label> </label>
<label> <label>
<h3>damping ({coords.damping})</h3> <h3>damping ({coords.damping})</h3>
<input bind:value={coords.damping} type="range" min="0" max="1" step="0.01"> <input bind:value={coords.damping} type="range" min="0" max="1" step="0.01" />
</label> </label>
</div> </div>
<svg <svg
on:mousemove="{e => coords.set({ x: e.clientX, y: e.clientY })}" on:mousemove={(e) => coords.set({ x: e.clientX, y: e.clientY })}
on:mousedown="{() => size.set(30)}" on:mousedown={() => size.set(30)}
on:mouseup="{() => size.set(10)}" on:mouseup={() => size.set(10)}
> >
<circle cx={$coords.x} cy={$coords.y} r={$size} /> <circle cx={$coords.x} cy={$coords.y} r={$size} />
</svg> </svg>
<style> <style>
svg { width: 100%; height: 100%; margin: -8px } svg {
circle { fill: #ff3e00 } width: 100%;
height: 100%;
margin: -8px;
}
circle {
fill: #ff3e00;
}
</style> </style>

@ -4,12 +4,10 @@
</script> </script>
<label> <label>
<input type="checkbox" bind:checked={visible}> <input type="checkbox" bind:checked={visible} />
visible visible
</label> </label>
{#if visible} {#if visible}
<p transition:fade> <p transition:fade>Fades in and out</p>
Fades in and out
</p>
{/if} {/if}

@ -4,12 +4,10 @@
</script> </script>
<label> <label>
<input type="checkbox" bind:checked={visible}> <input type="checkbox" bind:checked={visible} />
visible visible
</label> </label>
{#if visible} {#if visible}
<p transition:fly="{{ y: 200, duration: 2000 }}"> <p transition:fly={{ y: 200, duration: 2000 }}>Flies in and out</p>
Flies in and out
</p>
{/if} {/if}

@ -4,12 +4,10 @@
</script> </script>
<label> <label>
<input type="checkbox" bind:checked={visible}> <input type="checkbox" bind:checked={visible} />
visible visible
</label> </label>
{#if visible} {#if visible}
<p in:fly="{{ y: 200, duration: 2000 }}" out:fade> <p in:fly={{ y: 200, duration: 2000 }} out:fade>Flies in, fades out</p>
Flies in, fades out
</p>
{/if} {/if}

@ -7,7 +7,7 @@
function spin(node, { duration }) { function spin(node, { duration }) {
return { return {
duration, duration,
css: t => { css: (t) => {
const eased = elasticOut(t); const eased = elasticOut(t);
return ` return `
@ -16,19 +16,19 @@
${~~(t * 360)}, ${~~(t * 360)},
${Math.min(100, 1000 - 1000 * t)}%, ${Math.min(100, 1000 - 1000 * t)}%,
${Math.min(50, 500 - 500 * t)}% ${Math.min(50, 500 - 500 * t)}%
);` );`;
} }
}; };
} }
</script> </script>
<label> <label>
<input type="checkbox" bind:checked={visible}> <input type="checkbox" bind:checked={visible} />
visible visible
</label> </label>
{#if visible} {#if visible}
<div class="centered" in:spin="{{duration: 8000}}" out:fade> <div class="centered" in:spin={{ duration: 8000 }} out:fade>
<span>transitions!</span> <span>transitions!</span>
</div> </div>
{/if} {/if}

@ -2,10 +2,7 @@
let visible = false; let visible = false;
function typewriter(node, { speed = 1 }) { function typewriter(node, { speed = 1 }) {
const valid = ( const valid = node.childNodes.length === 1 && node.childNodes[0].nodeType === Node.TEXT_NODE;
node.childNodes.length === 1 &&
node.childNodes[0].nodeType === Node.TEXT_NODE
);
if (!valid) { if (!valid) {
throw new Error(`This transition only works on elements with a single text node child`); throw new Error(`This transition only works on elements with a single text node child`);
@ -16,7 +13,7 @@
return { return {
duration, duration,
tick: t => { tick: (t) => {
const i = ~~(text.length * t); const i = ~~(text.length * t);
node.textContent = text.slice(0, i); node.textContent = text.slice(0, i);
} }
@ -25,12 +22,10 @@
</script> </script>
<label> <label>
<input type="checkbox" bind:checked={visible}> <input type="checkbox" bind:checked={visible} />
visible visible
</label> </label>
{#if visible} {#if visible}
<p transition:typewriter> <p transition:typewriter>The quick brown fox jumps over the lazy dog</p>
The quick brown fox jumps over the lazy dog
</p>
{/if} {/if}

@ -8,17 +8,17 @@
<p>status: {status}</p> <p>status: {status}</p>
<label> <label>
<input type="checkbox" bind:checked={visible}> <input type="checkbox" bind:checked={visible} />
visible visible
</label> </label>
{#if visible} {#if visible}
<p <p
transition:fly="{{ y: 200, duration: 2000 }}" transition:fly={{ y: 200, duration: 2000 }}
on:introstart="{() => status = 'intro started'}" on:introstart={() => (status = 'intro started')}
on:outrostart="{() => status = 'outro started'}" on:outrostart={() => (status = 'outro started')}
on:introend="{() => status = 'intro ended'}" on:introend={() => (status = 'intro ended')}
on:outroend="{() => status = 'outro ended'}" on:outroend={() => (status = 'outro ended')}
> >
Flies in and out Flies in and out
</p> </p>

@ -12,8 +12,8 @@
const ASSETS = `https://sveltejs.github.io/assets/crossfade`; const ASSETS = `https://sveltejs.github.io/assets/crossfade`;
const load = image => { const load = (image) => {
const timeout = setTimeout(() => loading = image, 100); const timeout = setTimeout(() => (loading = image), 100);
const img = new Image(); const img = new Image();
@ -37,10 +37,10 @@
{#if selected !== image} {#if selected !== image}
<button <button
style="background-color: {image.color};" style="background-color: {image.color};"
on:click="{() => load(image)}" on:click={() => load(image)}
in:receive={{ key: image.id }} in:receive={{ key: image.id }}
out:send={{key:image.id}} out:send={{ key: image.id }}>{loading === image ? '...' : image.id}</button
>{loading === image ? '...' : image.id}</button> >
{/if} {/if}
</div> </div>
{/each} {/each}
@ -49,14 +49,13 @@
{#if selected} {#if selected}
{#await selected then d} {#await selected then d}
<div class="photo" in:receive={{ key: d.id }} out:send={{ key: d.id }}> <div class="photo" in:receive={{ key: d.id }} out:send={{ key: d.id }}>
<img <img alt={d.alt} src="{ASSETS}/{d.id}.jpg" on:click={() => (selected = null)} />
alt={d.alt}
src="{ASSETS}/{d.id}.jpg"
on:click="{() => selected = null}"
>
<p class='credit'> <p class="credit">
<a target="_blank" rel="noreferrer" href="https://www.flickr.com/photos/{d.path}">via Flickr</a> &ndash; <a target="_blank" rel="noreferrer" href="https://www.flickr.com/photos/{d.path}"
>via Flickr</a
>
&ndash;
<a target="_blank" rel="noreferrer" href={d.license.url}>{d.license.name}</a> <a target="_blank" rel="noreferrer" href={d.license.url}>{d.license.name}</a>
</p> </p>
</div> </div>
@ -114,7 +113,8 @@
will-change: transform; will-change: transform;
} }
.photo, img { .photo,
img {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
@ -147,7 +147,8 @@
background: rgba(0, 0, 0, 0.4); background: rgba(0, 0, 0, 0.4);
} }
.credit a, .credit a:visited { .credit a,
.credit a:visited {
color: white; color: white;
} }
</style> </style>

@ -11,7 +11,7 @@
return { return {
duration: 600, duration: 600,
easing: quintOut, easing: quintOut,
css: t => ` css: (t) => `
transform: ${transform} scale(${t}); transform: ${transform} scale(${t});
opacity: ${t} opacity: ${t}
` `
@ -25,7 +25,7 @@
{ id: 3, done: true, description: 'buy some milk' }, { id: 3, done: true, description: 'buy some milk' },
{ id: 4, done: false, description: 'mow the lawn' }, { id: 4, done: false, description: 'mow the lawn' },
{ id: 5, done: false, description: 'feed the turtle' }, { id: 5, done: false, description: 'feed the turtle' },
{ id: 6, done: false, description: 'fix some bugs' }, { id: 6, done: false, description: 'fix some bugs' }
]; ];
let uid = todos.length + 1; let uid = todos.length + 1;
@ -42,43 +42,35 @@
} }
function remove(todo) { function remove(todo) {
todos = todos.filter(t => t !== todo); todos = todos.filter((t) => t !== todo);
} }
</script> </script>
<div class='board'> <div class="board">
<input <input
class="new-todo" class="new-todo"
placeholder="what needs to be done?" placeholder="what needs to be done?"
on:keydown="{event => event.key === 'Enter' && add(event.target)}" on:keydown={(event) => event.key === 'Enter' && add(event.target)}
> />
<div class='left'> <div class="left">
<h2>todo</h2> <h2>todo</h2>
{#each todos.filter(t => !t.done) as todo (todo.id)} {#each todos.filter((t) => !t.done) as todo (todo.id)}
<label <label in:receive={{ key: todo.id }} out:send={{ key: todo.id }} animate:flip>
in:receive="{{key: todo.id}}" <input type="checkbox" bind:checked={todo.done} />
out:send="{{key: todo.id}}"
animate:flip
>
<input type=checkbox bind:checked={todo.done}>
{todo.description} {todo.description}
<button on:click="{() => remove(todo)}">x</button> <button on:click={() => remove(todo)}>x</button>
</label> </label>
{/each} {/each}
</div> </div>
<div class='right'> <div class="right">
<h2>done</h2> <h2>done</h2>
{#each todos.filter(t => t.done) as todo (todo.id)} {#each todos.filter((t) => t.done) as todo (todo.id)}
<label <label in:receive={{ key: todo.id }} out:send={{ key: todo.id }} animate:flip>
in:receive="{{key: todo.id}}" <input type="checkbox" bind:checked={todo.done} />
out:send="{{key: todo.id}}"
animate:flip
>
<input type=checkbox bind:checked={todo.done}>
{todo.description} {todo.description}
<button on:click="{() => remove(todo)}">x</button> <button on:click={() => remove(todo)}>x</button>
</label> </label>
{/each} {/each}
</div> </div>
@ -96,7 +88,8 @@
margin: 0 auto; margin: 0 auto;
} }
.left, .right { .left,
.right {
float: left; float: left;
width: 50%; width: 50%;
padding: 0 1em 0 0; padding: 0 1em 0 0;
@ -122,7 +115,9 @@
user-select: none; user-select: none;
} }
input { margin: 0 } input {
margin: 0;
}
.right label { .right label {
background-color: rgb(180, 240, 100); background-color: rgb(180, 240, 100);

@ -26,7 +26,7 @@
await ease_path.set(current.shape); await ease_path.set(current.shape);
await Promise.all([ await Promise.all([
time.set(1000, {duration, easing: x => x}), time.set(1000, { duration, easing: (x) => x }),
value.set(0, { duration, easing: current.fn }) value.set(0, { duration, easing: current.fn })
]); ]);
@ -42,24 +42,15 @@
<g class="canvas"> <g class="canvas">
<Grid x={$time} y={$value} /> <Grid x={$time} y={$value} />
<g class="graph"> <g class="graph">
<path <path d={$ease_path} stroke="#333" stroke-width="2" fill="none" />
d={$ease_path}
stroke="#333"
stroke-width="2"
fill="none"
/>
<path d="M0,23.647C0,22.41 27.014,0.407 28.496,0.025C29.978,-0.357 69.188,3.744 70.104,4.744C71.02,5.745 71.02,41.499 70.104,42.5C69.188,43.501 29.978,47.601 28.496,47.219C27.014,46.837 0,24.884 0,23.647Z" <path
d="M0,23.647C0,22.41 27.014,0.407 28.496,0.025C29.978,-0.357 69.188,3.744 70.104,4.744C71.02,5.745 71.02,41.499 70.104,42.5C69.188,43.501 29.978,47.601 28.496,47.219C27.014,46.837 0,24.884 0,23.647Z"
fill="#ff3e00" fill="#ff3e00"
style="transform: translate(1060px, {($value - 24)}px)" style="transform: translate(1060px, {$value - 24}px)"
/> />
<circle <circle cx={$time} cy={$value} r="15" fill="#ff3e00" />
cx="{$time}"
cy="{$value}"
r="15"
fill="#ff3e00"
/>
</g> </g>
</g> </g>
</svg> </svg>
@ -93,7 +84,7 @@
} }
.graph { .graph {
transform: translate(200px,400px) transform: translate(200px, 400px);
} }
@media (max-width: 600px) { @media (max-width: 600px) {

@ -20,10 +20,7 @@
{#if mobile} {#if mobile}
<select bind:value={current_ease}> <select bind:value={current_ease}>
{#each [...eases] as [name]} {#each [...eases] as [name]}
<option <option value={name} class:selected={name === current_ease}>
value={name}
class:selected={name === current_ease}
>
{name} {name}
</option> </option>
{/each} {/each}
@ -31,10 +28,7 @@
{:else} {:else}
<ul> <ul>
{#each [...eases] as [name]} {#each [...eases] as [name]}
<li <li class:selected={name === current_ease} on:click={() => (current_ease = name)}>
class:selected={name === current_ease}
on:click={() => current_ease = name}
>
{name} {name}
</li> </li>
{/each} {/each}
@ -44,9 +38,7 @@
{#if mobile} {#if mobile}
<select bind:value={current_type}> <select bind:value={current_type}>
{#each types as [name, type]} {#each types as [name, type]}
<option <option value={type}>
value={type}
>
{name} {name}
</option> </option>
{/each} {/each}
@ -54,24 +46,19 @@
{:else} {:else}
<ul> <ul>
{#each types as [name, type]} {#each types as [name, type]}
<li <li class:selected={type === current_type} on:click={() => (current_type = type)}>
class:selected={type === current_type}
on:click={() => current_type = type}
>
{name} {name}
</li> </li>
{/each} {/each}
</ul> </ul>
{/if} {/if}
</div> </div>
<h4> <h4>Duration</h4>
Duration
</h4>
<div class="duration"> <div class="duration">
<span> <span>
<input type="number" bind:value={duration} min="0" step="100" /> <input type="number" bind:value={duration} min="0" step="100" />
<button class="number" on:click={() => duration -= 100}>-</button> <button class="number" on:click={() => (duration -= 100)}>-</button>
<button class="number" on:click={() => duration += 100}>+</button> <button class="number" on:click={() => (duration += 100)}>+</button>
</span> </span>
<button class="play" on:click={() => dispatch('play')}> <button class="play" on:click={() => dispatch('play')}>
{playing ? 'Restart' : 'Play'} {playing ? 'Restart' : 'Play'}
@ -79,7 +66,6 @@
</div> </div>
</div> </div>
<style> <style>
.easing-sidebar { .easing-sidebar {
width: 11em; width: 11em;

@ -1,52 +1,30 @@
<svelte:options namespace="svg" />
<script> <script>
export let x, y; export let x, y;
</script> </script>
<svelte:options namespace="svg" />
<rect <rect
x=0 x="0"
y=0 y="0"
width=1400 width="1400"
height=1800 height="1800"
stroke=#ccc stroke="#ccc"
style="opacity: 0.5" style="opacity: 0.5"
fill=none fill="none"
stroke-width=2 stroke-width="2"
/> />
{#each { length: 8 } as _, i} {#each { length: 8 } as _, i}
{#if i < 6} {#if i < 6}
<path <path d="M{(i + 1) * 200} 0 L{(i + 1) * 200} 1802" class="grid-line" />
d="M{(i+1) * 200} 0 L{(i+1)*200} 1802"
class="grid-line"
/>
{/if} {/if}
<path <path d="M0 {(i + 1) * 200} L1400 {(i + 1) * 200} " class="grid-line" />
d="M0 {(i+1) * 200} L1400 {(i+1)*200} "
class="grid-line"
/>
{/each} {/each}
<path <path style="transform: translateX({x + 200}px)" d="M0 0 L0 1800" class="grid-line-xy" />
style="transform: translateX({x+200}px)" <path style="transform: translateY({y}px)" d="M0 400 L1400 400" class="grid-line-xy" />
d="M0 0 L0 1800" <rect x="200" y="400" width="1000" height="1000" stroke="#999" fill="none" stroke-width="2" />
class="grid-line-xy"
/>
<path
style="transform: translateY({y}px)"
d="M0 400 L1400 400"
class="grid-line-xy"
/>
<rect
x=200
y=400
width=1000
height=1000
stroke=#999
fill=none
stroke-width=2
/>
<style> <style>
.grid-line { .grid-line {

@ -20,48 +20,28 @@
}); });
</script> </script>
<svg viewBox='-50 -50 100 100'> <svg viewBox="-50 -50 100 100">
<circle class='clock-face' r='48'/> <circle class="clock-face" r="48" />
<!-- markers --> <!-- markers -->
{#each [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55] as minute} {#each [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55] as minute}
<line <line class="major" y1="35" y2="45" transform="rotate({30 * minute})" />
class='major'
y1='35'
y2='45'
transform='rotate({30 * minute})'
/>
{#each [1, 2, 3, 4] as offset} {#each [1, 2, 3, 4] as offset}
<line <line class="minor" y1="42" y2="45" transform="rotate({6 * (minute + offset)})" />
class='minor'
y1='42'
y2='45'
transform='rotate({6 * (minute + offset)})'
/>
{/each} {/each}
{/each} {/each}
<!-- hour hand --> <!-- hour hand -->
<line <line class="hour" y1="2" y2="-20" transform="rotate({30 * hours + minutes / 2})" />
class='hour'
y1='2'
y2='-20'
transform='rotate({30 * hours + minutes / 2})'
/>
<!-- minute hand --> <!-- minute hand -->
<line <line class="minute" y1="4" y2="-30" transform="rotate({6 * minutes + seconds / 10})" />
class='minute'
y1='4'
y2='-30'
transform='rotate({6 * minutes + seconds / 10})'
/>
<!-- second hand --> <!-- second hand -->
<g transform='rotate({6 * seconds})'> <g transform="rotate({6 * seconds})">
<line class='second' y1='10' y2='-38'/> <line class="second" y1="10" y2="-38" />
<line class='second-counterweight' y1='10' y2='2'/> <line class="second-counterweight" y1="10" y2="2" />
</g> </g>
</svg> </svg>
@ -94,7 +74,8 @@
stroke: #666; stroke: #666;
} }
.second, .second-counterweight { .second,
.second-counterweight {
stroke: rgb(180, 0, 0); stroke: rgb(180, 0, 0);
} }

@ -41,7 +41,7 @@
<g class="axis y-axis"> <g class="axis y-axis">
{#each yTicks as tick} {#each yTicks as tick}
<g class="tick tick-{tick}" transform="translate(0, {yScale(tick)})"> <g class="tick tick-{tick}" transform="translate(0, {yScale(tick)})">
<line x2="100%"></line> <line x2="100%" />
<text y="-4">{tick} {tick === 20 ? ' per 1,000 population' : ''}</text> <text y="-4">{tick} {tick === 20 ? ' per 1,000 population' : ''}</text>
</g> </g>
{/each} {/each}
@ -51,19 +51,19 @@
<g class="axis x-axis"> <g class="axis x-axis">
{#each points as point, i} {#each points as point, i}
<g class="tick" transform="translate({xScale(i)},{height})"> <g class="tick" transform="translate({xScale(i)},{height})">
<text x="{barWidth/2}" y="-4">{width > 380 ? point.year : formatMobile(point.year)}</text> <text x={barWidth / 2} y="-4">{width > 380 ? point.year : formatMobile(point.year)}</text>
</g> </g>
{/each} {/each}
</g> </g>
<g class='bars'> <g class="bars">
{#each points as point, i} {#each points as point, i}
<rect <rect
x="{xScale(i) + 2}" x={xScale(i) + 2}
y="{yScale(point.birthrate)}" y={yScale(point.birthrate)}
width="{barWidth - 4}" width={barWidth - 4}
height="{yScale(0) - yScale(point.birthrate)}" height={yScale(0) - yScale(point.birthrate)}
></rect> />
{/each} {/each}
</g> </g>
</svg> </svg>
@ -88,7 +88,7 @@
.tick { .tick {
font-family: Helvetica, Arial; font-family: Helvetica, Arial;
font-size: .725em; font-size: 0.725em;
font-weight: 200; font-weight: 200;
} }

@ -19,7 +19,7 @@
$: minX = points[0].x; $: minX = points[0].x;
$: maxX = points[points.length - 1].x; $: maxX = points[points.length - 1].x;
$: path = `M${points.map(p => `${xScale(p.x)},${yScale(p.y)}`).join('L')}`; $: path = `M${points.map((p) => `${xScale(p.x)},${yScale(p.y)}`).join('L')}`;
$: area = `${path}L${xScale(maxX)},${yScale(0)}L${xScale(minX)},${yScale(0)}Z`; $: area = `${path}L${xScale(maxX)},${yScale(0)}L${xScale(minX)},${yScale(0)}Z`;
function formatMobile(tick) { function formatMobile(tick) {
@ -35,7 +35,7 @@
<g class="axis y-axis" transform="translate(0, {padding.top})"> <g class="axis y-axis" transform="translate(0, {padding.top})">
{#each yTicks as tick} {#each yTicks as tick}
<g class="tick tick-{tick}" transform="translate(0, {yScale(tick) - padding.bottom})"> <g class="tick tick-{tick}" transform="translate(0, {yScale(tick) - padding.bottom})">
<line x2="100%"></line> <line x2="100%" />
<text y="-4">{tick} {tick === 8 ? ' million sq km' : ''}</text> <text y="-4">{tick} {tick === 8 ? ' million sq km' : ''}</text>
</g> </g>
{/each} {/each}
@ -45,22 +45,28 @@
<g class="axis x-axis"> <g class="axis x-axis">
{#each xTicks as tick} {#each xTicks as tick}
<g class="tick tick-{tick}" transform="translate({xScale(tick)},{height})"> <g class="tick tick-{tick}" transform="translate({xScale(tick)},{height})">
<line y1="-{height}" y2="-{padding.bottom}" x1="0" x2="0"></line> <line y1="-{height}" y2="-{padding.bottom}" x1="0" x2="0" />
<text y="-2">{width > 380 ? tick : formatMobile(tick)}</text> <text y="-2">{width > 380 ? tick : formatMobile(tick)}</text>
</g> </g>
{/each} {/each}
</g> </g>
<!-- data --> <!-- data -->
<path class="path-area" d={area}></path> <path class="path-area" d={area} />
<path class="path-line" d={path}></path> <path class="path-line" d={path} />
</svg> </svg>
</div> </div>
<p>Average September extent. Source: <a href='https://climate.nasa.gov/vital-signs/arctic-sea-ice/'>NSIDC/NASA</a></p> <p>
Average September extent. Source: <a href="https://climate.nasa.gov/vital-signs/arctic-sea-ice/"
>NSIDC/NASA</a
>
</p>
<style> <style>
.chart, h2, p { .chart,
h2,
p {
width: 100%; width: 100%;
max-width: 500px; max-width: 500px;
margin-left: auto; margin-left: auto;
@ -75,7 +81,7 @@
} }
.tick { .tick {
font-size: .725em; font-size: 0.725em;
font-weight: 200; font-weight: 200;
} }

@ -18,13 +18,9 @@
.domain([0, 12]) .domain([0, 12])
.range([height - padding.bottom, padding.top]); .range([height - padding.bottom, padding.top]);
$: xTicks = width > 180 ? $: xTicks = width > 180 ? [0, 4, 8, 12, 16, 20] : [0, 10, 20];
[0, 4, 8, 12, 16, 20] :
[0, 10, 20];
$: yTicks = height > 180 ? $: yTicks = height > 180 ? [0, 2, 4, 6, 8, 10, 12] : [0, 4, 8, 12];
[0, 2, 4, 6, 8, 10, 12] :
[0, 4, 8, 12];
onMount(resize); onMount(resize);
@ -33,32 +29,32 @@
} }
</script> </script>
<svelte:window on:resize='{resize}'/> <svelte:window on:resize={resize} />
<svg bind:this={svg}> <svg bind:this={svg}>
<!-- y axis --> <!-- y axis -->
<g class='axis y-axis'> <g class="axis y-axis">
{#each yTicks as tick} {#each yTicks as tick}
<g class='tick tick-{tick}' transform='translate(0, {yScale(tick)})'> <g class="tick tick-{tick}" transform="translate(0, {yScale(tick)})">
<line x1='{padding.left}' x2='{xScale(22)}'/> <line x1={padding.left} x2={xScale(22)} />
<text x='{padding.left - 8}' y='+4'>{tick}</text> <text x={padding.left - 8} y="+4">{tick}</text>
</g> </g>
{/each} {/each}
</g> </g>
<!-- x axis --> <!-- x axis -->
<g class='axis x-axis'> <g class="axis x-axis">
{#each xTicks as tick} {#each xTicks as tick}
<g class='tick' transform='translate({xScale(tick)},0)'> <g class="tick" transform="translate({xScale(tick)},0)">
<line y1='{yScale(0)}' y2='{yScale(13)}'/> <line y1={yScale(0)} y2={yScale(13)} />
<text y='{height - padding.bottom + 16}'>{tick}</text> <text y={height - padding.bottom + 16}>{tick}</text>
</g> </g>
{/each} {/each}
</g> </g>
<!-- data --> <!-- data -->
{#each points as point} {#each points as point}
<circle cx='{xScale(point.x)}' cy='{yScale(point.y)}' r='5'/> <circle cx={xScale(point.x)} cy={yScale(point.y)} r="5" />
{/each} {/each}
</svg> </svg>

@ -9,35 +9,29 @@
{#if visible} {#if visible}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 103 124"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 103 124">
<g out:fade="{{duration: 200}}" opacity=0.2> <g out:fade={{ duration: 200 }} opacity="0.2">
<path <path
in:expand="{{duration: 400, delay: 1000, easing: quintOut}}" in:expand={{ duration: 400, delay: 1000, easing: quintOut }}
style="stroke: #ff3e00; fill: #ff3e00; stroke-width: 50;" style="stroke: #ff3e00; fill: #ff3e00; stroke-width: 50;"
d={outer} d={outer}
/> />
<path <path in:draw={{ duration: 1000 }} style="stroke:#ff3e00; stroke-width: 1.5" d={inner} />
in:draw="{{duration: 1000}}"
style="stroke:#ff3e00; stroke-width: 1.5"
d={inner}
/>
</g> </g>
</svg> </svg>
<div class="centered" out:fly="{{y: -20, duration: 800}}"> <div class="centered" out:fly={{ y: -20, duration: 800 }}>
{#each 'SVELTE' as char, i} {#each 'SVELTE' as char, i}
<span <span in:fade={{ delay: 1000 + i * 150, duration: 800 }}>{char}</span>
in:fade="{{delay: 1000 + i * 150, duration: 800}}"
>{char}</span>
{/each} {/each}
</div> </div>
{/if} {/if}
<label> <label>
<input type="checkbox" bind:checked={visible}> <input type="checkbox" bind:checked={visible} />
toggle me toggle me
</label> </label>
<link href="https://fonts.googleapis.com/css?family=Overpass:100,400" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Overpass:100,400" rel="stylesheet" />
<style> <style>
svg { svg {

@ -1,14 +1,12 @@
<script> <script>
import { clickOutside } from "./click_outside.js"; import { clickOutside } from './click_outside.js';
let showModal = true; let showModal = true;
</script> </script>
<button on:click={() => (showModal = true)}>Show Modal</button> <button on:click={() => (showModal = true)}>Show Modal</button>
{#if showModal} {#if showModal}
<div class="box" use:clickOutside on:outclick={() => (showModal = false)}> <div class="box" use:clickOutside on:outclick={() => (showModal = false)}>Click outside me!</div>
Click outside me!
</div>
{/if} {/if}
<style> <style>

@ -6,14 +6,15 @@
</script> </script>
<label> <label>
<input type=range bind:value={duration} max={2000} step={100}> <input type="range" bind:value={duration} max={2000} step={100} />
{duration}ms {duration}ms
</label> </label>
<button use:longpress={duration} <button
on:longpress="{() => pressed = true}" use:longpress={duration}
on:mouseenter="{() => pressed = false}" on:longpress={() => (pressed = true)}
>press and hold</button> on:mouseenter={() => (pressed = false)}>press and hold</button
>
{#if pressed} {#if pressed}
<p>congratulations, you pressed and held for {duration}ms</p> <p>congratulations, you pressed and held for {duration}ms</p>

@ -2,17 +2,20 @@
import { spring } from 'svelte/motion'; import { spring } from 'svelte/motion';
import { pannable } from './pannable.js'; import { pannable } from './pannable.js';
const coords = spring({ x: 0, y: 0 }, { const coords = spring(
{ x: 0, y: 0 },
{
stiffness: 0.2, stiffness: 0.2,
damping: 0.4 damping: 0.4
}); }
);
function handlePanStart() { function handlePanStart() {
coords.stiffness = coords.damping = 1; coords.stiffness = coords.damping = 1;
} }
function handlePanMove(event) { function handlePanMove(event) {
coords.update($coords => ({ coords.update(($coords) => ({
x: $coords.x + event.detail.dx, x: $coords.x + event.detail.dx,
y: $coords.y + event.detail.dy y: $coords.y + event.detail.dy
})); }));
@ -25,7 +28,8 @@
} }
</script> </script>
<div class="box" <div
class="box"
use:pannable use:pannable
on:panstart={handlePanStart} on:panstart={handlePanStart}
on:panmove={handlePanMove} on:panmove={handlePanMove}
@ -33,7 +37,7 @@
style="transform: style="transform:
translate({$coords.x}px,{$coords.y}px) translate({$coords.x}px,{$coords.y}px)
rotate({$coords.x * 0.2}deg)" rotate({$coords.x * 0.2}deg)"
></div> />
<style> <style>
.box { .box {

@ -2,20 +2,11 @@
let current = 'foo'; let current = 'foo';
</script> </script>
<button <button class:active={current === 'foo'} on:click={() => (current = 'foo')}>foo</button>
class:active="{current === 'foo'}"
on:click="{() => current = 'foo'}"
>foo</button>
<button <button class:active={current === 'bar'} on:click={() => (current = 'bar')}>bar</button>
class:active="{current === 'bar'}"
on:click="{() => current = 'bar'}"
>bar</button>
<button <button class:active={current === 'baz'} on:click={() => (current = 'baz')}>baz</button>
class:active="{current === 'baz'}"
on:click="{() => current = 'baz'}"
>baz</button>
<style> <style>
button { button {

@ -3,7 +3,7 @@
</script> </script>
<label> <label>
<input type=checkbox bind:checked={big}> <input type="checkbox" bind:checked={big} />
big big
</label> </label>

@ -1,5 +1,5 @@
<div class="box"> <div class="box">
<slot></slot> <slot />
</div> </div>
<style> <style>

@ -3,12 +3,10 @@
</script> </script>
<ContactCard> <ContactCard>
<span slot="name"> <span slot="name"> P. Sherman </span>
P. Sherman
</span>
<span slot="address"> <span slot="address">
42 Wallaby Way<br> 42 Wallaby Way<br />
Sydney Sydney
</span> </span>
</ContactCard> </ContactCard>

@ -30,10 +30,11 @@
h2 { h2 {
padding: 0 0 0.2em 0; padding: 0 0 0.2em 0;
margin: 0 0 1em 0; margin: 0 0 1em 0;
border-bottom: 1px solid #ff3e00 border-bottom: 1px solid #ff3e00;
} }
.address, .email { .address,
.email {
padding: 0 0 0 1.5em; padding: 0 0 0 1.5em;
background: 0 0 no-repeat; background: 0 0 no-repeat;
background-size: 20px 20px; background-size: 20px 20px;
@ -41,7 +42,13 @@
line-height: 1.2; line-height: 1.2;
} }
.address { background-image: url(/tutorial/icons/map-marker.svg) } .address {
.email { background-image: url(/tutorial/icons/email.svg) } background-image: url(/tutorial/icons/map-marker.svg);
.missing { color: #999 } }
.email {
background-image: url(/tutorial/icons/email.svg);
}
.missing {
color: #999;
}
</style> </style>

@ -11,5 +11,5 @@
</script> </script>
<div on:mouseenter={enter} on:mouseleave={leave}> <div on:mouseenter={enter} on:mouseleave={leave}>
<slot hovering={hovering}></slot> <slot {hovering} />
</div> </div>

@ -1,5 +1,5 @@
<script> <script>
import Profile from "./Profile.svelte"; import Profile from './Profile.svelte';
</script> </script>
<Profile> <Profile>

@ -4,9 +4,7 @@
let showModal = false; let showModal = false;
</script> </script>
<button on:click={() => (showModal = true)}> <button on:click={() => (showModal = true)}> show modal </button>
show modal
</button>
<Modal bind:showModal> <Modal bind:showModal>
<h2 slot="header"> <h2 slot="header">
@ -17,11 +15,15 @@
<ol class="definition-list"> <ol class="definition-list">
<li>of or relating to modality in logic</li> <li>of or relating to modality in logic</li>
<li> <li>
containing provisions as to the mode of procedure or the manner of taking effect —used of a contract or legacy containing provisions as to the mode of procedure or the manner of taking effect —used of a
contract or legacy
</li> </li>
<li>of or relating to a musical mode</li> <li>of or relating to a musical mode</li>
<li>of or relating to structure as opposed to substance</li> <li>of or relating to structure as opposed to substance</li>
<li>of, relating to, or constituting a grammatical form or category characteristically indicating predication</li> <li>
of, relating to, or constituting a grammatical form or category characteristically indicating
predication
</li>
<li>of or relating to a statistical mode</li> <li>of or relating to a statistical mode</li>
</ol> </ol>

@ -6,8 +6,8 @@
<Map lat={35} lon={-84} zoom={3.5}> <Map lat={35} lon={-84} zoom={3.5}>
<MapMarker lat={37.8225} lon={-122.0024} label="Svelte Body Shaping" /> <MapMarker lat={37.8225} lon={-122.0024} label="Svelte Body Shaping" />
<MapMarker lat={33.8981} lon={-118.4169} label="Svelte Barbershop & Essentials" /> <MapMarker lat={33.8981} lon={-118.4169} label="Svelte Barbershop & Essentials" />
<MapMarker lat={29.7230} lon={-95.4189} label="Svelte Waxing Studio"/> <MapMarker lat={29.723} lon={-95.4189} label="Svelte Waxing Studio" />
<MapMarker lat={28.3378} lon={-81.3966} label="Svelte 30 Nutritional Consultants" /> <MapMarker lat={28.3378} lon={-81.3966} label="Svelte 30 Nutritional Consultants" />
<MapMarker lat={40.6483} lon={-74.0237} label="Svelte Brands LLC" /> <MapMarker lat={40.6483} lon={-74.0237} label="Svelte Brands LLC" />
<MapMarker lat={40.6986} lon={-74.4100} label="Svelte Medical Systems"/> <MapMarker lat={40.6986} lon={-74.41} label="Svelte Medical Systems" />
</Map> </Map>

@ -3,7 +3,7 @@
import { mapbox, key } from './mapbox.js'; import { mapbox, key } from './mapbox.js';
setContext(key, { setContext(key, {
getMap: () => map, getMap: () => map
}); });
export let lat; export let lat;
@ -18,7 +18,7 @@
container, container,
style: 'mapbox://styles/mapbox/streets-v9', style: 'mapbox://styles/mapbox/streets-v9',
center: [lon, lat], center: [lon, lat],
zoom, zoom
}); });
} }
@ -28,11 +28,7 @@
</script> </script>
<svelte:head> <svelte:head>
<link <link rel="stylesheet" href="https://unpkg.com/mapbox-gl/dist/mapbox-gl.css" on:load={load} />
rel="stylesheet"
href="https://unpkg.com/mapbox-gl/dist/mapbox-gl.css"
on:load={load}
/>
</svelte:head> </svelte:head>
<div bind:this={container}> <div bind:this={container}>

@ -9,11 +9,7 @@
export let lon; export let lon;
export let label; export let label;
const popup = new mapbox.Popup({ offset: 25 }) const popup = new mapbox.Popup({ offset: 25 }).setText(label);
.setText(label);
const marker = new mapbox.Marker() const marker = new mapbox.Marker().setLngLat([lon, lat]).setPopup(popup).addTo(map);
.setLngLat([lon, lat])
.setPopup(popup)
.addTo(map);
</script> </script>

@ -5,9 +5,7 @@
{ {
type: 'folder', type: 'folder',
name: 'Important work stuff', name: 'Important work stuff',
files: [ files: [{ type: 'file', name: 'quarterly-results.xlsx' }]
{ type: 'file', name: 'quarterly-results.xlsx' }
]
}, },
{ {
type: 'folder', type: 'folder',

@ -1,6 +1,6 @@
<script> <script>
import File from './File.svelte'; import File from './File.svelte';
import {slide} from 'svelte/transition' import { slide } from 'svelte/transition';
export let expanded = false; export let expanded = false;
export let name; export let name;

@ -6,7 +6,7 @@
const options = [ const options = [
{ color: 'red', component: RedThing }, { color: 'red', component: RedThing },
{ color: 'green', component: GreenThing }, { color: 'green', component: GreenThing },
{ color: 'blue', component: BlueThing }, { color: 'blue', component: BlueThing }
]; ];
let selected = options[0]; let selected = options[0];

@ -9,17 +9,15 @@
<a class="parallax-container" href="https://www.firewatchgame.com"> <a class="parallax-container" href="https://www.firewatchgame.com">
{#each layers as layer} {#each layers as layer}
<img <img
style="transform: translate(0,{-y * layer / (layers.length - 1)}px)" style="transform: translate(0,{(-y * layer) / (layers.length - 1)}px)"
src="https://www.firewatchgame.com/images/parallax/parallax{layer}.png" src="https://www.firewatchgame.com/images/parallax/parallax{layer}.png"
alt="parallax layer {layer}" alt="parallax layer {layer}"
> />
{/each} {/each}
</a> </a>
<div class="text"> <div class="text">
<span style="opacity: {1 - Math.max(0, y / 40)}"> <span style="opacity: {1 - Math.max(0, y / 40)}"> scroll down </span>
scroll down
</span>
<div class="foreground"> <div class="foreground">
You have scrolled {y} pixels You have scrolled {y} pixels

@ -1,7 +1,7 @@
<script> <script>
let selection = ''; let selection = '';
const handleSelectionChange = (e) => selection = document.getSelection(); const handleSelectionChange = (e) => (selection = document.getSelection());
</script> </script>
<svelte:document on:selectionchange={handleSelectionChange} /> <svelte:document on:selectionchange={handleSelectionChange} />

@ -1,21 +1,18 @@
<script> <script>
let hereKitty = false; let hereKitty = false;
const handleMouseenter = () => hereKitty = true; const handleMouseenter = () => (hereKitty = true);
const handleMouseleave = () => hereKitty = false; const handleMouseleave = () => (hereKitty = false);
</script> </script>
<svelte:body <svelte:body on:mouseenter={handleMouseenter} on:mouseleave={handleMouseleave} />
on:mouseenter={handleMouseenter}
on:mouseleave={handleMouseleave}
/>
<!-- creative commons BY-NC http://www.pngall.com/kitten-png/download/7247 --> <!-- creative commons BY-NC http://www.pngall.com/kitten-png/download/7247 -->
<img <img
class:curious={hereKitty} class:curious={hereKitty}
alt="Kitten wants to know what's going on" alt="Kitten wants to know what's going on"
src="/tutorial/kitten.png" src="/tutorial/kitten.png"
> />
<style> <style>
img { img {

@ -1,5 +1,5 @@
<svelte:head> <svelte:head>
<link rel="stylesheet" href="/tutorial/dark-theme.css"> <link rel="stylesheet" href="/tutorial/dark-theme.css" />
</svelte:head> </svelte:head>
<h1>Hello world!</h1> <h1>Hello world!</h1>

@ -2,9 +2,7 @@
import AudioPlayer, { stopAll } from './AudioPlayer.svelte'; import AudioPlayer, { stopAll } from './AudioPlayer.svelte';
</script> </script>
<button on:click={stopAll}> <button on:click={stopAll}> stop all audio </button>
stop all audio
</button>
<!-- https://musopen.org/music/9862-the-blue-danube-op-314/ --> <!-- https://musopen.org/music/9862-the-blue-danube-op-314/ -->
<AudioPlayer <AudioPlayer

@ -2,7 +2,7 @@
const elements = new Set(); const elements = new Set();
export function stopAll() { export function stopAll() {
elements.forEach(element => { elements.forEach((element) => {
element.pause(); element.pause();
}); });
} }
@ -25,7 +25,7 @@
}); });
function stopOthers() { function stopOthers() {
elements.forEach(element => { elements.forEach((element) => {
if (element !== audio) element.pause(); if (element !== audio) element.pause();
}); });
} }
@ -35,18 +35,23 @@
<h2>{title}</h2> <h2>{title}</h2>
<p><strong>{composer}</strong> / performed by {performer}</p> <p><strong>{composer}</strong> / performed by {performer}</p>
<audio <audio bind:this={audio} bind:paused on:play={stopOthers} controls {src} />
bind:this={audio}
bind:paused
on:play={stopOthers}
controls
{src}
></audio>
</article> </article>
<style> <style>
article { margin: 0 0 1em 0; max-width: 800px } article {
h2, p { margin: 0 0 0.3em 0; } margin: 0 0 1em 0;
audio { width: 100%; margin: 0.5em 0 1em 0; } max-width: 800px;
.playing { color: #ff3e00; } }
h2,
p {
margin: 0 0 0.3em 0;
}
audio {
width: 100%;
margin: 0.5em 0 1em 0;
}
.playing {
color: #ff3e00;
}
</style> </style>

@ -5,8 +5,8 @@
}; };
</script> </script>
<input bind:value={user.firstname}> <input bind:value={user.firstname} />
<input bind:value={user.lastname}> <input bind:value={user.lastname} />
{@debug user} {@debug user}

@ -3,5 +3,5 @@
let count = 0; let count = 0;
</script> </script>
<input type=number bind:value={count}> <input type="number" bind:value={count} />
<button on:click="{() => count += 1}">count</button> <button on:click={() => (count += 1)}>count</button>

@ -4,18 +4,18 @@
function setBothFromC(value) { function setBothFromC(value) {
c = +value; c = +value;
f = +(32 + (9 / 5 * c)).toFixed(1); f = +(32 + (9 / 5) * c).toFixed(1);
} }
function setBothFromF(value) { function setBothFromF(value) {
f = +value; f = +value;
c =+(5 / 9 * (f - 32)).toFixed(1); c = +((5 / 9) * (f - 32)).toFixed(1);
} }
</script> </script>
<!-- https://eugenkiss.github.io/7guis/tasks/#temp --> <!-- https://eugenkiss.github.io/7guis/tasks/#temp -->
<input value={c} on:input="{e => setBothFromC(e.target.value)}" type=number> °C = <input value={c} on:input={(e) => setBothFromC(e.target.value)} type="number" /> °C =
<input value={f} on:input="{e => setBothFromF(e.target.value)}" type=number> °F <input value={f} on:input={(e) => setBothFromF(e.target.value)} type="number" /> °F
<style> <style>
input { input {

@ -42,16 +42,15 @@
<option value={true}>return flight</option> <option value={true}>return flight</option>
</select> </select>
<input type=date bind:value={start}> <input type="date" bind:value={start} />
<input type=date bind:value={end} disabled={!isReturn}> <input type="date" bind:value={end} disabled={!isReturn} />
<button <button on:click={bookFlight} disabled={isReturn && startDate >= endDate}>book</button>
on:click={bookFlight}
disabled="{isReturn && (startDate >= endDate)}"
>book</button>
<style> <style>
select, input, button { select,
input,
button {
display: block; display: block;
margin: 0.5em 0; margin: 0.5em 0;
font-size: inherit; font-size: inherit;

@ -13,13 +13,10 @@
frame = requestAnimationFrame(update); frame = requestAnimationFrame(update);
const time = window.performance.now(); const time = window.performance.now();
elapsed += Math.min( elapsed += Math.min(time - last_time, duration - elapsed);
time - last_time,
duration - elapsed
);
last_time = time; last_time = time;
}()); })();
onDestroy(() => { onDestroy(() => {
cancelAnimationFrame(frame); cancelAnimationFrame(frame);
@ -28,14 +25,14 @@
<label> <label>
elapsed time: elapsed time:
<progress value="{elapsed / duration}"></progress> <progress value={elapsed / duration} />
</label> </label>
<div>{(elapsed / 1000).toFixed(1)}s</div> <div>{(elapsed / 1000).toFixed(1)}s</div>
<label> <label>
duration: duration:
<input type="range" bind:value={duration} min="1" max="20000"> <input type="range" bind:value={duration} min="1" max="20000" />
</label> </label>
<button on:click="{() => elapsed = 0}">reset</button> <button on:click={() => (elapsed = 0)}>reset</button>

@ -13,7 +13,7 @@
let i = 0; let i = 0;
$: filteredPeople = prefix $: filteredPeople = prefix
? people.filter(person => { ? people.filter((person) => {
const name = `${person.last}, ${person.first}`; const name = `${person.last}, ${person.first}`;
return name.toLowerCase().startsWith(prefix.toLowerCase()); return name.toLowerCase().startsWith(prefix.toLowerCase());
}) })
@ -50,7 +50,7 @@
} }
</script> </script>
<input placeholder="filter prefix" bind:value={prefix}> <input placeholder="filter prefix" bind:value={prefix} />
<select bind:value={i} size={5}> <select bind:value={i} size={5}>
{#each filteredPeople as person, i} {#each filteredPeople as person, i}
@ -58,13 +58,13 @@
{/each} {/each}
</select> </select>
<label><input bind:value={first} placeholder="first"></label> <label><input bind:value={first} placeholder="first" /></label>
<label><input bind:value={last} placeholder="last"></label> <label><input bind:value={last} placeholder="last" /></label>
<div class='buttons'> <div class="buttons">
<button on:click={create} disabled="{!first || !last}">create</button> <button on:click={create} disabled={!first || !last}>create</button>
<button on:click={update} disabled="{!first || !last || !selected}">update</button> <button on:click={update} disabled={!first || !last || !selected}>update</button>
<button on:click={remove} disabled="{!selected}">delete</button> <button on:click={remove} disabled={!selected}>delete</button>
</div> </div>
<style> <style>

@ -56,7 +56,7 @@ radius of the selected circle.
} }
function travel(d) { function travel(d) {
circles = clone(undoStack[i += d]); circles = clone(undoStack[(i += d)]);
adjusting = false; adjusting = false;
} }
@ -66,19 +66,22 @@ radius of the selected circle.
</script> </script>
<div class="controls"> <div class="controls">
<button on:click="{() => travel(-1)}" disabled="{i === 0}">undo</button> <button on:click={() => travel(-1)} disabled={i === 0}>undo</button>
<button on:click="{() => travel(+1)}" disabled="{i === undoStack.length -1}">redo</button> <button on:click={() => travel(+1)} disabled={i === undoStack.length - 1}>redo</button>
</div> </div>
<svg on:click={handleClick}> <svg on:click={handleClick}>
{#each circles as circle} {#each circles as circle}
<circle cx={circle.cx} cy={circle.cy} r={circle.r} <circle
on:click="{event => select(circle, event)}" cx={circle.cx}
on:contextmenu|stopPropagation|preventDefault="{() => { cy={circle.cy}
r={circle.r}
on:click={(event) => select(circle, event)}
on:contextmenu|stopPropagation|preventDefault={() => {
adjusting = !adjusting; adjusting = !adjusting;
if (adjusting) selected = circle; if (adjusting) selected = circle;
}}" }}
fill="{circle === selected ? '#ccc': 'white'}" fill={circle === selected ? '#ccc' : 'white'}
/> />
{/each} {/each}
</svg> </svg>
@ -86,7 +89,7 @@ radius of the selected circle.
{#if adjusting} {#if adjusting}
<div class="adjuster"> <div class="adjuster">
<p>adjust diameter of circle at {selected.cx}, {selected.cy}</p> <p>adjust diameter of circle at {selected.cx}, {selected.cy}</p>
<input type="range" value={selected.r} on:input={adjust}> <input type="range" value={selected.r} on:input={adjust} />
</div> </div>
{/if} {/if}

@ -12,7 +12,7 @@
if (path.startsWith('/item')) { if (path.startsWith('/item')) {
const id = path.slice(6); const id = path.slice(6);
item = await fetch(`https://node-hnapi.herokuapp.com/item/${id}`).then(r => r.json()); item = await fetch(`https://node-hnapi.herokuapp.com/item/${id}`).then((r) => r.json());
window.scrollTo(0, 0); window.scrollTo(0, 0);
} else if (path.startsWith('/top')) { } else if (path.startsWith('/top')) {

@ -1,5 +1,5 @@
<script> <script>
import Comment from "./Comment.svelte"; import Comment from './Comment.svelte';
export let item; export let item;
export let returnTo; export let returnTo;
@ -10,14 +10,14 @@
<a href={returnTo}>&laquo; back</a> <a href={returnTo}>&laquo; back</a>
<article> <article>
<a href="{url}"> <a href={url}>
<h1>{item.title}</h1> <h1>{item.title}</h1>
{#if item.domain} {#if item.domain}
<small>{item.domain}</small> <small>{item.domain}</small>
{/if} {/if}
</a> </a>
<p class="meta">submitted by {item.user} {item.time_ago} <p class="meta">submitted by {item.user} {item.time_ago}</p>
</article> </article>
<div class="comments"> <div class="comments">

@ -1,6 +1,6 @@
<script> <script>
import { beforeUpdate } from "svelte"; import { beforeUpdate } from 'svelte';
import Summary from "./Summary.svelte"; import Summary from './Summary.svelte';
const PAGE_SIZE = 20; const PAGE_SIZE = 20;
@ -10,8 +10,8 @@
let offset; let offset;
$: fetch(`https://node-hnapi.herokuapp.com/news?page=${page}`) $: fetch(`https://node-hnapi.herokuapp.com/news?page=${page}`)
.then(r => r.json()) .then((r) => r.json())
.then(data => { .then((data) => {
items = data; items = data;
offset = PAGE_SIZE * (page - 1); offset = PAGE_SIZE * (page - 1);
window.scrollTo(0, 0); window.scrollTo(0, 0);
@ -40,7 +40,11 @@
} }
@keyframes fade-in { @keyframes fade-in {
from { opacity: 0; } from {
to { opacity: 1; } opacity: 0;
}
to {
opacity: 1;
}
} }
</style> </style>

@ -8,7 +8,7 @@
return `${c} ${c === 1 ? 'comment' : 'comments'}`; return `${c} ${c === 1 ? 'comment' : 'comments'}`;
} }
$: url = item.type === "ask" ? `https://news.ycombinator.com/${item.url}` : item.url; $: url = item.type === 'ask' ? `https://news.ycombinator.com/${item.url}` : item.url;
</script> </script>
<article> <article>

@ -9,7 +9,7 @@
]; ];
function toggle(id) { function toggle(id) {
todos = todos.map(todo => { todos = todos.map((todo) => {
if (todo.id === id) { if (todo.id === id) {
// return a new object // return a new object
return { return {
@ -27,10 +27,10 @@
<h2>Immutable</h2> <h2>Immutable</h2>
{#each todos as todo} {#each todos as todo}
<ImmutableTodo {todo} on:click="{() => toggle(todo.id)}"/> <ImmutableTodo {todo} on:click={() => toggle(todo.id)} />
{/each} {/each}
<h2>Mutable</h2> <h2>Mutable</h2>
{#each todos as todo} {#each todos as todo}
<MutableTodo {todo} on:click="{() => toggle(todo.id)}"/> <MutableTodo {todo} on:click={() => toggle(todo.id)} />
{/each} {/each}

@ -16,7 +16,8 @@
<!-- the text will flash red whenever <!-- the text will flash red whenever
the `todo` object changes --> the `todo` object changes -->
<div bind:this={div} on:click> <div bind:this={div} on:click>
{todo.done ? '👍': ''} {todo.text} {todo.done ? '👍' : ''}
{todo.text}
</div> </div>
<style> <style>

@ -14,7 +14,8 @@
<!-- the text will flash red whenever <!-- the text will flash red whenever
the `todo` object changes --> the `todo` object changes -->
<div bind:this={div} on:click> <div bind:this={div} on:click>
{todo.done ? '👍': ''} {todo.text} {todo.done ? '👍' : ''}
{todo.text}
</div> </div>
<style> <style>

@ -6,5 +6,12 @@
<Hero /> <Hero />
<div class={comicSans}> <div class={comicSans}>
<p>Did you enjoy your lunch, mom? You drank it fast enough. I know, I just call her Annabelle cause she's shaped like a…she's the belle of the ball! YOU'RE the Chiclet! Not me. Caw ca caw, caw ca caw, caw ca caw! A Colombian cartel that WON'T kidnap and kill you. You go buy a tape recorder and record yourself for a whole day. <a class={link} href="https://bluthipsum.com/">I think you'll be surprised at some of your phrasing.</a></p> <p>
Did you enjoy your lunch, mom? You drank it fast enough. I know, I just call her Annabelle cause
she's shaped like a…she's the belle of the ball! YOU'RE the Chiclet! Not me. Caw ca caw, caw ca
caw, caw ca caw! A Colombian cartel that WON'T kidnap and kill you. You go buy a tape recorder
and record yourself for a whole day. <a class={link} href="https://bluthipsum.com/"
>I think you'll be surprised at some of your phrasing.</a
>
</p>
</div> </div>

@ -3,7 +3,7 @@
let b = 2; let b = 2;
</script> </script>
<input type="number" bind:value={a}> <input type="number" bind:value={a} />
<input type="number" bind:value={b}> <input type="number" bind:value={b} />
<p>{a} + {b} = {a + b}</p> <p>{a} + {b} = {a + b}</p>

@ -2,4 +2,4 @@
let src = '/tutorial/image.gif'; let src = '/tutorial/image.gif';
</script> </script>
<img> <img />

@ -3,4 +3,4 @@
let name = 'Rick Astley'; let name = 'Rick Astley';
</script> </script>
<img {src} alt="{name} dances."> <img {src} alt="{name} dances." />

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save