{#if x > 10}
{x} is too large!
{:else if 5 > x}
{x} is perfect
{:else}
Not sure what you want me to do. >:(
{/if}
{#each any[] as foo, index (key)}
{foo} is at index: {index}
{/each}
{#await getRandomNumber()}
-- getRandomNumber() returns a promise/is async function
{:then number}
-- {number} is the promise resolution/returned value
{:catch error}
{error.message} is the error thrown
{/await}
{#await promise then value}
<p>the value is {value}</p>
{/await}
<button on:click|trusted={(e) => void }/>
preventDefault
— calls event.preventDefault() before running the handler. Useful for client-side form handling, for example.stopPropagation
— calls event.stopPropagation(), preventing the event reaching the next elementpassive
— improves scrolling performance on touch/wheel events (Svelte will add it automatically where it's safe to do so)nonpassive
— explicitly set passive: falsecapture
— fires the handler during the capture phase instead of the bubbling phase MDN docsonce
— remove the handler after the first time it runsself
— only trigger handler if event.target is the element itselftrusted
— only trigger handler if event.isTrusted is true. I.e. if the event is triggered by a user action.
You can chain modifiers together, e.g. on:click|once|capture={...}.
Any component can trigger an event using the createEventDispatcher
, the parent can handle what happens using the on:eventname={handler}
prop.
// App.svelte
<script>
import Inner from "./Inner.svelte";
</script>
<Inner on:customeventname={(e)=>alert(`Passed: ${e.detail.text}`)}/>
// Inner.svelte
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
</script>
<button on:click={()=>dispatch('customeventname', { text: 'Hello world!' })}>
Click me!
</button>
// App.svelte
<script>
import Outer from './Outer.svelte';
</script>
<Outer on:click={()=>alert("Root handled click")}/>
// Outer.svelte
<script>
import Inner from './Inner.svelte';
</script>
<Inner on:click />
// Inner.svelte
<button on:click >Click me!</button>
You can bind do any form element in different ways. Radio and Checkbox inputs can utilize groups, you can bind to object values (such as todos.done
) or even put a object into the value
field. Svelte doesn't mind.
<script>
let textContent = "Foo";
let textareaContent = "Bar";
let checBoxChecked = false;
let checBoxCheckedValues = ["red"];
let radioCheckedValue = null;
let todos = [
{id: 1, content: "Eat", done: false},
{id: 2, content: "Work", done: false},
{id: 3, content: "Sleep", done: false}
];
let selectedPeople = [];
</script>
<input bind:value={textContent} type=text />
<textarea bind:value={textareaContent}></textarea>
<label>
<input bind:checked={checBoxChecked} type=checkbox /> Checkbox
</label>
{#each ["red","green","blue"] as color}
<label>
<input bind:group={checBoxCheckedValues} type=checkbox value={color} /> {color}
</label>
{/each}
{#each ["red","green","blue"] as color}
<label>
<input bind:group={radioCheckedValue} type=radio value={color} /> {color}
</label>
{/each}
{#each todos as todo (todo.id)}
<label>
<input bind:checked={todo.done} type=checkbox /> {todo.content}
</label>
{/each}
<select multiple bind:value={selectedPeople}>
{#each [{name: "Mark", age: 28},{name:"Matt", age: 27}] as person}
<option value={person}>
{person.name}
</option>
{/each}
</select>
// ContenteditableBind.svelte
<script>
let html = '<p>Write text!</p>';
</script>
<div contenteditable="true" bind:innerHTML={html} />
// ReadonlyBinds.svelte
<script>
let [w,h,ow,oh] = [0,0,0,0]
</script>
<div bind:clientWidth={w} bind:clientHeight={h} bind:offsetWidth={ow} bind:offsetHeight={oh}>
// ThisBind.svelte
<script>
import { onMount } from 'svelte';
let canvas;
onMount(() => {
let frame = requestAnimationFrame(loop);
const loop = (timestamp) => {
frame = requestAnimationFrame(loop);
...
}
return () => cancelAnimationFrame(frame);
});
</script>
<canvas bind:this={canvas} .../>
// ComponentBinding.svelte
<script>
import Keypad from "./Keypad.svelte";
let pin = "";
</script>
<Keypad bind:value={pin} on:submit={handleSubmit}/>
// Keypad.svelte
<script>
export let value = 'default value';
</script>
Keypad can update parents pin
variable without dispatching any events.
View in svelte REPL
Lifecycle hooks take one argument, a callback function, and can only be called at root level of a component with the exception of tick
;
onMount
- return of onMount is cleanup, similar to useEffect from ReactonDestroy
- runs before component unmountsbeforeUpdate
- runs before DOM updates with updated dataafterUpdate
- runs after DOM updates with new datatick
- if you need for DOM to update with new data, you can do so withawait tick();
import {
onMount,
onDestroy,
beforeUpdate,
afterUpdate,
tick
} from 'svelte';
//stores.js
import { writable } from 'svelte/store';
export const count = writable(0);
// StoreReader.svelte -- subscribe method and returned unsubscribe value
<script>
import { onDestroy } from 'svelte';
import { count } from './stores.js';
const unsubscribe = count.subscribe(value => {
console.log("Value updated to: " + value)
});
onDestroy(unsubscribe);
</script>
// StoreWriter.svelte
<script>
import { count } from './stores.js';
count.update(prevValue => prevValue + 1);
count.set(0);
</script>
You can use auto-subsciptions by prepending $
to the store variable.
$
is a reserved character and no other variables can begin with $
in svelte.
// store.js
import { writable } from 'svelte/store';
export const count = writable(0);
// StoreReader.svelte
<script>
import { count } from './store.js';
</script>
<h1>The current count is {$count}</h1>
<button on:click={()=>$count++}>Increment count</button>
readable()
's first parameter is the initial value, the second parameter is the start
callback, which is called with the first subscriber to the value, and the starts
's return function end
is called whenever subscriber count goes back to 0,
// stores.js
import { readable } from 'svelte/store';
export const time = readable(new Date(), function start(set) {
const interval = setInterval(() => {
set(new Date());
}, 1000);
return function stop() {
clearInterval(interval);
};
});
// count.js
import { writable } from 'svelte/store';
const { subscribe, set, update } = writable(0);
export const count = {
subscribe,
increment: () => update(n => n + 1),
decrement: () => update(n => n - 1),
reset: () => set(0)
};
derived
at it's simplest form has a single dependency which should be the first parameter of the function, this dependency is then passed into the 2nd parameter - the callback function, which should return the new derived value.
derived(dep, $dep => $dep / 2 )
If there are multiple dependencies, you put them into an array and pass it as 1st parameter of derived
, the callback now passes an array of these dependencies as 1st parameter of the callback function.
derived([dep_a, dep_b], ([$dep_a, $dep_b]) => $dep_a + $dep_b);
And finally if called similarly to readable
, you can call the start
callback which passes the value setter as first prop, and you return end
just as with readable
. The difference however is that end
and start
are re-called again whenever the dependency changes.
// timeStore.js
import { readable, derived } from 'svelte/store';
const initialTime = new Date();
export const time = readable(initialTime, function start(set){
const interval = setInterval(() => set(new Date()), 1000);
return function stop() {
clearInterval(interval);
};
});
export const elapsed = derived( time, $time =>
Math.round( ($time - initialTime) / 1000)
);
Svelte will interpolate between numbers, dates, and identically-shaped arrays and objects (as long as they only contain numbers and dates or other valid arrays and objects). If you want to interpolate (for example) colour strings or transformation matrices, supply a custom interpolator.
There are further options you can specift with tweened
and spring
that this demo covers.
//LinearTween.svelte
<script>
import { tweened } from 'svelte/motion';
const progress = tweened(0);
</script>
//EasedTween.svelte
<script>
import { tweened } from 'svelte/motion';
import { cubicOut } from 'svelte/easing';
const progress = tweened(0, {
duration: 400,
easing: cubicOut
});
</script>
//BasicSpring.svelte
<script>
import { spring } from 'svelte/motion';
let value = spring(10);
</script>
//ConfiguredSpring.svelte
<script>
import { spring } from 'svelte/motion';
let coords = spring({ x: 50, y: 50 }, {
stiffness: 0.1,
damping: 0.25
});
let size = spring(10);
</script>
Blink in svelte with transitions. Main part is transition:fade
on DOM element.
<script>
import { onMount} from 'svelte';
import { fade } from 'svelte/transition';
let visible = true;
onMount( () => {
const interval = setInterval(() => visible = !visible, 1000 );
return () => clearInterval(interval)
})
</script>
{#if visible}
<p transition:fade> Fades in and out </p>
{/if}
You can also use fly
:
<script>
import { fly } from 'svelte/transitions';
</script>
<p transition:fly={{ y: 50, duration: 200}}> Flies in and out </p>
Or you can specify transition-in and out respectively:
<p in:fly={{ y: 200, duration: 2000 }} out:fade>
Flies in, fades out
</p>