Runes
The “core” part of Svelte
Props
$props()Props rune - an object containing all of the properties passed down
State
$state(initial value)
State rune - sets a state with the initial value
Effect
$effect(func)
Defined custom “reactors” to runes
Effects can return a cleanup function.
Also can be used for “on component mount”
Bindable
$bindable('')Used to mark a component prop as “bindable”, meaning it can be used in a Bindings
Directives
A core feature of svelte is “directives” that you can pass into HTML elements, similar to the HTML properties
<element directive:func></element>
<element directive:func={"pass in a value to the function"}></element>Inline Logic Blocks
Conditionals
{#if count > 10}
// stuf to run in the if
{:else if count < 5}
// more stuff
{:else}
// fallback
{/if}Loops
{#each colors as color}
{/each}anything that can be Array.from()
You can add keys do them. Svelte is very fine grained and will only updated the variables that depend on the rune state, but nothing else. In order for it to update a WHOLE component, you’ll need to key them to make Svelte aware of it’s existence
{#each colors as color (color.id)}Async/await
Svelte even supports async await tasks
{#await promise}
// to execute while awaiting
{:then result}
// for the result
{:catch err}
// for error
{/await}Shorthand:
{#await promise then result}
{/await}
Key Blocks
{#key i}
// HTML
{/key}These will destroy and frecreate their contents when the inside is changed, simulating DOM add/remove events (useful for transitions!). The i refers to the fact that it’ll be destroyed when i is changed.
DOM events
Very much like html
<div onclick={handler}>
</div>
They can be inline as well thru arrow functions
Capturing: The inner handlers run first, then bubbles ‘up’. Capture (onkeydowncapture for example) works out in.
Bindings
<input bind:value={name}>
You can bind a variable to an element, so name updates based on form input, etc.
Svelte even does conversion for you!
This binding
You can bind to this (referring to a readonly-current element)
<canvas bind:this={canvas}></canvas>Component Bindings
First, mark a component prop as Bindable
Then, bind it using
<Component bind:name_of_component_prop={variable} />Use these sparingly! Hard to keep track
Styling
Svelte uses clsx
“
<button
class={["card", { flipped }]}
onclick={() => flipped = !flipped}
>You can also use the style: directive
<button
style:--bg-1="palegoldenrod"
>
Action Functions
Use directive
<div class="menu" use:action>
This is used for element-level lifecycle functions.
The action function should take in a node and return a cleanup function. It should be within an $effect()
The use directive can also take in parameters like so:
<div class="menu" use:action={() => ({ params })}>
In this case, we’re passing in a function. This is because the action function DOES NOT rerun, just the bit inside the effect (Runes)
Transitions
Transition Directive
Svelte has a lot of really easy transitions with the transition directive, like
<p transition:fade> </p>You can apply parameters to the functions (Directives)
In, out
Instead of the Transition Directive, you can have much more fine grained using in and out. In is for when the element gets rendered INTO the dom, out is when the element gets rendered OUT of the dom
Custom Transitions
The fade transition looks like this,
function fade(node, { delay = 0, duration = 400 }) {
const o = +getComputedStyle(node).opacity;
return {
delay,
duration,
css: (t) => `opacity: ${t * o}`
};
}The function takes in the node that it is being applied on, and a destructured object of parameters. It returns a transition object which have the following properties:
delay- delay before transitionduration- length of transitioneasinga p => t function (easing)cssa(t, u) => cssfunction, where u === 1 - ttick- a(t, u) => {...}function that has some effect on the node
Try to use css the function if possible, because Svelte simulates the transition and constructs a CSS animation.
You can also use javascript for animations, like a typewriter effect.
DOM Events
You can listen to dom events like onintrostart, onoutrostart, onintroend, onoutroend
Outro is the out: Directives, which occurs when the element is removed from DOM
Global Events
Usually in Svelte, transitions on elements are only applied when targeting that element (the direct HTML tag) is targeted specifically? For example
{#if showItems}
{#each items.slice(0, i) as item}
<div transition:slide>
{item}
</div>
{/each}
{/if}This would not apply the transition if showItems changes. Global plays when any block containing the transition is added or removed
Keyed Events
Key Blocks destroy and recreate their contents if the value changes Key Blocks. This is perfect for transitions that should be retriggered on value change
Svelte Motion
Oftentimes, a good way to communicate values being changed is through motion. Svelte ships a class called “tween” that allows you to add motion
import { Tween } from "svelte/motion";
let progress = $state(0);And then use .current property and a writeable target property
Another alternative to Tween is Spring.
Deferred Transitions
Svelte can “defer” animations that coordinate across multiple elements
<li
class={{ done: todo.done }}
in:receive={{ key: todo.id }}
out:send={{ key: todo.id }}
animate:flip={{ duration: 200}}
>So send, receive, are closures that mutate internal state. Once the element leaves, it will call the out and call the send function. Once the element enters, it calls receive. Then, svelte
Advanced State
Raw States - when react only tracks REASSIGNMENTS, not mutations. Good for data where no need for deep reactivity. When you don’t change individual properties, or need referential equality (?)
svelte/reactivity
Svelte ships with a bunch of reactive components that replace javascript defaults, like Map,Date, etc. They are said to have additional reactivity features. For example, SvelteDate automatically updates?
svelte/store
Svelte ships with a way to handle “global states”, avoid all that prop drilling, redux hell, etc. Svelte ships with a store.
import { writable } from "svelte/store";
count = writable(0)To reference the values of store, use the $
$count Snippets
A way to ‘reuse’ content in the same component.
For example:
{#snippet monkey()}
<tr>
<td>{emoji}</td>
<td>{description}</td>
<td>\u{emoji.charCodeAt(0).toString(16)}\u{emoji.charCodeAt(1).toString(16)}</td>
<td>&#{emoji.codePointAt(0)}</td>
</tr>
{/snippet}and then you can call the snippet by using
{@render monkey()}