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 transition
  • duration - length of transition
  • easing a p => t function (easing)
  • css a (t, u) => css function, where u === 1 - t
  • tick - 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>&amp#{emoji.codePointAt(0)}</td>
	</tr>
{/snippet}

and then you can call the snippet by using

{@render monkey()}