Svelte 4: Zero To Mastery
Tags: svelte, javascript, typescript, frontend
Published: 2024-04-03 22:19:30

![Svelte logo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2qld71kagdydwscurldu.png)

<br/>

***

<br/>

## Table Of Contents <a href="#table-of-contents"></a>
1. [Preface](#preface)
2. [Introduction](#introduction)
3. [Use Cases](#use-cases)
4. [Benefits & Drawbacks](#benefits-drawbacks)
5. [Project Setup](#project-setup)
6. [Project Structure](#project-structure)
7. [Component Structure](#component-structure)
8. [State Management](#state-management)
9. [Props](#props)
10. [Data Binding](#data-binding)
11. [DOM Binding](#dom-binding)
12. [Reference Binding](#reference-binding)
13. [Reactivity](#reactivity)
14. [Reactivity Behavior](#reactivity-behavior)
15. [Templating](#templating)
16. [Keyed {#each} Block](#keyed-each-block)
17. [Events](#events)
18. [DOM Event Modifiers](#dom-event-modifiers)
19. [Component Dispatched Events](#component-dispatched-events)
20. [Component Lifecycle](#component-lifecycle)
21. [Stores](#stores)
22. [Custom Stores](#custom-stores)
23. [Slots](#slots)
24. [Context API](#context-api)
25. [Special Elements](#special-elements)
26. [Higher-order Components](#hoc)
27. [Module Context](#module-context)
28. [Transitions & Animations](#transitions-animations)
29. [Motion](#motion)
30. [Transition Application](#transition-application)
31. [Transition Events](#transition-events)
32. [Custom Transitions](#custom-transitions)
33. [Key Blocks](#key-blocks)
34. [Transition Modifiers](#transition-modifiers)
35. [Deferred Transitions](#deferred-transitions)
36. [Animate Directive](#animate-directive)
37. [Actions](#actions)
38. [CSS Preprocessor Integration](#css-preprocessors)
39. [Tailwind CSS Integration](#tailwind-integration)
40. [Lazy Loading](#lazy-loading)
41. [Consuming APIs](#consuming-apis)
42. [Forms & Validation](#forms-validation)
43. [Documenting](#documenting)
44. [Debugging](#debugging)
45. [Testing](#testing)
46. [Routing](#routing)
47. [TypeScript Limitations](#ts-limitations)
48. [Deploying](#deploying)
49. [Runes](#runes)
50. [Conclusion](#conclusion)

<br/>

***

<br/>

## Preface <a href="#preface"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

This tutorial provides a comprehensive overview of Svelte 4, detailing all its aspects. Basic knowledge of HTML, CSS, and JavaScript is necessary to follow this tutorial effectively. Moreover, having familiarity with frontend frameworks would be beneficial for a better understanding of the concepts presented. 

**Note that** this tutorial does not include coverage of SvelteKit.

> All the examples used in this post can be found in this [GitHub repository](https://github.com/admaletsas/svelte-tutorial)

<br/>

***

<br/>

## Introduction <a href="#introduction"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Svelte is a JavaScript framework used for building user interfaces. What sets Svelte apart from other frameworks is that it compiles your code at build time rather than running it in the browser. This means that the resulting code is highly optimized and efficient, resulting in faster load times and better performance for your applications. 

During development, Svelte code is written using its component-based syntax and reactive programming model. Svelte analyzes the code and compiles it into optimized JavaScript code. When the application is ready for deployment, the building process starts.  A bundle that can be served to the browser is generated. The bundle typically includes the optimized JavaScript, CSS, and other necessary assets. Once the build is complete, the generated bundle is deployed to a web server. When a user visits your site, their browser downloads and executes the compiled JavaScript code. 

It is important to highlight that Svelte provides official support for TypeScript and includes built-in animation and transition capabilities, eliminating the need for external libraries.

Additionally, as you explore Svelte, you may encounter SvelteKit, the official framework built on top of Svelte. While Svelte serves as a standalone framework for UI development, SvelteKit expands its capabilities by offering additional features and tools.

<br/>

***

<br/>

## Use Cases <a href="#use-cases"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Svelte excels in single-page applications (SPAs), providing smooth user experiences. Its reactive nature enables interactive UI components responsive to user actions. It is also well-suited for data visualization, rapid prototyping, and progressive web applications due to its simplicity, quick setup, and small bundle size, ensuring fast loading times and offline capabilities.

> A **single-page application (SPA)** is a type of application where a single HTML file is loaded for all server requests.

<br/>

***

<br/>

## Benefits & Drawbacks <a name="benefits-drawbacks" href="#benefits-drawbacks"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Some key benefits of using Svelte include:
- **Component-based Architecture:** Svelte promotes a component-based architecture, allowing you to build reusable, self-contained and modular components. This helps in organizing your codebase and enables easier collaboration among developers. Additionally, it encourages a clear separation of concerns, making your code more maintainable and scalable.

- **Performance:** Svelte takes a different approach than virtual DOM-based frameworks. It is a compiler that analyzes your code during build time and generates optimized JavaScript code that directly manipulates the DOM. This means that updates and changes are handled at compile time, resulting in faster and more efficient rendering at runtime. By eliminating the need for a virtual DOM, Svelte can offer improved runtime performance and reduced overhead.

- **Reactivity:** Svelte provides a built-in store system that allows you to manage and update the application's state in a reactive manner. With stores, you can define and subscribe to reactive data, and any changes to that data will automatically trigger updates in the UI. This makes it easier to keep your UI synchronized with the underlying data and ensures that it reflects the latest state of the application.

- **Minimalism:** Minimalism refers to the design philosophy of keeping things simple and concise. Svelte follows this principle by providing a syntax that is designed to be concise and readable. With Svelte, the same functionality can be achieved with less code compared to other frameworks, which can lead to improved readability and a reduced learning curve.

- **Framework Size:** Svelte itself is lightweight, which means it does not come bundled with a lot of additional dependencies. This can make your development process simpler by reducing the project complexity. By keeping the core framework lightweight, it gives you more control and allows you to make informed decisions about which additional tools or libraries to include. This flexibility lets you choose only the specific features you need, rather than dealing with a potentially bloated ecosystem.

- **Bundle Size:** Svelte compiles your code during the build process, resulting in highly optimized JavaScript code and smaller bundle sizes compared to other frameworks. Smaller bundle sizes lead to faster load times, as there is less data to transfer over the network, and improved performance, as the browser can parse and execute the code more quickly.

- **Compatibility:** Svelte is compatible with numerous JavaScript/TypeScript libraries and tools, aligning with the established standards of the JavaScript/TypeScript ecosystem.

- **Accessibility Checks:** Although Svelte does not include built-in accessibility checks, it does offer warnings during compile time if you create inaccessible markup.

While Svelte has many benefits, like any framework, it also has some potential drawbacks:
- **Small(er) Community & Ecosystem:** The Svelte ecosystem is not as extensive as others. While Svelte may not have as large of an ecosystem as some of the more established frameworks, it has been steadily growing in popularity. There are several third-party libraries and tools specifically built for Svelte, such as Svelte Material UI, Svelte Charts, and Svelte Testing Library, among others. These libraries provide additional functionality and convenience for developing Svelte applications. 

- **Developer Experience (DX):** Svelte introduces unique concepts and syntax that may feel different from other frameworks. While Svelte utilizes familiar HTML, CSS, and JavaScript/TypeScript, it has its own way of constructing UIs. Instead of relying on a virtual DOM or manual state management, Svelte introduces reactivity at a language level. This reactive approach can be a paradigm shift for developers. Moreover, component composition is achieved using slots and props, rather than relying on a parent-child relationship. Additionally, it takes a compile-time approach, where components are compiled into efficient JavaScript code during the building process. This differs from frameworks like React, which perform updates at runtime.

- **No Older Browser Support:** Svelte utilizes modern features like reactive updates and JavaScript modules, which offer efficient and dynamic updates to UI. However, it is important to note that not all browsers fully support these modern features. Older browsers may have limited or no support for them. While Svelte itself does not have built-in support for older browsers, Babel can be utilized in the build process to ensure compatibility across a wider range of browsers. Babel is a JavaScript compiler that can transpile modern code into a format that older browsers can interpret. By using Babel with Svelte, you can transform your code into a compatible format, allowing you to leverage Svelte's modern features while still supporting older browsers. Additionally, if you choose to use Vite to build your Svelte code, you will not need to worry about additional configuration for Babel. Vite uses Babel under the hood to handle the transpilation process automatically.

- **Tooling:** Svelte lacks an official CLI tool for project scaffolding, unlike other frameworks. Nevertheless, community-driven solutions like degit enable the quick setup of a new Svelte project with a basic folder structure. On the debugging and testing front, Svelte provides a dev mode with useful error messages and warnings during development. Furthermore, there are dedicated testing frameworks such as Svelte Testing Library tailored for unit testing Svelte components.

<br/>

***

<br/>

## Project Setup <a href="#project-setup"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

To create a Svelte project there are 2 main methods.

The first method involves using degit, a tool for cloning Git repositories. 
After installing degit via `npm install degit`, you can run `npx degit sveltejs/template my-app` to create a new Svelte project named **my-app**. This command downloads the contents of the Svelte project template from the GitHub repository called **sveltejs/template**. If you prefer to use TypeScript, you can specify the TypeScript branch with `--branch typescript`. 

After creating the project, navigate to the folder **my-app** and run `npm install` to install dependencies, followed by `npm run dev` to start the development server. If you are using TypeScript, run `node scripts/setupTypescript.js`, inside **my-app** folder, before installing dependencies. You can replace **my-app** with your desired project name. 

The second method, which is considered the modern approach, involves using npm to create a Svelte project with Vite, a modern build tool for web development. By executing `npm create vite@latest`, you can initialize a new project with **Vite**, providing a streamlined setup process with built-in support for Svelte and modern build features like fast development server and optimized production builds. With Vite, you can choose between JavaScript and TypeScript when creating your Svelte project, offering flexibility to tailor the project setup to your preferences. This command fetches the latest version of Vite from the npm registry and guides you through configuration options.

Note that both commands create a basic Svelte project without SvelteKit. After setting up your project, you can run `npm run dev` to start the development server.

```console
npm install degit
npx degit sveltejs/template my-app
cd my-app
npm install
npm run dev
```
*Create JavaScript project with degit*

***

```console
npm install degit
npx degit sveltejs/template my-app --branch typescript
cd my-app
node scripts/setupTypescript.js
npm install
npm run dev
```
*Create TypeScript project with degit*

***

```console
npm create vite@latest
cd my-app
npm install
npm run dev
```
*Create JavaScript/TypeScript project with Vite*

<br/>

***

<br/>

## Project Structure <a href="#project-structure"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

In a Svelte project, the **src** folder typically includes 2 key files, `main.js`, or `main.ts` for TypeScript, and `App.svelte`.
 
The `main.js` or `main.ts` file acts as the entry point for the application, responsible for configuring and initializing Svelte components. It manages tasks like mounting the root component onto the DOM and handling application-level functionality.

On the other hand, the `App.svelte` file functions as the primary component that lays the groundwork for the application's UI. It defines the overall layout and structure, importing and rendering other components as necessary. Each Svelte component has its own scoped CSS styles defined within the component file. Additionally, Svelte projects often include a file for application-wide styles.
 
For projects created with degit, this file can be found under `public/global.css`, while for Vite projects, it is typically located under `src/app.css`. 

Svelte offers flexibility in naming conventions and file structure, allowing developers to organize their code according to the specific requirements of their project.

<br/>

***

<br/>

## Component Structure <a href="#component-structure"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

A component is a reusable and modular building block that encapsulates a part of the UI. Components can range from simple elements like buttons or input fields to more complex elements like navigation bars or modals. They help in organizing the UI into smaller, manageable parts, promoting code reusability and maintainability. Components have their own structure, styling, and behavior, making it easier to develop and maintain large-scale web applications. In Svelte, components are defined in `.svelte` files. These files contain 3 main sections: **script**, **markup**, and **style**. 

The **script section** is where you write your JavaScript/TypeScript code. Here, you can define variables, create functions, import modules, or even other components, and handle component logic. When importing other components, any name beginning with a capital letter is valid. It is recommended to use Pascal casing for the names for consistency and readability. Note that for a TypeScript project, you can specify the language by adding a `lang='ts'` property to the script section.

The **style section** is where you define the CSS styles for the component. You can write regular CSS rules to style your component's elements. It is important to note that in Svelte, these sections are tightly integrated. This means that you can reference variables and functions defined in the script section directly in the markup and style sections. 

Additionally, it is worth mentioning that these sections can be written in any order or even omitted if they are not needed for a particular component. Everything that is not within the style or script sections is considered markup. The **markup section** contains the HTML markup for your component, where you can use regular HTML tags and Svelte-specific syntax to define the structure and content of your component. By combining HTML, CSS, and JavaScript/TypeScript in one file, Svelte simplifies development and encourages component reusability. 

```svelte
<script>
    let name = 'World';
</script>

<p>Hello, {name}</p>

<style>
    p {
        font-weight: 600;
    }
</style>
``` 
*A simple JavaScript component example featuring all sections*

```svelte
<script lang='ts'>
    let name: String;
</script>

<p>Hello, {name || 'World'}</p>

<style>
    p {
        font-weight: 600;
    }
</style>
``` 
*A simple TypeScript component example featuring all sections*

<br/>

***

<br/>

## State Management <a href="#state-management"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

**State** refers to the data that represents the current condition or snapshot of an application at any given moment. It includes information such as user inputs, fetched data, selected options, and any other relevant data that affects the behavior and appearance of the application. 

**State management** involves techniques, patterns, and tools that allow developers to handle and update this state in a predictable and efficient manner. Svelte utilizes stores as reactive data containers that facilitate state sharing and observation within components. By defining reactive variables and storing values in these stores, you can ensure automatic state updates when changes occur. This centralized method streamlines state management and enhances code organization.

Further information about **stores** will be provided later.

<br/>

***

<br/>

## Props <a href="#props"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

In component-based frameworks like Svelte, props serve as a fundamental mechanism for establishing communication between different components. They allow for the passing of data from parent components to child components, enabling the creation of modular and reusable pieces of code. 

Child components are components that are integrated into a parent component's markup. The parent component includes these child components, which are designed to work together within the parent's structure. This approach promotes a clear separation of concerns, with each component being responsible for a specific part of the UI or functionality.

To define props in a component, the `export` keyword is utilized for each prop declaration in the script section. Props can either have default values or be left undefined. By passing values to the child component's props from the parent, specific data or behavior can be provided to customize the child component's functionality. 

The child component can access and utilize these prop values in its markup or script sections. It is worth noting that any modifications made to the props within the child component solely impact the local copy and do not change the original values passed by the parent.

```svelte
<script>
    export let username, email;
    export let group = 'Users';
    export let status;

    /**
     * $$props is a special object that contains 
     *   all the props passed to a component as key-value pairs.
     * $$restProps is used to access any additional props 
     *   passed that are not explicitly defined in the 
     *   component to its child.
     * $$props include $$restProps, but not vice versa.
     */
    if (Object.entries($$restProps).length) {
        console.log('props:', $$props);
        console.log('restProps:', $$restProps);
    }
</script>

<div class='container'>
    <p>Username: {username}</p>
    <p>Email: {email}</p>
    <p>Group: {group}</p>
    <p>Status: {status}</p>
</div>

<style>
    .container {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: flex-start;
        margin-left: 1em;
        padding: 1em;
        border: 2px solid;
    }
</style>
```
*User.svelte*

***

```svelte
<script>
    import User from './User.svelte';

    const userEmail = 'user2@mail.com';
    const status = 'Online';
    const user = { 
        username: 'User 4',
        email: 'user4@mail.com',
        status
    };
</script>

<div class='container'>
    <!-- Passing all props -->
    <User 
        username='User 1'
        email='user1@mail.com'
        group='Super Users'
        status='Offline'
    />

    <!-- 
        Passing all props except for the "group" prop, 
          which has a default value.
        "email" prop receives the value of variable userEmail.
        "status" prop receives the value of variable status.
    -->
    <User 
        username='User 2'
        email={userEmail}
        status={status}
    />

    <!-- "{status}" is shorthand for "status={status}" -->
    <User 
        username='User 3'
        email='user3@mail.com'
        {status}
    />

    <!-- Spread props -->
    <User {...user} />

    <!-- 
        User with extra props.
        The "prop=value" syntax passes values as a string.
        When the value is enclosed in {value}, 
            it will retain its original type. 
    -->
    <User
        {...user}
        arr={[1, 2, 3]}
        obj={{ a: 1, b: 2, c: 3 }}
        bool={true}
        num={123}
    />
</div>

<style>
    .container {
        display: flex;
        justify-content: center;
        align-items: center;
        flex-wrap: wrap;
        gap: 1em;
    }
</style>
```
*Profile.svelte*

> This example illustrates how props are passed between a parent component named **Profile** and a child component called **User**.

> Within the User Component, props for username, email, group, and status are declared, with the group prop having a default value of "Users" for fallback.

> The Profile component demonstrates prop passing methods such as direct assignment, variable utilization, and prop spreading via the spread operator.

> It is important to note the difference between the `prop=value` syntax, which passes values as strings, and enclosing values in `{value}` to maintain their original data type.

> Additionally, the User component makes use of the special variables `$$props` and `$$restProps`. The `$$props` variable holds all the passed props, while `$$restProps` allows access to any extra, undeclared props. If `$$restProps` are present, these values are logged into the console.

<br/>

***

<br/>

# Data Binding  <a href="#data-binding"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Parent components serve as higher-level components responsible for managing the state and behavior of one or more child components. They transmit data to child components via props, which are variables or values accessible to and utilized by the child components. In contrast, child components function as lower-level components that receive data from their parent components through props to render content or execute specific tasks. Child components can trigger events or call functions in their parent components to communicate changes and update shared data. There are 2 approaches for updating data between components, uni-directional and bi-directional binding. 

**Uni-directional** binding, or **one-way** binding, enables data to flow solely from a parent component to a child component. Changes in the parent component are reflected in the child component, maintaining a structured data flow. 

Conversely, **bi-directional** binding, or **two-way** binding, facilitates data exchange between a parent and child component bi-directionally. Modifications in either component trigger updates in both, ensuring synchronized data. This is beneficial for scenarios where immediate updates in one component should be mirrored in the other.

When a parent component passes a value through props to a child component, and the child component calls a parent component function with that value, it creates a scenario where the 2 values reference the same data. This can create a **form of two-way binding** because changes in one component affect the other. If the data passed between components is different or unrelated, it establishes **2 distinct one-way bindings**, one from the parent component to the child component and another from the child component to the parent component. Each component operates independently in this situation, with changes in one component not directly impacting the other unless explicitly programmed to do so.

It is important to note that when a parent component passes a function through props to a child component, and the child component uses this function to send data back to the parent component, it adheres to **uni-directional** data flow principles. 

Svelte promotes uni-directional binding, which improves clarity and simplifies application debugging. However, it also provides features like **event handling** or the `bind:` directive to facilitate bi-directional binding when necessary.

```svelte
<script>
    export let description, count;
    export let updateValue = null;

    function increment() {
        count++;
        typeof updateValue === 'function' && updateValue(count);
    }
</script>

<div>
    <p>Child with {description}</p>
    <p>Count: {count}</p>
    <button on:click={increment}>Increment</button>
</div>

<style>
    div {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
    }
</style>
```
*Child.svelte*

***

```svelte
<script>
    import Child from './Child.svelte';
    
    let count = 0;
</script>

<div class='container'>
    <div class='parent'>
        <p>Parent</p>
        <p>Count: {count}</p>
        <button on:click={() => count++}>Increment</button>
    </div>

    <!-- "{count}" is shorthand for "count={count}" -->
    <Child 
        description='one-way binding' 
        {count} 
    />

    <!-- "bind:count" is shorthand for "bind:count={count}" -->
    <Child 
        description='two-way binding' 
        bind:count 
    />
    
    <Child 
        description='2 one-way bindings resulting in a two-way binding' 
        {count}
        updateValue={cnt => count = cnt}
    />
</div>

<style>
    .container {
        display: flex;
        flex-wrap: wrap;
        gap: 1em;
        justify-content: center;
        align-items: center;
    }

    /** 
     * :global() targets global CSS styles, applying them 
     *   universally across components 
     */
    .container :global(div) {
        padding: 1em;
        margin: 1em;
    }

    .container :global(div):not(.parent) {
        border: 2px solid red;
    }

    .parent {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        border: 2px solid green;
    }
</style>
```
*Parent.svelte*

> In the example above, the **Parent** component initializes a **variable** named `count` with an initial value of `0`. This `count` variable is then passed down to the Child components as a **prop** called `count`, establishing a one-way binding. Within the Parent component, there are 3 instances of the Child component. 

> The **first Child** component receives the `count` **prop**, showcasing a one-way binding. This means that any modifications made to the `count` **variable** in the Parent component will be reflected in the first Child component. However, changes made within the first Child component will not impact the Parent component.

> In contrast, the **second Child** component utilizes the `bind:` directive in the `count` **prop**, creating a two-way binding. This two-way binding allows changes made to the `count` **variable** within the second Child component to affect the Parent component as well.

> The **third Child** component receives both the `count` **prop** and an `updateValue` **prop**, which is a function intended to update the `count` **variable** in the Parent component. This setup results in a situation where the values in both components reference the same data, leading to a form of two-way binding where modifications in one component will influence the other.

> If the data passed between the components were distinct or unrelated, it would demonstrate 2 separate one-way bindings, one from the Parent to the Child and another from the Child to the Parent. In such a scenario, each component would function independently, with changes in one component not directly impacting the other unless specifically programmed to do so.

> An important aspect to consider is that updating the `count` **variable** in the Parent component will lead to a re-rendering of all Child components that receive the `count` **prop**. Consequently, Child components that are two-way bound will update all other Child components.

<br/>

***

<br/>

## DOM Binding  <a href="#dom-binding"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

The `bind:` directive can be used to establish a two-way binding between DOM elements and your component's data, ensuring that any changes made in the DOM elements automatically update the component's data, and vice versa. Additionally, utilizing the `bind:group` feature allows you to group radio or checkbox inputs related to the same value, with radio inputs offering exclusive selection and checkbox inputs enabling multiple selections.

```svelte
<script>
    let value = 'Default value';
    let numValue, rangeValue;
    let checked = true;
    let selected;
    let selectedOptions = [];
    let checkedOptions = [];
    let selectedRadioOption;
</script>

<div class='container'>
    <div class='item'>
        <!-- Binding between attributes and component properties -->
        <p>Text: {value}</p>
        <!-- "bind:value" is shorthand for "bind:value={value}" -->
        <input bind:value />
        <textarea bind:value></textarea>
    </div>

    <div class='item'>
        <!-- 
            Svelte automatically handles 
                the conversion of data types 
        -->
        <p>
            {numValue || 0} + 
            {rangeValue || 'Drag Slider'} = 
            {(numValue + rangeValue) || '---'}
        </p>
        <input type='number' bind:value={numValue} />
        <input type='range' bind:value={rangeValue} />
    </div>

    <div class='item'>
        <label>
            <!-- 
                "bind:checked" is shorthand for 
                    "bind:checked={checked}" 
            -->
            <input type='checkbox' bind:checked />
            Toggle Button
        </label>
        <button disabled={!checked}>Button</button>
    </div>

    <div class='item'>
        <p>Selected: {selected}</p>
        <select bind:value={selected}>
            <option value='A'>A</option>
            <option value='B'>B</option>
            <option value='C'>C</option>
        </select>
    </div>

    <div class='item'>
        <p>Selected: {selectedOptions.join(', ')}</p>
        <select multiple bind:value={selectedOptions}>
            <option value='A'>A</option>
            <option value='B'>B</option>
            <option value='C'>C</option>
        </select>
    </div>

    <!-- 
        Bind a group of checkbox inputs, 
        allowing multiple selections 
    -->
    <div class='item'>
        <p>Checked: {checkedOptions.join(', ')}</p>
        <label>
            <input 
                type='checkbox' 
                value='A' 
                bind:group={checkedOptions} 
            />
            A
        </label>
        <label>
            <input 
                type='checkbox' 
                value='B' 
                bind:group={checkedOptions} 
            />
            B
        </label>
        <label>
            <input 
                type='checkbox' 
                value='C' 
                bind:group={checkedOptions} 
            />
            C
        </label>
    </div>

    <!-- 
        Bind a group of radio buttons, 
            allowing only one selection at a time 
    -->
    <div class='item'>
        <p>Checked: {selectedRadioOption || '---'}</p>
        <label>
            <input 
                type='radio' 
                value='A' 
                bind:group={selectedRadioOption} 
            />
            A
        </label>
        <label>
            <input 
                type='radio' 
                value='B' 
                bind:group={selectedRadioOption} 
            />
            B
        </label>
        <label>
            <input 
                type='radio' 
                value='C' 
                bind:group={selectedRadioOption} 
            />
            C
        </label>
    </div>
</div>

<style>
    div {
        display: flex;
        flex-wrap: wrap;
        gap: 1em;
        justify-content: center;
        align-items: center;
    }

    .container {
        flex-direction: row;
        width: 80%;
    }

    .item {
        flex-direction: column;
        padding: 1em;
        border: 2px solid green;
    }
</style>
```
*DOM.svelte*

> The code example above demonstrates data binding implementation with various DOM elements. It initially binds an input field and a textarea to a variable named `value`, ensuring changes in one element reflect instantly in the other. The `value` variable's content is dynamically displayed in real-time, showcasing the seamless connection between these elements.

> Additionally, it binds a number input and a range input to variables `numValue` and `rangeValue` respectively, and calculates their sum. Svelte automatically handles string to number conversion.

> Moreover, a checkbox is bound to a variable `checked`, enabling the seamless toggling of a button based on the checkbox's status. This showcases how data binding can create interactive UIs that respond to user actions.

> A select element is bound to the variable `selected`, showing the currently selected option.
 
> A multi-select element is bound to an array `selectedOptions`, displaying all selected choices.
 
> Furthermore, the code binds a group of checkboxes to an array `checkedOptions`, displaying **all currently checked** checkboxes.

> Lastly, a group of radio buttons is bound to the variable `selectedRadioOption`, allowing only one selection at a time. This enforces **exclusivity** among radio options.

<br/>

***

<br/>

## Reference Binding <a href="#reference-binding"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Reference binding, facilitated by `bind:this`, empowers you to connect DOM elements and component references to variables, providing direct access to their properties and methods. This capability simplifies interaction and manipulation of components and DOM elements.

```svelte
<script>
    export let content = '';

    export function clear() {
        content = '';
    }
</script>

<p>{content}</p>
```
*Paragraph.svelte*

***

```svelte
<script>
    import Paragraph from './Paragraph.svelte';
    let content;
    let p, div;
</script>

<div class='container'>
    <div class='item'>
        <textarea bind:value={content}></textarea>
        <button on:click={p.clear}>Clear Paragraph</button>
        
        <!-- Bind to component reference -->
        <Paragraph bind:content bind:this={p}></Paragraph>
    </div>

    <!-- Bind to DOM element -->
    <div class='item' bind:this={div}>
        <button on:click={() => div.style.backgroundColor='red'}>
            Change Color
        </button>
    </div>
</div>

<style>
    div {
        display: flex;
        flex-wrap: wrap;
        gap: 1em;
        justify-content: center;
        align-items: center;
    }

    .container {
        flex-direction: row;
        width: 80%;
    }

    .item {
        flex-direction: column;
        padding: 1em;
        border: 2px solid green;
    }
</style>
```
*ReferenceBinding.svelte*

> The code example above demonstrates 2 distinct uses of the `this` binding. Initially, it binds a component reference by associating the **Paragraph** component instance with the variable `p`. This connection grants direct access to the properties and methods of the Paragraph component through the `p` variable. 

> As a result, clicking the **Clear Paragraph** button triggers the invocation of the **clear** method of the Paragraph component. 

> Note that the `bind:content` binding is used to populate the Paragraph component with the content provided in the textarea.

> Furthermore, the `this` binding is employed to bind the div DOM element to the variable `div`. This linkage enables direct manipulation of the DOM element using the `div` variable. Consequently, clicking the button within this div alters the background color of the div to red.

<br/>

***

<br/>

## Reactivity <a href="#reactivity"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Reactivity is a core feature of the Svelte framework, ensuring that the DOM reflects changes in the application's state in real-time. This synchronization keeps the UI current with data modifications triggered by user interactions or other events.  Svelte's reactivity system functions by tracking dependencies between variables and the UI elements that rely on them. When a variable changes, Svelte smartly updates only the necessary parts of the DOM to show the new value, avoiding the need to re-render the entire component. This targeted updating approach reduces unnecessary computations, boosts performance, and provides a smooth user experience.  Svelte employs various techniques for achieving reactivity, including reactive assignments, reactive statements, and reactive declarations.
 
**Reactive assignments** trigger automatic updates in the DOM when a variable in the markup is reassigned. 

On the other hand, **reactive declarations** involve **prefixing a variable or expression** with `$:` to establish a subscription to the variable. This subscription ensures that any modifications to the variable lead to a re-rendering of the component, keeping the UI current. 

It is important to differentiate between reactive assignments, which handle variable reassignment in the markup, and reactive declarations, which are variables that update when the corresponding right-hand side variable changes. 

**Reactive statements**, identified by `$:` **preceding a code block**, subscribe to a variable within the block, leading to the execution of the code when that variable changes. 

While **reactive declarations** and **reactive statements** are sometimes used interchangeably, it is essential to understand their unique purposes. Reactive declarations create variables, while reactive statements execute code blocks based on variable changes.

It is worth noting that Svelte's reactive syntax resembles JavaScript labels in the `label: expression` format but introduces additional concepts beyond standard JavaScript. 

```svelte
<script>
    let message = 'Initial value';
    let counter = 0;

    // Reactive declaration
    $: doubled = 2*counter + 1;
    
    // Single reactive statement
    $: console.log('Counter is', counter);

    // Multiple reactive statements
    $: {
        if (counter > 10)
            message = 'More than 10';
        else if (counter > 5)
            message = 'More than 5';
        else
            message = 'Less than or equal to 5';
    }
</script>

<p>{message}</p>
<p>Counter: {counter}</p>
<p>Doubled + 1: {doubled}</p>

<!-- 
    Reactive assignment.
    "counter++" translates to "counter = counter + 1" under the hood. 
-->
<button on:click={() => counter++}>Increment</button>
```
*Reactivity.svelte*

> The code above demonstrates the concept of reactivity in Svelte using different mechanisms. It initializes a `counter` variable to `0` and a `message` variable to `Initial value`.
 
> The line `$: doubled = 2*counter + 1;` sets up a **reactive declaration**, ensuring that whenever the `counter` variable changes, `doubled` will update to twice the value of `counter` plus one.

> The line `$: console.log('Counter is', counter);` represents a single reactive statement, which logs the current value of `counter` to the console whenever `counter` changes.
 
> Within the `$: {}` block, there are multiple reactive statements that determine the value of the `message` variable based on the current `counter` value. The `message` variable updates reactively based on the conditions specified in the block.

> Upon initialization, the reactive declaration and reactive statements are triggered. 

> In the markup, the values of `message`, `counter`, and `doubled` are displayed and automatically update when the corresponding variables change. Initially, `message` displays **Less than or equal to 5**, `counter` shows **0**, and `doubled` is **1** due to the triggering of reactivity. Additionally, "Counter is 0" will be logged to the console. The button **Increment** increases the "counter" variable by 1 when clicked, triggering the reactive updates.

<br/>

***

<br/>

## Reactivity Behavior <a href="#reactivity-behavior"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

The reactivity system in Svelte is designed to automatically handle most common scenarios. However, there are specific cases where reactivity may not trigger as expected. One such instance is when modifying arrays using methods like **push** and **splice**. To ensure reactivity in such cases, you can **add an assignment** to the array after modification, or use the **spread operator** to create a new array instead of modifying the existing one.

Similarly, when modifying nested properties of an object through a reference object, reactivity may not be triggered automatically. To address this, you can ensure reactivity by **reassigning** the object variable.

In cases where functions in the markup contain variables that have been changed, Svelte may not detect these changes and trigger a re-render. 

Additionally, if a function parameter shares the same name as a top-level variable, the parameter may **shadow** the variable, leading to unexpected behavior. To maintain proper reactivity, it is recommended to use distinct names for variables and parameters.

```svelte
<script>
    let stack = [0, 1, 2];
    let n = 3;
</script>

<p>n: {n}</p>
<p>Stack top: {stack.at(-1)}</p>

<button on:click={() => stack.push(++n)}>
    Non-working Push
</button>

<button on:click={() => stack = [...stack, ++n]}>
    Working Push
</button>
```
*Array.svelte*

> In the code above, the `stack` variable is initialized as an array `[0, 1, 2]`, and `n` is set to `3`. The current value of `n`, representing the next value to be added to the stack, is displayed, along with the top element of the stack. Two buttons, **Non-working Push** and **Working Push** are present.

> The **Non-working Push** button pushes the incremented value of `n` into the `stack` array but fails to update the displayed stack top. In contrast, the **Working Push** button correctly updates the UI by adding the incremented `n` value to a new array created using the **spread** operator.

> The issue with the **Non-working Push** button arises from directly mutating the original stack array using **push**, which does not trigger Svelte's reactivity system to update the UI. Conversely, the **Working Push** button creates a new array by spreading the original stack elements and adding the incremented `n` value. This method correctly updates the stack array, leveraging Svelte's reactivity based on assignment to reflect changes in the UI.

***

```svelte
<script>
    const user = {
        location: {
            country: 'France'
        } 
    };

    let nonWorkingLocation = user.location;
    let workingLocation = user.location;

    let value;

    function nonWorkingSetCountry(country) {
        user.location.country = country;
    }

    function workingSetCountry(country) {
        user.location.country = country;
        workingLocation = user.location;
    }
</script>

<p>{user.location.country}</p>
<p>{nonWorkingLocation.country}</p>
<p>{workingLocation.country}</p>

<input bind:value />

<button on:click={() => nonWorkingSetCountry(value)}>
    Non-working Set Country
</button>

<button on:click={() => workingSetCountry(value)}>
    Working Set Country
</button>
```
*Object.svelte*

> In the code above, the `user` object contains a nested `location` object with a `country` property set to **France**. Two variables, `nonWorkingLocation` and `workingLocation`, are initialized to reference the `user.location` object. A `value` variable is declared to store the input value. 

> There are 2 functions, `nonWorkingSetCountry`, which updates the `user.location.country` directly with the input country, and `workingSetCountry`, which updates the `user.location.country` with the input country and assigns the updated `user.location` to `workingLocation`.
 
> In the markup, the **country** of the `user.location` object, `nonWorkingLocation`, and `workingLocation` are displayed. An input field is provided for entering a new country value. Two buttons, **Non-working Set Country** and **Working Set Country**, trigger the respective functions to update the country value in the `user.location` object. The difference between the **Non-working Set Country** and **Working Set Country** functions lies in how they handle updating the `workingLocation` variable.
 
The **Non-working Set Country** function directly modifies the `user.location.country`, while the **Working Set Country** function updates both `user.location.country` and then **reassigns** `workingLocation` to reference the updated `user.location` object. This distinction affects reactivity. **Updating the reference** of `workingLocation` **triggers** reactivity, ensuring that changes are reflected in the UI, while **not reassigning** the reference object **does not** trigger reactivity.

***

```svelte
<script>
    let stack = [0, 1, 2];
    let n = 3;

    let topVariable = stack.at(-1);

    $: topReactDecl = stack.at(-1);

    function topFn() {
        return stack.at(-1);
    }
</script>

<p>n: {n}</p>
<p>Stack top: {stack.at(-1)}</p>
<p>Stack top (Variable): {topVariable}</p>
<p>Stack top (Reactive Declaration): {topReactDecl}</p>
<p>Stack top (Function): {topFn()}</p>

<button on:click={() => stack = [...stack, ++n]}>
    Push
</button>
```
*Function.svelte*

> In this code example, there is an array named `stack` initialized as `[0, 1, 2]`, and the variable `n` is set to `3`. The current value of `n` indicates the next value to be added to the stack. 

>A variable `topVariable` is defined to reference the top element of the stack using `stack.at(-1)`. 

> There is also a reactive declaration named `topReactDecl`, which tracks the value of the top element of the stack with the expression `$: topReactDecl = stack.at(-1)`. 

> Additionally, a function named `topFn` is created to return the value of the top element of the stack by using `stack.at(-1)`.

> Within the markup, the values of `n` and the various methods to access the top of the stack are displayed. A button labeled **Push** is included to trigger an event that adds the incremented value of `n` to the `stack` array by creating a new array with the **spread** operator. This click event triggers reactivity for all approaches except for `topVariable` and `topFn()`.

> Reactivity is not triggered for `topVariable` and `topFn()` because they are not reactive in nature. The `topVariable` variable simply references the top element of the stack using `stack.at(-1)` when it is declared. It does not have any mechanism to automatically update its value when the stack changes. The `topFn()` function returns the value of the top element of the stack when called. Similar to `topVariable`, it does not have built-in reactivity to update its value when the stack changes.

> On the other hand, `topReactDecl` is a reactive declaration that explicitly tracks the value of the top element of the stack using the `$:` syntax. This means that whenever the stack changes, `topReactDecl` will automatically update its value to reflect the new top element of the stack.

> In the case of `{stack.at(-1)}`, the displayed value is dependent on the top element of the stack. As a result, whenever the top element of the stack changes, Svelte recognizes this dependency and updates the displayed value accordingly.

***

```svelte
<script>
    function nonWorkingLogout(user) {
        user = { ...user, status: 'offline' };
    }

    function workingLogout(loggedUser) {
        user = { ...loggedUser, status: 'offline' };
    }

    let user = {
        username: 'user',
        status: 'online'
    };
</script>

<p>{user.username} is {user.status}</p>

<button on:click={() => nonWorkingLogout(user)}>
    Non-working Logout
</button>

<button on:click={() => workingLogout(user)}>
    Working Logout
</button>
```
*Shadowing.svelte*

> In the code example above, there is a `user` object with properties `username` set to `user` and `status` set to `online`. Two functions, `nonWorkingLogout` and `workingLogout`, are defined.

> In the **nonWorkingLogout** function, the parameter is named **user**. Inside the function, a new object is created by **spreading** the properties of the user parameter and adding a new key-value pair to change the status to **offline**. However, due to variable shadowing, the `user` variable within the function is **local** and does not affect the **outer** `user` variable defined outside the function.

> On the other hand, in the **workingLogout** function, the parameter is named **loggedUser**. The object is updated similarly to the **nonWorkingLogout** function. In this case, the new object is **assigned** to the variable `user`, which is **not locally** defined in the function. This action successfully updates the **outer** `user` variable defined outside the function.

> In the markup, the **username** and **status** of the `user` object are displayed. 

> Two buttons are provided, with one triggering the **nonWorkingLogout** function and the other triggering the **workingLogout** function upon being clicked. When the **Non-working Logout** button is clicked, the status of the `user` object does not change to **offline** as intended due to variable shadowing. Conversely, clicking the **Working Logout** button successfully updates the status of the user object to **offline** because the **outer** `user` variable is modified within the function.

<br/>

***

<br/>

## Templating <a href="#templating"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Svelte's templating system provides a concise and intuitive approach for developing reactive web applications. In component markup, the `{variable}` syntax is used for variable interpolation, allowing dynamic content rendering with reactive updates. The `{@html variable}` special tag permits the injection of raw, unsanitized HTML content, but caution is advised to prevent potential XSS vulnerabilities. 

Svelte offers features for conditional rendering, looping, and promise handling within templates. **Conditional rendering** is achieved using the `{#if}` block statement to render code based on specific conditions, with support for `{:else if}` and `{:else}` statements for multiple conditions. The `{#each}` block statement enables **iteration** over arrays or iterable objects for markup rendering. For **promise handling**, the `{#await}` block statement manages promises with separate blocks for pending, resolved, and rejected states.

The `{@const expression}` special tag defines local constants for use within `{#if}`, `{:else if}`, `{:else}`, `{#each}`, `{:then}`, and `{:catch}` blocks, enhancing readability and efficiency by avoiding repetitive calculations.

Svelte also includes the **class:** directive for dynamic CSS class inclusion, allowing adjustments to styling based on conditions. The **style:** directive enables the transfer of CSS variables to CSS properties, facilitating dynamic styling of DOM elements. Additionally, through component styles, Svelte promotes reusability and consistency by passing CSS variables to child components, ensuring a cohesive design experience throughout the application.

It is worth noting that CSS is contained within the component to prevent unintended style clashes. When styling elements beyond a component's boundaries is necessary, the `:global()` directive can be used to extend CSS rules throughout the application. It is advisable to use it sparingly to minimize CSS leakage and maintain encapsulation. Limiting the use of `:global()` enhances styling encapsulation and helps prevent unintended style conflicts between components.

```svelte
<script>
    const item = '<strong>Hello, world</strong>'
</script>

<p>Render as text: {item}</p>
<p>Render as HTML: {@html item}</p>
```
*Example of variable interopolation*

***

```svelte
<script>
    let count = 0;
</script>

<p>Count: {count}</p>
<button on:click={() => count++}>Increment</button>

<!-- Both "else if" and "else" blocks are optional -->
{#if count > 10}
    <p>More than 10</p>
{:else if count >= 5}
    <p>More than or equal to 5</p>
{:else}
    <p>Less than 5</p>
{/if}
```
*Example of conditional rendering*

***

```svelte
<script>
    const users = [
        { username: 'user1', status: 'online'},
        { username: 'user2', status: 'offline'},
        { username: 'user3', status: 'online'}
    ];
</script>

<!-- else block is optional -->
{#each users as user}
    <p>{user.username} is {user.status}</p>
{:else}
    <p>No users to display</p>
{/each}

{#each users as user, index}
    <p>{index}. {user.username} is {user.status}</p>
{/each}
```
*Example of iteration over array to render each element*

***

```svelte
<script>
    const users = [
        { username: 'user1', age: 25, location: { country: 'USA' } },
        { username: 'user2', age: 35, location: { country: 'UK' } },
        { username: 'user3', age: 32, location: { country: 'USA' } },
        { username: 'user4', age: 23, location: { country: 'UK' } },
        { username: 'user5', age: 21, location: { country: 'UK' } },
        { username: 'user6', age: 44, location: { country: 'USA' } },
    ];
</script>

<!-- Object destruction-->
{#each users as { username, age, location }, index}
    <!-- Local constants -->
    {@const country = location.country}

    {#if country === 'USA'}
        {@const text = `${username}, ${age} is`}
        <p>{index + 1}. {text} from {country}</p>
    {/if}
{/each}
```
*Example of using object destruction and local constants in the markup*

***

```svelte
<script>
    const promiseThatResolves = new Promise(resolve => {
        setTimeout(
            () => resolve('Hello, world'), 
            2000
        );
    });

    const promiseThatRejects = new Promise((_, reject) => {
        setTimeout(
            () => reject('An error occured'), 
            2000
        );
    });
</script>

<!-- Handle pending and resolved states-->
{#await promiseThatResolves}
    <p>1. Waiting to resolve...</p>
{:then data} 
    <p>1. Resolved to "{data}"</p>
{/await}

<!-- Handle resolved state -->
{#await promiseThatResolves then data}
    <p>2. Resolved to "{data}"</p>
{/await}

<!-- Handle pending, resolved, and rejected states -->
{#await promiseThatRejects}
    <p>3. Waiting to resolve...</p>
{:then data} 
    <p>3. Resolved to "{data}"</p>
{:catch error}
    <p>3. Rejected with "{error}"</p>
{/await}

<!-- Handle resolved and rejected states -->
{#await promiseThatRejects then data}
    <p>4. Resolved to "{data}"</p>
{:catch error}
    <p>4. Rejected with "{error}"</p>
{/await}
```
*Example of rendering based on promise status*

***

> The example above illustrates the `class:` directive, `style:` directive, and component styles:

```svelte
<script>
    export let label;
    
    let toggled = true;
</script>

<!-- Toggle class without class directive -->
<button
    on:click={() => toggled = !toggled}
    class={toggled ? 'state-true' : 'state-false'}
>
    {label}
</button>

<!-- Toggle class with class directive -->
<button
    on:click={() => toggled = !toggled}
    class='state-true'
    class:state-false={!toggled}
>
    {label}
</button>

<!-- Toggle class with multiple class directives -->
<button
    on:click={() => toggled = !toggled}
    class:state-true={toggled}
    class:state-false={!toggled}
>
    {label}
</button>

<!-- Shorthand class directive -->
<button
    on:click={() => toggled = !toggled}
    class:toggled
>
    {label}
</button>

<style>
    .state-true {
        background-color: var(--color-true);
    }

    .state-false {
        background-color: var(--color-false);
    }

    .toggled {
        background-color: brown;
    }
</style>
```
*ToggleButtons.svelte*

```svelte
<script>
    import ToggleButtons from './ToggleButtons.svelte';
</script>

<!-- Using component styles -->
<ToggleButtons
    label='Click'
    --color-true='green'
    --color-false='red'
/>

<!-- Using style directive on DOM element -->
<p style:--text-color='blue'>Click any button</p>

<style>
    p {
        color: var(--text-color);
    }
</style>
```
*Styling.svelte*

***

> An example of leaking CSS using the `:global()` directive:

```svelte
<p>Child Component</p>
```
*Child.svelte*

```svelte
<script>
    import Child from './Child.svelte';
</script>

<p>Parent Component</p>
<Child />
```
*Parent.svelte*

```svelte
<script>
    import Parent from './Parent.svelte';
</script>

<div>
    <Parent />
</div>

<style>
    /* 
       Limit :global() rules as much as possible.
       Apply to p elements that follow another 
           p element and have a div parent.
    */
    div > :global(p + p) {
        background-color: red;
        color: #fff;
        padding: 1em;
        margin: 1em;
    }
</style>
```
*Global.svelte*

> The `div > :global(p + p)` rule targets the Child component.

<br />

***

<br />

## Keyed {#each} Block <a href="#keyed-each-block"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

In an `{#each}` block, the key attribute uniquely identifies each array item during rendering in Svelte. This helps Svelte efficiently update and re-render the list when changes occur. Although the array index can serve as a key in some cases, it may not always guarantee uniqueness, especially with dynamic array manipulation. It is recommended to associate the key attribute directly with the object itself by accessing a property that is guaranteed to be unique. This ensures that each item has a distinct identifier. Providing a key allows Svelte to map each rendered item to a specific identifier. When the array is updated, Svelte uses these keys to efficiently determine which blocks need to be removed from the DOM. If a key is no longer present in the updated array, the corresponding item is removed from the DOM. However, if the key remains the same and only the properties change, Svelte will update the properties of the existing item instead of recreating it. To prevent unintended behavior during array manipulation, it is recommended to utilize keyed `{#each}` blocks.

```svelte
<script>
	// Updated when prop changes in parent component
	export let current;

	// Set during component creation and not updated afterwards
	let initial = current;

	console.log(`ColorBadge (${initial}, ${current}) created`);
</script>

<p>
	<span style='background-color: {initial}'>Initial</span>
	<span style='background-color: {current}'>Current</span>
</p>

<style>
	p {
		display: flex;
		justify-content: center;
		align-items: center;
		gap: 0.2em;
		color: #fff;
		font-weight: 700;
	}

	span {
		width: 4em;
		margin: 0.2em;
		padding: 0.3em;
		border-radius: 0.2em;
		text-align: center;
	}
</style>

```
*ColorBadge.svelte*

***

```svelte
<script>
	import ColorBadge from './ColorBadge.svelte';

	let colors = [
		{ id: 1, value: 'red' },
		{ id: 2, value: 'orange' },
		{ id: 3, value: 'green' },
		{ id: 4, value: 'blue' },
		{ id: 5, value: 'brown' }
	];

	function deleteFirst() {
		colors = colors.slice(1);
	}
</script>

<div class='container'>
	<div>
		<h2>Keyed</h2>
		{#each colors as color (color.id)}
			<ColorBadge current={color.value} />
		{/each}
	</div>

	<div>
		<h2>Non-keyed</h2>
		{#each colors as color}
			<ColorBadge current={color.value} />
		{/each}
	</div>
</div>

<div class='container mt'>
	<button on:click={deleteFirst}>Delete First</button>
</div>

<style>
	.container {
		display: flex;
		justify-content: center;
		align-items: center;
		gap: 5em;
	}

	.mt {
		margin-top: 1em;
	}
</style>
```
*KeyedEach.svelte*

> The code example above demonstrates the use of keyed `{#each}` blocks. It includes a **ColorBadge** component with 2 variables, `current`, which updates with changes in the parent component, and `initial`, which is set during component creation and **remains constant**, storing **color** values.

> Two spans in a paragraph display background colors based on these variables. Additionally, a message is logged in the console when the component is created. The **KeyedEach** component uses an array of colors to create **ColorBadge** components.
 
> The colors are shown in 2 sections, one using the **keyed approach** and the other using the **non-keyed approach**. There is a **Delete First** button that removes the first item in the color array, triggering a UI re-render. In this scenario, **ColorBadge** components are not destroyed and recreated, instead, they are **updated**. The console.log will not trigger. 

> When the array is updated, the **keyed approach correctly** displays ColorBadge components. However, in the **non-keyed approach**, the **old value for initial** is displayed in each ColorBadge as items shift in the array. This issue arises from Svelte's inability to detect the dependency between the **initial** and **current** variables, leading to a mix-up in the non-keyed approach.

<br />

***

<br />

## Events <a href="#events"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Events are handled using the `on:` directive, which allows Svelte to listen for both DOM events and custom events on elements. These events serve as communication units between different elements and components. Custom events are particularly useful for transmitting data between child and parent components. When using the `on:event-name` directive, a function can be assigned as the value, which will be invoked after the event is dispatched. The function receives an event object containing information about the event. It is important to note that events can be triggered by various activities on the web page, such as clicks, mouse movements, and keyboard inputs.

```svelte
<button 
    on:click={() => console.log('Hello, world')}
>
    Click
</button>

<div
    on:mouseenter={() => console.log('Hovered')}
    on:mouseleave={() => console.log('Unhovered')}
>
    Hover Over Here
</div>
```
*Examples of event handling*

<br />

***

<br />

## DOM Event Modifiers <a href="#dom-event-modifiers"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Modifiers in DOM event handlers offer enhanced control and customization options, allowing for more precise handling of events. These modifiers grant extra control in managing event behavior.

For instance, the **preventDefault** modifier can be used to invoke `e.preventDefault()` before executing the handler, preventing the default event behavior. The **stopPropagation** modifier stops the event from propagating to the next element by calling `e.stopPropagation()`. The **passive** modifier enhances scrolling performance on touch and wheel events. Conversely, the **nonpassive** modifier explicitly sets `passive: false` for the event listener. The **capture** modifier triggers the handler during the capture phase instead of the bubbling phase. Using the **once** modifier removes the event handler after it has been triggered once. The **self** modifier ensures that the handler is activated only if the `e.target` corresponds to the element itself. Lastly, the **trusted** modifier only activates the handler if `e.isTrusted` is true, indicating that the event was initiated by a user action rather than programmatically. **Chaining** these modifiers allows for a more sophisticated approach to event handling, enabling greater precision and control.

```svelte
<button 
    on:click|once|capture={() => console.log('Hello, world')}
>
    Click
</button>
```
*Example of DOM event modifier chaining*

<br />

***

<br />

## Component Dispatched Events <a href="#component-dispatched-events"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Components can communicate with each other by dispatching custom events. This decoupled approach allows for flexible communication and interaction between components. To dispatch an event, you can use the **createEventDispatcher** function provided by Svelte. This function returns a dispatch function that you can use to send custom events with optional data payloads.

On the receiving end, the `on:event-name` directive is used to listen for and handle these custom events. This enables you to respond to events and access any data passed along with them using `e.detail`. By leveraging custom events, Svelte components can effectively communicate and coordinate their actions. 

In contrast to DOM events, event bubbling, which involves the propagation of events from innermost child components to outermost ones, does not occur automatically with component events.

If you wish to listen to an event on a deeply nested component, the intermediate components need to forward the event to the parent component. This process, known as **event forwarding**, enables event handling at various levels within the component hierarchy. It is worth noting that event forwarding is also applicable to DOM events.

> The example above showcases component event dispatching, event forwarding, and event handling:

```svelte
<script>
    import { createEventDispatcher } from 'svelte';
    
    const dispatch = createEventDispatcher();

    // Dispatch a "data" event
    const handleClick = () => {
        dispatch('data', { message: 'Hello from Inner' });
    }
</script>

<button on:click={handleClick}>Click</button>
```
*Inner.svelte*

***

```svelte
<script>
    import Inner from './Inner.svelte';
</script>

<!-- Forward component dispatched event instead of handling it -->
<Inner on:data />
```
*Outer.svelte*

***

```svelte
<script>
    import Inner from './Inner.svelte';
    import Outer from './Outer.svelte';
</script>

<!-- Handle component dispatched events -->
<Inner 
    on:data={e => console.log('Inner:', e.detail.message)}
/>

<Outer 
    on:data={e => console.log('Outer:', e.detail.message)} 
/>
```
*ComponentDispatcedEvents.svelte*

<br/>

***

<br/>

> The example above illustrates DOM event forwarding and DOM event handling:

```svelte
<!-- Forward click event -->
<button on:click>Click</button>
```
*ForwardButton.svelte*

***

```svelte
<!-- Handle click event -->
<button 
    on:click={() => console.log('Handled click event')}
>
    Click
</button>
```
*HandleButton.svelte*

***

```svelte
<script>
    import ForwardButton from './ForwardButton.svelte';
    import HandleButton from './HandleButton.svelte';

    let text = '';
</script>

<div class='container'>
    <div>
        <!-- Handling DOM event -->
        <input on:input={ ({ target }) => text = target.value} />
        <p>Input: {text}</p>
    </div>
    
    <div>
        <!-- Handle forwarded click event -->
        <ForwardButton 
            on:click={() => console.log('Received click event')} 
        />
    
        <!-- 
            Event is not forwarded, hence the 
                click handler will not be triggered 
        -->
        <HandleButton 
            on:click={() => console.log('Received click event')} 
        />
    </div>
</div>

<style>
    div {
        display: flex;
        flex-wrap: wrap;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        gap: 1em;
    }

    .container {
        flex-direction: row;
        gap: 5em;
    }
</style>
```
*DOMEvents.svelte*

<br />

***

<br />

## Component Lifecycle  <a href="#component-lifecycle"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

The lifecycle of a component refers to the various stages it goes through, from creation to destruction, with several functions available to execute code at crucial moments. 

The **onMount** function triggers after the component has been rendered to the DOM, allowing actions like fetching data from an API or setting up event listeners once the component has been mounted. Additionally, you can return a callback function that executes when the component when the component is about to be destroyed. This callback function will be executed within the onMount callback's function scope, which is useful for accessing variables.

The **onDestroy** function offers a cleaner semantic approach compared to the callback within onMount, as it explicitly signifies the purpose of performing clean-up tasks before the component is removed from the DOM. This function can be utilized when direct access to the onMount scope is not required, offering a structured approach to managing clean-up operations.

The **beforeUpdate** and **afterUpdate** functions allow you to perform imperative actions before and after the DOM is updated to reflect changes in the component's data. It is important to note that beforeUpdate runs initially before onMount, while afterUpdate runs after onMount.

Unlike the other functions, the **tick** function can be called at any time. Its purpose is to pause code execution. When invoked, it returns a promise that resolves once any pending state changes have been applied to the DOM. This functionality ensures that specific DOM updates have taken place before further code execution proceeds.

```svelte
<script>
    import { onMount, onDestroy } from 'svelte';

    export let name;

    onMount(() => console.log('Item created'));
    onDestroy(() => console.log('Item destroyed'));
</script>

<li>{name}</li>
```
*Item.svelte*

***

```svelte
<script>
    import { onMount, beforeUpdate, afterUpdate } from 'svelte';
    import Item from './Item.svelte';

    let show = true;
    let items = [];

    // Simulate an API call
    function fetchData() {
        const data = Array
            .from({ length: 5 })
            .map((_, idx) => `Item ${idx + 1}`);

        return new Promise(resolve => {
            setTimeout(
                () => resolve({ data }), 
                2000
            );
        });
    }

    onMount(async () => {
        console.log('List is being created');
        const res = await fetchData();
        items = res.data;
    });

    beforeUpdate(() => console.log('List is about to be updated'));
    afterUpdate(() => console.log('List has been updated'));
</script>

<button on:click={() => show = !show}>
    Toggle    
</button>

{#if show}
    <ul>
        {#each items as name}
            <Item {name} />
        {/each}
    </ul>
{:else}
    <p>Fetching data...</p>
{/if}
```
*List.svelte*

> The code example above includes a **List** component that manages a list of items. When the List component is mounted, it initiates a simulated API call using the **fetchData** function. This data is then used to create instances of the **Item** component.

> The **List** component includes beforeUpdate and afterUpdate functions that log messages before and after each update. The visibility of each Item component is controlled by a **show** variable, toggled by a button click. If **show** is true, the Item components are displayed, otherwise, a message **"Fetching data…"** is shown. 

> The **Item** component logs messages upon mounting and destruction. Toggling visibility causes the Item component to be destroyed and recreated, triggering the beforeUpdate and afterUpdate functions of the **List** component during re-rendering.

***

```svelte
<script>
    import { tick } from 'svelte';

    let count = 0;
    let p;

    async function increment() {
        count++;
        console.log('Before tick:', p.textContent);
        await tick();
        console.log('After tick:', p.textContent);
    }
</script>

<p bind:this={p}>{count}</p>

<button on:click={increment}>
    Increment
</button>
```
*Tick.svelte*

> In the code example above, there is a `p` element that is bound to the variable **p**. The initial value of count is **0**. When the **Increment** button is clicked, the **increment** function is called. 

> Within the function, **count** is incremented by 1, and the current value of `p.textContent` is logged to the console. 

> Initially, before the `await tick()` statement, the value of `p.textContent` is logged as **0**. This is because the DOM update to reflect the increment in **count** is not immediate.

> By utilizing the `await tick()` statement, you allow the DOM to update and apply the state change before continuing with the code execution. Once the promise returned by **tick** resolves, the code execution proceeds, and the updated value of `p.textContent`, which is now **1**, is logged to the console.

<br />

***

<br />

## Stores <a href="#stores"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Stores in Svelte are objects designed to hold specific values and provide a subscribe method for interested parties to receive notifications of any changes. They offer an efficient and reactive way to manage and share state among components. By using stores, you can store and update values that are accessible and modifiable by different components, even if they are unrelated. When the value within a store changes, any subscribed component will automatically update to reflect the new value.

To create a store, you can use the **writable** function to create a store that allows both reading and writing, or the **readable** function to create a store that can only be read from. **Writable stores** can be updated or set by subscribers, while **readable stores** do not have set and update methods, allowing subscribers only to read the data.

**Derived stores**, created with the **derived** function, are readable stores computed or derived from existing stores. They enable you to create new stores that automatically update whenever the values of the dependent stores change.

To reference the value of a store, you can prefix the store name with a `$`. For example, `$count` references the value of a store called `count`. This shorthand notation allows you to access the value of the store in components or expressions.

The `svelte/store` module provides the **writable**, **readable**, and **derived** functions. Additionally, it provides the **get** function, which fetches the value of a store you are not subscribed to, and the **readonly** function, which produces a new readable store from an existing store. Note that the get function is implemented by setting up a subscription, reading the value, and then unsubscribing, which is generally discouraged.

> In the context of reactivity, **subscribing** refers to the process of registering an interest in modifications to a specific data item or state. 

> When you **subscribe** to a reactive entity, such as a variable or a store, you are essentially indicating that you want to be notified whenever that entity's value changes. 

```js
import { writable, readable, derived, readonly } from 'svelte/store';

/**
 * Writable store.
 * Allows to retrieve and update the data.
 */
export const count = writable(0);

/** 
 * Readable store created with readonly(). 
 * Allows to retrieve the data.
 */
export const readableCount = readonly(count);

/** Derived readble store.
 * Allows to retrieve the computed data.
 */
export const doubledCount = derived(count, (cnt) => 2 * cnt);

/** 
 * Derived readble store from multiple stores.
 * Allows to retrieve the computed data.
 */
export const multiCount = derived(
    [count, readableCount],
    vals => vals[0] + vals[1],
);

/** 
 * Readable store.
 * Allows to retrieve the data.
 */
export const random = readable(randNum(), start);

// Generate a random number from 0 to 99
function randNum() {
    return Math.floor(Math.random() * 100);
}

// Start function to generate values
function start(set) {
    // Generate and set a random number every second
    const intervalId = setInterval(() => set(randNum()), 1000);

    /**
     * Stop function will be called on component destruction.
     * If multiple components use the random store at the same time, 
     * and one of them calls the stop function, it will impact all. 
     */
    return () => clearInterval(intervalId);
}
```
*stores.js*

***

```svelte
<script>
    import { onDestroy } from 'svelte';
    import { 
        count, 
        readableCount, 
        doubledCount, 
        multiCount, 
        random 
    } from './stores';

    /**
     * Store values received from subscriptions 
     *  will be stored to these variables.
     */
    let countValue, doubledCountValue, randomValue;
    
    /**
     * Subscribe to the stores and 
     *  store the returned unsubscribe functions.
     */
    const unsubscribeCount = count
        .subscribe(cnt => countValue = cnt);

    const unsubscribeDoubledCount = doubledCount
        .subscribe(val => { doubledCountValue = val; });

    const unsubscribeRandom = random
        .subscribe(val => randomValue = val);

    // Unsubscribe when component is about to be removed from the DOM
    onDestroy(() => {
        unsubscribeCount();
        unsubscribeDoubledCount();
        unsubscribeRandom();
    });
</script>

<p>Count: {countValue}</p>
<p>Readable Count: {$readableCount}</p>
<p>Doubled Count (1 Store): {doubledCountValue}</p>
<p>Doubled Count (2 Stores): {$multiCount}</p>
<p>Random Number: {randomValue}</p>

<!-- 
    Writable stores can be updated or set by the subscribers.
    Readable stores do not have set and update methods.
-->
<button on:click={() => count.update(cnt => cnt + 1)}>
    Increment Count
</button>

<button on:click={() => count.set(0)}>
    Reset Count
</button>
```
*Numbers.svelte*

> In the code above, the **stores.js** file introduces various types of stores. It begins by creating a **writable store** named `count` with an initial value of **0**, followed by a **readable store**, `readableCount`, generated using the **readonly** function. 

> Additionally, a **derived store** named `doubledCount` is established, computing its value as twice the `count` store's value. Another **derived store**, `multiCount`, calculates its value as the sum of `count` and `readableCount`.
 
> The code also includes a **readable store** named `random`, which generates random numbers from 0 to 99 and updates every second through the **start function**. This function orchestrates the continuous generation of random numbers and clears the interval when necessary, typically upon component destruction.

> The **Numbers** component subscribes to the `count`, `doubledCount`, and `random` stores, storing their values in variables **countValue**, **doubledCountValue**, and **randomValue**, respectively. 

> The **unsubscribe** functions are stored for cleanup purposes. During component destruction, the onDestroy lifecycle function is employed to unsubscribe from each store. 

> The values of the stores are displayed in the markup, with the use of `$` to access the values of `readableCount` and `multiCount` stores. Additionally, buttons are included for users to update the writable store `count` by incrementing its value or resetting it to 0, **triggering updates in all related stores**.

> This code effectively showcases how stores can be utilized for state management and interaction within a component.

<br />

***

<br />

## Custom Stores <a href="#custom-stores"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

By implementing the **subscribe** method, developers can easily create custom stores with domain-specific logic. This flexibility empowers developers to craft their own stores tailored to meet specific requirements. Custom stores offer a high level of control and encapsulation for effective state management.

For example, a custom store designed for a user's shopping cart, named **cart**, can be generated using a **createCart** function. The cart store maintains an array of items that represent the user's shopping cart. It offers methods such as **addToCart**, **removeFromCart**, and **emptyCart** to alter the cart state. By subscribing to the cart store, other components can effortlessly receive updates whenever changes occur in the cart, enabling them to reflect these modifications in their rendering.

```js
import { writable } from 'svelte/store';

// Create a custom store for a shopping cart
function createCart() {
    const { subscribe, set, update } = writable([]);

    // Do not expose set and update methods
    return {
        subscribe,
        addToCart: item => update((cart) => [...cart, item]),
        removeFromCart: itemId => {
            update(cart => 
                cart.filter((item) => item.id !== itemId)
            );
        },
        emptyCart: () => set([]),
    };
}

// Singleton cart
export const cart = createCart();
```
*cart.js*

***

```svelte
<script>
    import { onDestroy } from 'svelte';
    import { cart } from './cart';
    
    let items;
    let id = 0;

    const unsubscribe = cart.subscribe(val => items = val);
    onDestroy(unsubscribe);

    function addToCart() {
        cart.addToCart({ id, name: `Item ${id}` });
        id++;
    }

    function removeFromCart() {
        cart.removeFromCart(--id);
    }

    function emptyCart() {
        cart.emptyCart();
        id = 0;
    }
</script>

<h3>Cart Summary</h3>

<ul>
    {#each items as { id, name } (id)}
        <li>{name}</li>
    {/each}
</ul>

<button on:click={addToCart}>Add Item</button>
<button on:click={removeFromCart}>Remove Last Item</button>
<button on:click={emptyCart}>Empty Cart</button>
```
*ShoppingCart.svelte*

> In this example, the **createCart** function returns an object with a *subscribe* method, allowing components to subscribe to changes in the cart state. It also exposes 3 methods to update the cart state: **addToCart**, **removeFromCart**, and **emptyCart**. 

> The **addToCart** method adds an item to the cart by updating the cart state with a new array that includes the item. 

> Similarly, the **removeFromCart** method removes an item from the cart by updating the cart state with a new array that excludes the item. 

> Lastly, the **emptyCart** method resets the cart state to an empty array. 

> To ensure a clean and concise interface, the **update** and **set** methods are not exposed. This simplifies the usage of the cart store and allows components to interact with the cart state using the provided methods. 

> In the **ShoppingCart** component, a variable **id** is initialized to **0**, and a variable **items** is declared to hold the cart items. The **unsubscribe** variable is assigned the result of subscribing to the **cart** store. The **onDestroy** function is used to unsubscribe from the **cart** store when the component is destroyed, ensuring that there are no memory leaks. 

> The **addToCart** function adds an item to the cart by calling the **addToCart method of the cart** store and passing an object with the **id** and **name** properties. The **id** is incremented after each addition.

> The **removeFromCart** function removes the last added item from the cart by calling the **removeFromCart method of the cart** store and passing the **current id** value decremented by 1.

> The **emptyCart** function resets the **id** to 0 and empties the cart by calling the **emptyCart method of the cart** store. 

> In the markup a list of items is displayed, along with 3 buttons for cart updates. When changes occur in the cart store, Svelte detects them and re-renders the component. Consequently, the list of items dynamically updates to reflect the latest state of the cart.

<br />

***

<br />

## Slots <a href="#slots"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

**Slots** allow you to transfer content from a parent component to its child component. This feature provides greater flexibility and dynamism when composing components.

**Named slots** are particularly handy when you need to pass different content to specific slots within a component. By assigning a name to a slot, you can determine which content should be displayed in that slot, giving you more control over the composition of your components. 

In situations where a component does not receive any content for a specific slot, you can use **slot fallbacks**. By providing fallback content, you ensure that the component remains functional even if some slots are left empty. 

**Slot props** allow you to pass data from the parent component to the content displayed within a slot. This empowers you to customize the content based on the data provided by the parent component, giving you more flexibility in designing your components.

**Conditional slots** allow to selectively render distinct sets of content within a component, depending on specific conditions. This powerful feature enables the dynamic rendering or omission of different parts of a component's template, providing flexibility and adaptability.

```svelte
<div class='card'>
    <header>
        <slot name='name' />
    </header>

    <!-- 
        There is no way to apply CSS directly to a slot, 
          wrap it in a DOM element.
        i.e. ".card > *" will not match an unwrapped slot 
          inside the card container, so target the parent element.
    -->
    <div>
        <slot />
    </div>
    
    <footer>
        <span>Power:</span>
        <slot name='power'>100</slot>
    </footer>
</div>

<style>
    .card {
        width: 22em;
        border: 2px solid #000;
        border-radius: 0.5em;
        background-color:slategray;
    }

    .card > * {
        display: flex;
        justify-content: center;
        align-items: center;
        width: auto;
        padding: 1em;
        margin: 0.5em;
        background-color: cornflowerblue;
        color: #fff;
        font-size: 1.2rem;
    }

    header {
        border-radius: 0.3em 0.3em 0 0;
    }

    footer {
        border-radius: 0 0 0.3em 0.3em;
    }

    footer > span {
        padding-right: 0.5em;
    }

    :is(header, footer > span) {
        font-weight: 800;
    }

    :not(header, footer) {
        text-align: center;
        text-wrap: balance;
    }
</style>
```
*Card.svelte*

***

```svelte
<script>
    import Card from './Card.svelte';
</script>

<Card>
    <span>
        A strong and valiant <strong>fighter</strong> 
        with lightning attacks, 
        defensive skills, and empowering abilities, 
        inspiring allies and intimidating foes.
    </span>

    <span slot='name'>Mighty Warrior</span>
    <span slot='power'>245</span>
</Card>
```
*Slots.svelte*

> In the code above, the **Card** component utilizes slots to allow for customization and injection of content. It offers 2 named slots, namely **name** and **power**. Any content assigned to these slots will be displayed in their respective places within the Card component. 

> The first span element is not assigned to any specific slot and will be placed in the default slot, represented by `<slot />` without a name. 

> The second span element, designated with `slot='name'`, will be assigned to the **name** slot.
 
> Similarly, the third span element, marked with `slot='power'`, will be assigned to the **power** slot. If no content is provided for the power slot, the fallback content **100** will be shown.

> It is important to note that you cannot apply CSS styles directly to a slot. To style the slot content, you must wrap the slot inside an element and apply styles to that wrapping element.

***

```svelte
<script>
    let hovering;
    const enter = () => hovering = true;
    const leave = () => hovering = false;
</script>

<!-- svelte-ignore a11y-no-static-element-interactions -->
<div on:mouseenter={enter} on:mouseleave={leave}>
    <slot {hovering} />
</div>

<style>
    div {
        width: 10em;
        border: 2px solid #000;
        text-align: center;
    }
</style>
```
*Hoverable.svelte*

***

```svelte
<script>
    import Hoverable from './Hoverable.svelte';
</script>

<Hoverable let:hovering={active}>
    {#if active}
        <p>I'm being hovered upon</p>
    {:else}
        <p>Hover over me</p>
    {/if}
</Hoverable>
```
*SlotProps.svelte*

> The **Hoverable** component facilitates tracking if an element is being hovered over and relaying this to its slotted content. It encloses the slotted content with a div element that monitors **mouseenter** and **mouseleave** events.
 
> On **mouse entry**, the **enter** function triggers, setting the **hovering** variable to `true`. 

> On **mouse exit**, the **leave** function triggers, setting **hovering** to `false`.
 
> In the slotted content, the `let:hovering={active}` syntax receives the **hovering** value from **Hoverable**. The **active** variable is utilized for conditional content rendering, exclusively within the slot. It is worth noting that you can simplify by using `let:hovering` and checking if hovering is true, eliminating the need to define active separately.

***

```svelte
<div>
    <p>
        <span>Name:</span>
        <slot name='name' />
    </p>

    {#if $$slots.email}
        <p>
            <span>Email:</span>
            <slot name='email' />
        </p>
    {/if}

    {#if $$slots.phone}
        <p>
            <span>Phone:</span>
            <slot name='phone' />
        </p>
    {/if}
</div>

<style>
    div {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        width: 10em;
        border: 2px solid #000;
        padding: 0.5em;
    }
</style>
```
*Profile.svelte*

***

```svelte
<script>
    import Profile from './Profile.svelte';
</script>

<div>
    <Profile>
        <span slot='name'>John Doe</span>
        <span slot='email'>john@mail.com</span>    
    </Profile>
    
    <Profile>
        <span slot='name'>George Doe</span>
        <span slot='phone'>+1234567890</span>    
    </Profile>
    
    <Profile>
        <span slot='name'>Andrew Doe</span>
    </Profile>
</div>

<style>
    div {
        display: flex;
        justify-content: center;
        align-items: center;
        gap: 5em;
    }
</style>
```
*Users.svelte*

> In this code example, the `$$slots` special variable is employed to access defined slots, enabling conditional content rendering based on specific slot presence. Within `{#if}` blocks, `$$slots` is used to verify the existence of certain slots in the component. When a slot with a particular name is present, the associated section is rendered, facilitating dynamic content rendering according to the slots supplied by the parent component.

<br />

***

<br />

## Context API <a href="#context-api"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

The Context API in Svelte offers a convenient feature that simplifies the sharing of data and state between components, eliminating the need for prop drilling. **Prop drilling** refers to passing data through multiple intermediary components. However, with the Context API, a parent component can directly pass data to any children components, even if they are not immediate descendants. 

The **context** is an object that acts as a container for shared data and state. It can hold various types of data, including primitive values, arrays, objects, and stores. Unlike other frameworks, the key used in the Context object can be any value, even non-strings, giving you more control over access to the Context. 

It is important to keep in mind that the Context API in Svelte is not reactive by default. This means that the value of the Context is set once when the component is mounted and does not automatically update when the value changes. However, you can make use of stores within the Context object to pass dynamic values to child components. This allows the child components to reactively update when the store values change. This capability provides a powerful way to manage and share state across components in a reactive manner. 

Note that the **context object** itself is the specific object that holds the shared data, while the **Context API** is the feature that enables the creation and usage of this context object within the Svelte framework.

```svelte
<script>
    import { getAllContexts, getContext, hasContext } from 'svelte';

    const name = hasContext('name') ? getContext('name') : '';
    const { format } = getContext('format');
    const contextMap = getAllContexts();
</script>

<p>{format(name)}</p>
<p>Contexts: {Array.from(contextMap.keys()).join(', ')}</p>
```
*Child.svelte*

***

```svelte
<script>
    import Child from './Child.svelte';
</script>

<Child />
```
*Parent.svelte*

***

```svelte
<script>
    import Parent from './Parent.svelte';
</script>

<Parent />
```
*Grandparent.svelte*

***

```svelte
<script>
    import { setContext } from 'svelte';
    import Grandparent from './Grandparent.svelte';

    setContext('name', 'Jonh Doe');

    setContext('format', {
        format: name => `Hello, ${name}`
    });
</script>

<Grandparent />
```
*Context.svelte*

> In the code above, the **Context** component renders the **Grandparent** component, which then renders the **Parent** component, and subsequently, the Parent component renders the **Child** component, establishing a component hierarchy.

> Within the **Context** component, the **setContext** function is used to define the context data. The **name** key is associated with the value **"Jonh Doe"**, while the **format** key is connected to an object containing a format function. 

> The **Child** component retrieves and utilizes the context data, showcasing the seamless passing of information through various component levels.

***

```svelte
<script>
    import { getContext, setContext } from 'svelte';
    import { writable } from 'svelte/store';

    let name = writable('');
    setContext('name', name);
    
    let message = getContext('name');

    function randomName() {
        const names = ['George', 'John', 'Peter', 'Dennis'];
        const idx = Math.floor(Math.random() * names.length);
        
        return names[idx];
    }
</script>

<p>Hello, {$message}</p>

<button on:click={() => $name = randomName()}>
    Change Name
</button>
```
*ReactiveContext.svelte*

> This code example illustrates a reactive context implementation. It establishes a dynamic data flow by leveraging context and store functionalities. 

> Initially, a writable store named **name** is created and assigned as the context data. The **message** variable retrieves and stores this context data. A **randomName** function is defined to generate a random name from a predefined list.
 
> Within the markup, a p element displays the **message** variable, which holds a writable store as its value. Furthermore, a button triggers the **randomName** function to update the name store, leading to automatic updates in the displayed message content.

<br />

***

<br />

## Special Elements <a href="#special-elements"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Svelte provides special elements that enhance component markup. 

The `<svelte:self>` refers to the current component and is commonly used for recursive components or self-referencing within a template. 

The `<svelte:component>` and `<svelte:element>` elements enable dynamic switching between different components or DOM elements based on specific conditions. For instance, `<svelte:component>` can render a login form when the user is not authenticated and switch to a user profile once authenticated. Similarly, `<svelte:element>` dynamically renders HTML elements based on user interactions or conditions.

The `<svelte:head>` permits direct manipulation of the head element in components. It proves useful for dynamically modifying or adding elements like title, style or meta tags.

The `<svelte:window>`, `<svelte:body>`, and `<svelte:document>` elements allow event listening on window, body, and document respectively within components. These elements facilitate handling global events occurring outside the component's immediate scope, responding to user interactions or external changes.

The `<svelte:fragment>` element allows content placement in a named slot without requiring a container DOM element. It proves useful when you want to avoid unnecessary wrapping elements.

Lastly, with `<svelte:options>`, compiler options can be configured. This customization allows you to tailor the behavior of your components by enabling or disabling specific features or optimizations.

```js
export let data = [
  {
    name: "dir1",
    files: [
      {
        name: "dir1A",
        files: [{ name: "file.json" }],
      },
    ],
  },
  {
    name: "dir2",
    files: [{ name: "file.txt" }],
  },
  { name: "file.txt" },
];
```
*data.js*

***

```svelte
<script>
    export let name;
</script>

<span>{name}</span>
```
*File.svelte*

***

```svelte
<script>
    import File from './File.svelte';

    export let name, files, expanded;
</script>

<button on:click={() => expanded = !expanded}>
    /{name}
</button>

{#if expanded}
    <div class='expanded'>
        {#each files as file}
            {@const isDir = file.files}

            {#if isDir}
                <svelte:self {...file} />
            {:else}
                <File {...file} />
            {/if}
        {/each}
    </div>
{/if}

<style>
    * {
        display: block;
    }

    button {
        background-color: transparent;
        border: none;
        padding: 0;
        margin: 0;
        cursor: pointer;
    }

    .expanded {
        margin-left: 1em;
    }
</style>
```
*Directory.svelte*

***

```svelte
<script>
    import Directory from './Directory.svelte';
    import { data } from './data';
</script>

<Directory name='root' files={data} expanded />
```
*FileSystem.svelte*

> In the code above, the **FileSystem** component serves as the entry-point component where the **Directory** component is rendered and data are imported. Within the **Directory** component, the logic for displaying a directory is implemented, with props such as **name**, **files**, and **expanded** being passed. Toggling the expanded state controls the visibility of directory contents, iterating over the files array to render either the **Directory** or **File** component based on the item type. 

> The special element `<svelte:self {...file} />` is utilized within the **Directory** component to allow recursive rendering, enabling the component to render itself with different props based on the data in the files object. Meanwhile, the **File** component focuses on displaying the name of a file received as a prop. Utilizing this special element, simplifies the component's structure and makes the code more readable and maintainable.

***

```svelte
<span>Admin</span>

<style>
    span {
        background-color: red;
        color: gold;
        font-weight: 600;
        height: max-content;
        padding: 0.2em 1em;
        margin: 0.5em;
        border-radius: 0.5em;
    }
</style>
```
*AdminBadge.svelte*

***

```svelte
<span>Moderator</span>

<style>
    span {
        background-color: green;
        color: #fff;
        font-weight: 500;
        height: max-content;
        padding: 0.2em 1em;
        margin: 0.5em;
        border-radius: 0.5em;
    }
</style>
```
*ModeratorBadge.svelte*

***

```svelte
<span>User</span>

<style>
    span {
        background-color: gray;
        color: #fff;
        font-weight: 500;
        height: max-content;
        padding: 0.2em 1em;
        margin: 0.5em;
        border-radius: 0.5em;
    }
</style>
```
*UserBadge.svelte*

***

```svelte
<script>
    import AdminBadge from './badges/AdminBadge.svelte';
    import ModeratorBadge from './badges/ModeratorBadge.svelte';
    import UserBadge from './badges/UserBadge.svelte';

    const badges = [
        { name: 'user', component: UserBadge },
        { name: 'moderator', component: ModeratorBadge },
        { name: 'admin', component: AdminBadge }
    ];

    const formats = ['h4', 'h5', 'h6', 'p'];

    let selectedBadge = badges[0];
    let selectedFormat = formats[0];
</script>

<div>
    <svelte:component this={selectedBadge.component} />

    <svelte:element this={selectedFormat}>
        Username
    </svelte:element>
</div>

<div>
    <!-- Select component -->
    <select bind:value={selectedBadge}>
        {#each badges as badge}
            <option value={badge}>{badge.name}</option>
        {/each}
    </select>

    <!-- Select element -->
    <select bind:value={selectedFormat}>
        {#each formats as format}
            <option value={format}>{format}</option>
        {/each}
    </select>
</div>

<style>
    div {
        display: flex;
        flex-direction: row;
        flex-wrap: nowrap;
        justify-content: center;
        align-items: center;
    }
</style>
```
*Profile.svelte*

> In the code above, a **Profile** component and **3 badge components** are defined. The Profile component displays a badge, which indicates the user role, and a username in a text format. The badge type and text format can be chosen from dropdown menus.

> The `<svelte:component>` and `<svelte:element>` special elements are used to reflect the chosen options in real-time.

> Note that this simple example showcases the real-time switching between components. Typically, in real-world projects, you would not need 3 nearly identical components like in this demonstration.

***

```svelte
<script>
    let show, key, selection;

    const externalCss = 'https://cdnjs.cloudflare.com' + 
        '/ajax/libs/nes.css/2.3.0/css/nes.min.css';
</script>

<svelte:head>
    <link 
        rel='stylesheet' 
        href='https://fonts.googleapis.com/css?family=Gelasio' 
    />

    <link 
        rel='stylesheet' 
        href={externalCss}
    />

    <title>Svelte App</title>
</svelte:head>

<svelte:window
    on:keydown={e => key = e.key}
/>

<svelte:body
    on:mouseenter={() => show = true}
    on:mouseleave={() => show = false}
/>

<svelte:document
    on:selectionchange={() => selection = `${document.getSelection()}`}
/>

<div>
    {#if show}
        <p>Pressed: {key || '--'}</p>
        <p>Selected Text: {selection || '--'}</p>
    {:else}
        <p>Hover over here</p>
    {/if}
</div>

<style>
    div {
        font-family: Gelasio;
        border: 2px solid #000;
        margin: 1em;
        padding: 1em;
    }
</style>
```
*App.svelte*

> In this code example, the special elements `<svelte:head>`, `<svelte:window />`, `<svelte:body />`, and `<svelte:document />` are employed to interact with different parts of the browser environment.

> The `<svelte:head>` element manipulates the document's head by adding external stylesheets, external fonts, and setting the title.

> The `<svelte:window />` element listens for keydown events on the window and updates the **key** variable accordingly.

> `The <svelte:body />` element handles mouseenter and mouseleave events to control the visibility of content based on the **show** variable. 

> Lastly, the `<svelte:document />` element captures selectionchange events on the document, updating the **selection** variable with the currently selected text. 

***

```svelte
<div>
    <slot name='header'>No header provided</slot>
    <p>Content</p>
    <slot name='footer' />
</div>
```
*Widget.svelte*

***

```svelte
<script>
    import Widget from './Widget.svelte';
</script>

<Widget>
    <!-- "slot='header'" is visible on the source code -->
    <h3 slot='header'>Header</h3>

    <!-- "slot='footer'" is not visible on the source code -->
    <svelte:fragment slot='footer'>
        <h4>Footer</h4>
    </svelte:fragment>
</Widget>
```
*Fragment.svelte*

> In the code example above, the **Fragment** component renders a **Widget** component.

> Within the **Widget** component, slots are designated for **header** and **footer** content. The **header** slot is populated with an h3 element displaying the text **"Header"**. Conversely, the **footer** slot contains an h4 element with the text **"Footer"** but is not immediately visible in the source code due to its encapsulation within a `<svelte:fragment />` element.

***

```svelte
<!-- Only one per component allowed -->
<svelte:options 
    immutable
    accessors={false}
/>

<p>Component</p>
```
*Options.svelte*

> In the this code example, the `<svelte:options>` element is used to specify compiler options specific to a component. For instance, setting **immutable**, which is shorthand for `immutable={true}`, indicates that only immutable data is used for direct value change detection through referential equality checks. 

> On the other hand, the default setting of `immutable={false}` means that Svelte takes a cautious approach when assessing changes to mutable objects. 

> Additionally, enabling `accessors={true}` introduces getters and setters for the component's properties, while `accessors={false}` is the default setting for component accessors.

<br />

***

<br />

## Higher-order Components <a href="#hoc" name="hoc"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

A Higher-order Component (HOC) is a component that takes another component as an input and returns a new component with enhanced functionality. This pattern allows for code reusability and composability.

In Svelte, this concept differs from traditional frameworks. Unlike frameworks where HOCs enhance component functionality, Svelte utilizes slots for component composition. Additionally, Svelte introduces the `<svelte:component>` special element for dynamic component rendering based on component definitions. Despite the absence of HOCs in Svelte, similar functionality can be achieved through these alternative mechanisms.

<br />

***

<br />

## Module Context <a href="#module-context"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

A **module-level** script in a component allows for defining variables, functions, and importing external modules that can be shared across all instances of the component. A module-level script is created within the component using the script tag with a `context='module'` attribute. This script runs only once during the component's compilation and is not re-evaluated for each instance. It is beneficial for sharing data or utility functions across multiple instances of the component, such as for API calls. It is worth noting that a module-level script operates in a separate module context from the component's **instance-level** script. 

Anything exported from the module-level script becomes an export from the module itself. The module-level script is executed before the instance-level script, making its variables or functions readily available for use within the instance-level script.

Although the module-level script **does not** directly access the instance-level script, the context API can be utilized to pass essential information from the instance-level script to the module-level script.

```js
export async function fetchData() {
    const data = [1, 2, 3, 4, 5];

    return new Promise((resolve) => {
        setTimeout(() => resolve(data), 2000);
    });
}
```
*api.js*

```svelte
<script context='module'>
    import { getContext, setContext } from 'svelte';
    import { fetchData } from './api';

    const data = await fetchData(); 

    console.log('I will be printed only once');

    export function sharedFunction() {
        return `Hello, ${getContext('name')}`;
    }
</script>

<script>
    export let name;

    setContext('name', name);

    console.log(`Item: ${sharedFunction()}`);
</script>

{#each data as num}
    <p>{num}</p>
{/each}
```
*Item.svelte*

***

```svelte
<script>
    import Item from './Item.svelte';
</script>

<Item name='A' />
<Item name='B' />
<Item name='C' />
```
*List.svelte*

> In the code example above, the **List** component displays **3 instances** of the **Item** component. 

> Each **Item** component comprises 2 script sections. The **module-level** script section, labeled with `context='module'`, imports the **fetchData** function from `api.js` and retrieves data during the component's importation. The **fetchData** function returns a Promise that eventually resolves to an array of numbers after a brief delay. 

> This module-level script runs **only once**, upon the initial rendering of the Item component. Additionally, the message **"I will be printed only once"** is logged to the console.

> Furthermore, a **sharedFunction** is defined. This function accesses the context object to retrieve the value of the **name** prop.

> In the **instance-level** script section, the **name** context is established, and the **sharedFunction** is called.

<br />

***

<br />

## Transitions & Animations <a href="#transitions-animations" name="transitions-animations"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Svelte provides several modules that offer different functionalities for creating dynamic and animated experiences. One of these modules is `svelte/motion`. It exports 2 functions, **tweened** and **spring**. These functions enable the creation of writable stores, which smoothly transition between values over a specified duration when updated or set. This allows for a more visually pleasing and gradual change in the variables.
 
Another module, `svelte/transition`, exports 7 functions, **fade**, **blur**, **fly**, **slide**, **scale**, **draw**, and **crossfade**. These functions are specifically designed to be used with transitions. **Transitions** are visual effects that can be applied to elements, such as fading in or out, sliding in from a direction, or scaling up or down. These functions provide ready-to-use transitions that can be easily applied to elements in your components. 

To control the rate of change over time in these transitions and animations, Svelte provides easing functions. The `svelte/easing` module contains 31 named exports, including a **linear ease** and 3 variants, **in**, **out**, and **inOut**, of **10 different easing** functions. **Easing functions** define how the transition progresses, allowing you to create smooth and natural-looking animations. 

Lastly, the `svelte/animate` module exports a single function that is used for Svelte animations. Animations are more complex than transitions and allow for more advanced effects and interactions.

<br />

***

<br />

## Motion <a href="#motion"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Transitions play a crucial role in animating changes within the DOM elements when data or component state changes. **Tweens** and **springs** are motion techniques used to create smooth and dynamic transitions between different states of a component.

**Tweens**, short for **tweening** or **in-betweening**, refer to the process of generating intermediate frames between 2 keyframes to create the illusion of smooth animation. They smoothly interpolate between 2 states over a specified duration and are ideal for creating linear or easing animations, such as fading in/out, sliding, or scaling elements. You can use the **tweened** function to create a tweened value that transitions smoothly from one state to another. Tweens offer options like **duration**, **delay**, **easing function**, and more. 

**Springs**, on the other hand, provide a more physics-based approach to animation. They simulate the behavior of a physical spring, resulting in a more natural and livelier feel to the animation. Springs are commonly used for effects like bouncing, overshooting, or elastic animations. You can adjust parameters such as stiffness, damping, and mass to control the behavior of the spring animation. Svelte provides the **spring** function for creating spring-based animations.

The choice between tweens and springs depends on the desired effect and the specific behavior you wish to achieve. Both techniques offer customization options to tailor your animations.

```svelte
<script>
    import { cubicOut } from 'svelte/easing';
    import { tweened } from 'svelte/motion';

    const initialValue = 0;
    const step = 0.25;

    // Options for the tweened animation
    const options = {
        delay: 0,      // Time in ms before the tween starts
        duration: 400, // Time in ms or (from, to) => time in ms
        easing: cubicOut
    };

    let progress = initialValue;
    const tweenProgress = tweened(initialValue, options);

    function increase() {
        if (progress !== 1) {
            progress += step;
        }

        if ($tweenProgress < 1) {
            // Returns a promise that resolves when it completes
            tweenProgress.update(n => n + step);
        }
    }

    function reset() {
        progress = 0;

        // Returns a promise that resolves when it completes
        tweenProgress.set(initialValue);
    }
</script>

<div>
    <p>Without tweening:</p>
    <progress value={progress} />
</div>

<div>
    <p>Tweened:</p>
    <progress value={$tweenProgress} />
</div>

<button on:click={increase}>Increase</button>
<button on:click={reset}>Reset</button>

<style>
    div {
        display: flex;
        justify-content: flex-start;
        align-items: center;
        gap: 1em;
        margin-bottom: 1em;
    }

    p {
        width: 8em;
    }

    progress {
        flex: 1;
    }
</style>
```
*TweenProgressBar.svelte*

> In the this code snippet, a tweened animation is implemented using the **tweened** method.  The **progress** variable stores the current value of the animation, which is smoothly updated over time using the **update** method of the **tweened** store. Initially set to 0, this value serves as the starting point of the animation, with customizable aspects like **delay**, **duration**, and **easing function** controlled by the options object.

> The **increase** function responds to the **Increase** button click by incrementing the progress value by **0.25**, ensuring it **does not exceed 1**. 

> By binding the **progress** value to the value attribute of the `progress` element, the progress bar visually reflects the animation's state, smoothly transitioning as the value evolves. This setup allows for a gradual and controlled animation effect.

> Additionally, the presence of a `progress` element **without tweening** provides a direct comparison with the tweened animation, showcasing the difference in visual presentation and smoothness between the 2 approaches.

***

```svelte
<script>
    import { tweened } from 'svelte/motion';

    const initialValue = 100;
    const step = 50;

    const options = {
        delay: 0,       // Time in ms before the tween starts
        duration: 400,  // Time in ms or (from, to) => time in ms
        easing: t => t, // Linear easing
        interpolate: (from, to) => t => from + (to - from) * t
    };

    const tween = tweened(initialValue, options);

    function increase() {
        tween.update(n => n + step);
    }

    function reset() {
        tween.set(initialValue);
    }
</script>

<button on:click={increase}>Increase</button>
<button on:click={reset}>Reset</button>

<div>
    <p style:--size={$tween + 'px'}>
        {$tween} x {$tween}
    </p>
</div>

<style>
    div {
        display: flex;
        margin: 2em;
    }

    p {
        width: var(--size);
        height: var(--size);
        padding: 2em;
        background-color: red;
        color: #fff;
    }
</style>
```
*TweenInterpolationSquare.svelte*

> In this code example, the **tween** variable holds the current value of the animation, which is continuously updated over time through the update method of the **tweened** store. Initially set at **100**, this value serves as the starting point for the animation. The options object contains a custom **interpolation function** that defines how values between the initial and final points are computed throughout the animation. By using this interpolation function, you can precisely manage the transition of values between the start and end points, providing flexibility in defining the animation's behavior.

> When the **Increase** button is clicked, the **increase** function is activated, increasing the **tween** value by **50**. As a result, the width and height of the p element dynamically adjust based on the updated **tween** value, visually representing the changing state of the animation. 

> It is essential to understand that the **easing function** and the **interpolation function** have distinct roles in animations. 

> The **easing function** controls the timing and pace of the animation, determining how the intermediate values progress between the starting and ending points. Easing functions can create various effects such as **linear motion**, **smooth acceleration**, or **bouncing movements**, influencing the **speed** and **smoothness** of the animation to shape the perception of motion.

> In this specific case, a **linear easing function** is utilized to ensure a consistent speed of animation progression. 

> On the other hand, the **interpolation function** calculates the actual values between the start and end points during the animation. By taking the initial value **from** and the target value **to** as inputs, it generates the **interpolated value** based on a specified parameter **t** that represents the animation's progress. This function plays a pivotal role in determining how values transition between the start and end points, contributing to the overall fluidity and visual appeal of the animation.

> The custom interpolation function employs **linear interpolation**, meaning the intermediate values are calculated by linearly scaling between the start and end values. 

> To summarize, the **easing function** manages the **timing and perception of motion**, while the **interpolation function** decides the **actual values between the start and end points** throughout the animation.

***

```svelte
<script>
    import { spring } from 'svelte/motion';

    const initialValue = 100;
    const step = 50;

    const options = {
        stiffiness: 0.5,
        damping: 0.1
    };

    const size = spring(initialValue, options);

    function increase() {
        size.update(n => n + step);
    }

    function reset() {
        size.set(initialValue);
    }
</script>

<button on:click={increase}>Increase</button>
<button on:click={reset}>Reset</button>

<div>
    <p style:--size={$size + 'px'}>
        {$size} x {$size}
    </p>
</div>

<style>
    div {
        display: flex;
        margin: 2em;
    }

    p {
        width: var(--size);
        height: var(--size);
        padding: 2em;
        background-color: red;
        color: #fff;
    }
</style>
```
*SpringSquare.svelte*

> In this code example, the animation is achieved using the **spring** function instead of custom interpolation and easing functions as in the previous code. The **size** variable is defined using the **spring** function with specific **stiffness** and **damping** options.

> **Stiffness** affects the rigidity of the spring animation, while damping controls how quickly the animation settles. Higher stiffness results in quicker changes, while lower stiffness allows for smoother transitions.

> **Damping** determines how rapidly the animation comes to a stop. A higher damping value leads to a faster settling animation with fewer oscillations, while a lower damping value allows for more pronounced movements before stability is reached, creating a more dynamic animation. 

> When the **Increase** button is clicked, the **size** value is updated by adding the **step** value of **50** through the **increase** function. This modification dynamically adjusts the width and height of the p element based on the updated **size** value.

> In summary, this code creates animation effects that mimic a spring-like behavior, offering a different approach compared to manually setting interpolation and easing functions in the previous example.

<br />

***

<br />

## Transition Application <a href="#transition-application"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Svelte provides a **transition:** directive that enables the integration of animations and transitions into elements when they are added, removed, or updated within the DOM. This directive empowers you to specify how an element should transition in and out of the DOM. You have a range of options available to tailor the animation, including parameters like **duration**, **easing**, **delay**, and more. 

The **in:** and **out:** properties of the transition directive are specifically utilized to define the animation to be applied when an element is added or removed from the DOM.

Transitions initiated through the **transition:** directive are **reversible**. This feature ensures that if the element undergoing a transition requires re-transitioning in the opposite direction, the new transition will start from its current position rather than the initial or final points. This capability allows for a smooth adjustment of the transition based on user interactions, enhancing the overall fluidity of the animation process.

#Transition Application
```svelte
<script>
    import { fade, fly } from 'svelte/transition';

    let visible1 = true;
    let visible2 = true;
    let visible3 = true;
</script>

<div>
    <div>
        <label>
            <input type='checkbox' bind:checked={visible1} />
            Make Visible
        </label>
        
        {#if visible1}
            <p transition:fade>
                Fades in and out
            </p>
        {/if}
    </div>
    
    <div>
        <label>
            <input type='checkbox' bind:checked={visible2} />
            Make Visible
        </label>
        
        {#if visible2}
            <!-- 
                "transition" directive with parameters.
                Transition is reversible, 
                  meaning if you toggle the checkbox while
                  the transition is ongoing, 
                  it transitions from the current point.
            -->
            <p transition:fly={{ y: 200, duration: 2000 }}>
                Flies in and out
            </p>
        {/if}
    </div>
    
    <div>
        <label>
            <input type='checkbox' bind:checked={visible3} />
            Make Visible
        </label>
        
        {#if visible3}
            <!-- 
                Different transitions for when the element 
                  is added and removed from the DOM.
            -->
            <p in:fly={{ y: 200, duration: 2000 }} out:fade>
                Flies in and fades out
            </p>
        {/if}
    </div>
</div>

<style>
    div {
        display: flex;
        justify-content: center;
        align-items: center;
        gap: 1em;
    }

    div > div {
        flex-direction: column;
        width: 10em;
        height: 5em;
        padding: 1em;
        border: 2px solid #000;
    }
</style>
```
*TransitionDirectives.svelte*

> In the code example above, 3 boolean variables: **visible1**, **visible2**, **visible3**, are declared and set to **true**. Each variable is bound to a checkbox input, allowing to toggle the visibility of a p element. For each variable, there is a section that is conditionally rendered based on the value of the variable.

> The transitions **fade** and **fly** are utilized to animate the appearance and disappearance of elements when the checkboxes are toggled. When the **transition:** directive is used, the same transition is applied when the element enters or exits the DOM.

> Alternatively, the **in:** and **out:** directives allow for different transitions to be applied in these scenarios. The **fade** transition smoothly fades the element in and out, while the **fly** transition moves the element vertically by 200 pixels over a duration of 2000 milliseconds.

<br />

***

<br />

## Transition Events <a href="#transition-events"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Svelte provides transition events that enable you to monitor specific moments during the transition process, particularly when an element is being added or removed from the DOM. These events can be leveraged to trigger custom logic or execute actions based on the state of the transition.

```svelte
<script>
    import { fly } from 'svelte/transition';

    let visible = true;
    let status;
</script>

<p>Status: {status || '--'}</p>

<label>
    <input type='checkbox' bind:checked={visible} />
    Make Visible
</label>
        
{#if visible}
    <p 
        transition:fly={{ y: 200, duration: 2000 }}
        on:introstart={() => status  = 'Intro started'}
        on:outrostart={() => status  = 'Outro started'}
        on:introend={() => status  = 'Intro ended'}
        on:outroend={() => status  = 'Outro ended'}
    >
        Flies in and out
    </p>
{/if}
```
*TransitionEvents.svelte*

> In the code example above, a boolean variable **visible** and a **status** variable are declared, with visible set to **true**. A p element displays the current status.
A checkbox is linked to the **visible** variable, allowing to toggle the visibility of the p element. Another p element is conditionally rendered based on the value of **visible**.

> When the second p element transitions in or out, event listeners are triggered to update the status variable with corresponding messages indicating the start and end of the intro and outro animations. This setup provides real-time feedback on the transition process.

<br />

***

<br />

## Custom Transitions <a href="#custom-transitions"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Custom transitions for the **transition:**, **in:**, and **out:** directives can be specified using CSS or JavaScript. 

**CSS transitions** involve defining animations through CSS properties such as transition-property, transition-duration, transition-timing-function, among others. These transitions are managed by the browser and offer a seamless way to animate CSS properties. 

On the other hand, **JavaScript transitions** are animations created using JavaScript, providing more intricate control over the animation logic. They enable the development of complex animations beyond the capabilities of CSS transitions. 

CSS transitions are commonly favored for their declarative nature, efficiency, and ease of implementation through the transition directive. However, there are scenarios where custom JavaScript transitions become essential. Custom JavaScript transitions are beneficial for intricate animations that cannot be achieved solely with CSS transitions. JavaScript provides enhanced control and flexibility to dynamically manipulate elements and craft sophisticated animations. When transitions rely on dynamic data or user interactions, custom JavaScript transitions are preferable as they allow for event responsiveness, real-time animation property updates, and condition-based transitions. Furthermore, for advanced or custom timing functions like elastic or bounce effects, JavaScript empowers you to define and integrate them into your animations effectively.

```svelte
<script>
    import { elasticOut } from 'svelte/easing';

    let visible = true;

    function fade(node, { delay = 0, duration = 400 }) {
        const opacity = +getComputedStyle(node).opacity;

        return {
            delay,
            duration,
            css: t => `opacity: ${t * opacity};`
        };
    }

    function spin(_node, { duration }) {
        return {
            duration,
            css: t => {
                const eased = elasticOut(t);

                return `
                    transform: 
                        scale(${eased}) 
                        rotate(${eased * 360}deg);
                    color: red;
                `;
            }
        };
    }
</script>

<label>
    <input type='checkbox' bind:checked={visible} />
    Make Visible
</label>

{#if visible}
    <p 
        in:spin={{ duration: 8000 }}
        out:fade
    >
        Spins in and fades out
    </p>
{/if}
```
*CSS.svelte*

> In this code example, there are 2 transition functions defined: **fade** and **spin**.
 
> The **fade** function adjusts the opacity of an element, gradually fading it in or out over a specified duration. It calculates the opacity based on the current style of the element and returns an object with properties for **delay**, **duration**, and a **css** function to control the opacity. 

> The **spin** function applies a spinning effect to an element by scaling and rotating it based on the progress of the transition. It uses the **elasticOut easing** function to create a smooth animation effect.

> The markup includes a checkbox labeled **Make Visible** that toggles the visibility of a p element based on the value of the **visible** variable. When the checkbox is checked, the p element will enter the DOM with a spinning animation that lasts for 8000 milliseconds and fade out smoothly when hidden. 

***

```svelte
<script>
    let visible = false;

    function typewriter(node, { speed = 1 }) {
        const hasOneChild = node.childNodes.length === 1;
        const isTextChild = node.childNodes[0].nodeType ===
            Node.TEXT_NODE;
        const isValid = hasOneChild && isTextChild;

        if (!isValid) {
            throw new Error(
                'Transition can be applied only to elements' +
                    'with a single text node child'
            );
        }

        const text = node.textContent;
        const duration = text.length / (speed * 0.01);

        return {
            duration,
            tick: t => {
                const idx = Math.trunc(text.length * t);
                node.textContent = text.slice(0,  idx);
            }
        };
    }
</script>

<label>
    <input type='checkbox' bind:checked={visible} />
    Make Visible
</label>

{#if visible}
    <p transition:typewriter>
        Hello, world!
    </p>
{/if}
```
*Javascript.svelte*

> In the code example above, a **typewriter** function accepts a **node** parameter representing the DOM element undergoing the transition. It also has an optional **speed** property. This function retrieves the text content of the **node** and calculates the duration of the transition based on the length of the text and the provided **speed**. It then returns an object containing a **duration** property and a **tick** function.
 
> The **duration** property specifies the total duration of the transition, determining how long it takes for the typewriter effect to complete. 

> The **tick** function is called repeatedly throughout the transition and receives a progress value, denoted as **t**, ranging **from 0 to 1**. Within the **tick** function, the text content of the **node** is updated to display a portion of the original text based on the progress value **t**. This creates the typewriter effect, gradually revealing the text as if it is being typed. 

> By utilizing the **typewriter** function, you can apply the typewriter effect to the text content of a DOM element, with the option to customize the **speed** and **duration**. 

> In the markup, there is a checkbox input that is connected to the **visible** variable. When the checkbox is checked, the **visible** variable is set to true, which triggers the rendering of a p element. This element is associated with the **typewriter** transition function using the `transition:typewriter` directive. When the p element enters the DOM, the **typewriter** transition function is applied, resulting in the text appearing gradually as if it is being typed.

<br />

***

<br />

## Key Blocks <a href="#key-blocks"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Key blocks are essential for triggering transitions when the value of an expression changes. They facilitate dynamic updates to elements, ensuring that transitions occur when values change, rather than when elements are added or removed from the DOM.

```svelte
<script>
    import { onMount } from 'svelte';

    let i = 0;

    onMount(() => {
        const interval = setInterval(() => i++, 5000);
        return () => clearInterval(interval);
    });

    function typewriter(node, { speed = 1 }) {
        const text = node.textContent;
        const duration = text.length / (speed * 0.01);

        return {
            duration,
            tick: t => {
                const idx = Math.trunc(text.length * t);
                node.textContent = text.slice(0,  idx);
            }
        };
    }
</script>

{#key i}
    <p in:typewriter={{ speed: 0.5 }}>
        Key block item {i}
    </p>
{/key}

<p in:typewriter={{ speed: 0.5 }}>
    Item without key block {i}
</p>
```
*KeyBlocks.svelte*

> In this code example, the `{#key}` block is utilized to create a typewriter effect on the p element. By incorporating the `{#key i}` block, Svelte recognizes that the element should be re-rendered whenever the value of i changes. This guarantees that the typewriter effect is applied to each new value of **i**, animating the text content accordingly.

> Without the `{#key}` block, Svelte would consider the content of the element to remain the same, disregarding changes in **i**, and thus preventing the desired typewriter animation from occurring. 

> Both scenarios are presented for comparison.

<br />

***

<br />

## Transition Modifiers <a href="#transition-modifiers"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

In **Svelte 4 and beyond**, transitions behave similarly to CSS, occurring when their **direct containing block** is added or removed. This differs from **Svelte 3**, where transitions were **global** by default, triggering when **any block containing transitions** was added or removed. 

When applying transitions in Svelte 4+, there are 2 variations to consider, **without any modifier** and with the **global modifier**. The first variation aligns with the default behavior of transitions in Svelte 4+, while the global modifier emulates the global transition behavior seen in Svelte 3.
 
In Svelte 3, there were also 2 variations, **without any modifier** and with the **local modifier**. The first variation mirrored the default behavior of transitions in Svelte 3, while the local modifier imitated the global transition behavior found in Svelte 4+.

```svelte
<script>
    import { slide } from 'svelte/transition';

    let items = ['Items 1', 'Items 2', 'Items 3'];
    let visible1 = true;
    let visible2 = true;

    function addItem() {
        items = [
            ...items,
            `Item ${items.length + 1}`
        ];
    }
</script>

<button on:click={addItem}>Add Item</button>

<div>
    <div>
        <label>
            <input type='checkbox' bind:checked={visible1} />
            Make Visible
        </label>
        
        {#if visible1}
            {#each items as item}
                <!-- 
                    In Svelte 4, it applies to a single p element.
                    In Svelte 3, it applies to each p element.
                    To achieve the Svelte 4 behavior in Svelte 3, 
                      use "transition:slide|local". 
                -->
                <p transition:slide>
                    {item}
                </p>
            {/each}
        {/if}
    </div>
    
    <div>
        <label>
            <input type='checkbox' bind:checked={visible2} />
            Make Visible
        </label>
        
        {#if visible2}
            {#each items as item}
                <!-- 
                    In Svelte 4, transition applies to each p element.
                    In Svelte 3, there is no global modifier. 
                -->
                <p transition:slide|global>
                    {item}
                </p>
            {/each}
        {/if}
    </div>
</div>

<style>
    div {
        display: flex;
        justify-content: center;
        align-items: center;
        gap: 1em;
    }

    div > div {
        flex-direction: column;
        padding: 1em;
        border: 2px solid #000;
    }
</style>
```
*TransitionModifiers.svelte*

> In the provided code example, when the transition is applied **globally**, toggling the checkbox will make all items appear or disappear smoothly. The transition effect will be applied to the entire block containing the items, creating a cohesive animation for all items.

> On the other hand, when the transition is applied **locally**, each item will have a smooth transition effect when added or removed. However, the block containing the items will not have a transition effect applied to it as a whole.

> In both cases, adding a new item will trigger the transition for that item.

<br />

***

<br />

## Deferred Transitions  <a href="#deferred-transitions"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Svelte's transition engine offers a useful feature known as deferred transitions, which enables coordination between multiple elements. For instance, there is a pair of todo lists where toggling a todo sends it to the opposite list. Instead of objects abruptly disappearing and reappearing, they smoothly move through a series of intermediate positions. 

To achieve this effect, Svelte provides the **crossfade** function. This function generates 2 transitions called **send** and **receive**. When an element is "sent", it gracefully transforms to its counterpart's position and fades out. Conversely, when an element is "received", it smoothly moves to its new position and fades in. 

```js
import { writable } from 'svelte/store';

export function createTodoStore(initial) {
	let uid = 1;

	const todos = initial.map(({ done, description }) => {
		return {
			id: uid++,
			done,
			description
		};
	});

	const { subscribe, update } = writable(todos);

	return {
		subscribe,
		add: description => {
			const todo = {
				id: uid++,
				done: false,
				description
			};

			update($todos => [...$todos, todo])
		},
		remove: todo => {
			update($todos => $todos.filter(t => t !== todo));
		},
		mark: (todo, done) => {
			update($todos => [
				...$todos.filter(t => t !== todo),
				{ ...todo, done }
			]);
		}
	};
}
```
*todos.js*

***

```js
import { crossfade } from 'svelte/transition';
import { quintOut } from 'svelte/easing';

export const [send, receive] = crossfade({
	duration: d => Math.sqrt(d * 200),

	fallback(node, _params) {
		const style = getComputedStyle(node);
		const transform = 
			style.transform === 'none' 
			? '' 
			: style.transform;

		return {
			duration: 600,
			easing: quintOut,
			css: t => `
				transform: ${transform} scale(${t});
				opacity: ${t}
			`
		};
	}
});
```
*transition.js*

***

```svelte
<script>
	import { send, receive } from './transition.js';

	export let store, done;
</script>

<ul>
	{#each $store.filter(todo => todo.done === done) as todo (todo.id)}
		<li
			class:done
			in:receive={{ key: todo.id }}
			out:send={{ key: todo.id }}
		>
			<label>
				<input
					type='checkbox'
					checked={todo.done}
					on:change={
						e => store.mark(todo, e.currentTarget.checked)
					}
				/>

				<span>{todo.description}</span>
				
                <button on:click={() => store.remove(todo)}>
                    Remove
                </button>
			</label>
		</li>
	{/each}
</ul>

<style>
    ul {
        padding: 0;
    }

    li {
        list-style: none;
        display: flex;
        align-items: center;
    }

	label {
		width: 90%;
		display: inline;
	}

	span {
		flex: 1;
	}

	button {
		margin-top: 0.5em;
        cursor: pointer;
	}
</style>
```
*TodoList.svelte*

***

```svelte
<script>
	import { createTodoStore } from './todos.js';
	import TodoList from './TodoList.svelte';

	const todos = createTodoStore([
		{ done: false, description: 'Todo 1' },
		{ done: false, description: 'Todo 2' },
		{ done: true, description: 'Todo 3' },
		{ done: false, description: 'Todo 4' },
		{ done: false, description: 'Todo 5' },
		{ done: false, description: 'Todo 6' }
	]);
</script>

<div class='board'>
	<input
		placeholder='What needs to be done?'
		on:keydown={(e) => {
			if (e.key !== 'Enter') return;

			todos.add(e.currentTarget.value);
			e.currentTarget.value = '';
		}}
	/>

	<div class='todo'>
		<h2>Todo</h2>
		<TodoList store={todos} done={false} />
	</div>

	<div class='done'>
		<h2>Done</h2>
		<TodoList store={todos} done={true} />
	</div>
</div>

<style>
	.board {
		display: grid;
		grid-template-columns: 1fr 1fr;
		grid-column-gap: 1em;
		max-width: 36em;
		margin: auto;
	}

	.board > input {
		font-size: 1em;
		grid-column: 1/3;
		padding: 0.5em;
		margin: 0 0 1rem 0;
	}

	h2 {
		font-size: 2em;
		font-weight: 200;
	}
</style>
```
*DeferredList.svelte*

> In the example code above, the **TodoList** component represents a list of todos, with each todo item rendered as an li element. The component includes a **send** function responsible for handling the transition of a todo item from one list to another. 

> When invoked, the **send** function accepts 2 arguments, the **todo** object representing the specific item and the **list** representing the target list. Within the **send** function, a transition is triggered using the **crossfade** function. This **crossfade** function takes 3 arguments, the **element** to transition, the **target position**, and an optional **configuration** object. It returns a promise that resolves once the transition is complete.
 
> In this case, the **crossfade** function smoothly transitions the todo item to its new position and fades it out when sent to the opposite list.

> When a todo item is toggled, the **send** function is invoked. 

> This function examines the list argument to determine the target list and utilizes the **crossfade** function to transition the todo item accordingly, providing a visually appealing effect as items move between the **Todo** and **Done**.

<br />

***

<br />

## Animate Directive <a href="#animate-directive"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

To ensure a seamless experience and enhance the overall illusion, it is crucial to incorporate motion into elements that are not currently undergoing transitions. This can be accomplished by using the animate directive. Svelte offers a convenient flip animation function, which can be utilized when you wish to add animations to a list of items that are being reordered. The **animate:** directive plays a key role in applying these animations to the elements.

```js
import { writable } from 'svelte/store';

export function createTodoStore(initial) {
	let uid = 1;

	const todos = initial.map(({ done, description }) => {
		return {
			id: uid++,
			done,
			description
		};
	});

	const { subscribe, update } = writable(todos);

	return {
		subscribe,
		add: description => {
			const todo = {
				id: uid++,
				done: false,
				description
			};

			update($todos => [...$todos, todo])
		},
		remove: todo => {
			update($todos => $todos.filter(t => t !== todo));
		},
		mark: (todo, done) => {
			update($todos => [
				...$todos.filter(t => t !== todo),
				{ ...todo, done }
			]);
		}
	};
}
```
*todos.js*

***

```js
import { crossfade } from 'svelte/transition';
import { quintOut } from 'svelte/easing';

export const [send, receive] = crossfade({
	duration: d => Math.sqrt(d * 200),

	fallback(node, _params) {
		const style = getComputedStyle(node);
		const transform = 
			style.transform === 'none' 
			? '' 
			: style.transform;

		return {
			duration: 600,
			easing: quintOut,
			css: t => `
				transform: ${transform} scale(${t});
				opacity: ${t}
			`
		};
	}
});
```
*transition.js*

***

```svelte
<script>
    import { flip } from 'svelte/animate';
	import { send, receive } from './transition.js';

	export let store, done;
</script>

<ul>
	{#each $store.filter(todo => todo.done === done) as todo (todo.id)}
		<li
			class:done
			in:receive={{ key: todo.id }}
			out:send={{ key: todo.id }}
			animate:flip={{ duration: 200 }}
		>
			<label>
				<input
					type='checkbox'
					checked={todo.done}
					on:change={
						e => store.mark(todo, e.currentTarget.checked)
					}
				/>

				<span>{todo.description}</span>
				
                <button on:click={() => store.remove(todo)}>
                    Remove
                </button>
			</label>
		</li>
	{/each}
</ul>

<style>
    ul {
        padding: 0;
    }

    li {
        list-style: none;
        display: flex;
        align-items: center;
    }

	label {
		width: 90%;
		display: inline;
	}

	span {
		flex: 1;
	}

	button {
		margin-top: 0.5em;
        cursor: pointer;
	}
</style>
```
*TodoList.svelte*

***

```svelte
<script>
	import { createTodoStore } from './todos.js';
	import TodoList from './TodoList.svelte';

	const todos = createTodoStore([
		{ done: false, description: 'Todo 1' },
		{ done: false, description: 'Todo 2' },
		{ done: true, description: 'Todo 3' },
		{ done: false, description: 'Todo 4' },
		{ done: false, description: 'Todo 5' },
		{ done: false, description: 'Todo 6' }
	]);
</script>

<div class='board'>
	<input
		placeholder='What needs to be done?'
		on:keydown={(e) => {
			if (e.key !== 'Enter') return;

			todos.add(e.currentTarget.value);
			e.currentTarget.value = '';
		}}
	/>

	<div class='todo'>
		<h2>Todo</h2>
		<TodoList store={todos} done={false} />
	</div>

	<div class='done'>
		<h2>Done</h2>
		<TodoList store={todos} done={true} />
	</div>
</div>

<style>
	.board {
		display: grid;
		grid-template-columns: 1fr 1fr;
		grid-column-gap: 1em;
		max-width: 36em;
		margin: auto;
	}

	.board > input {
		font-size: 1em;
		grid-column: 1/3;
		padding: 0.5em;
		margin: 0 0 1rem 0;
	}

	h2 {
		font-size: 2em;
		font-weight: 200;
	}
</style>
```
*AnimationList.svelte*

> In this example, the **TodoList** component from the **deferred transition example** is changed to include the **flip** animation. 

> **FLIP**, which stands for **First, Last, Invert, Play**, is a technique used to create seamless animations. It involves defining the initial and final states of an element, determining the changes that occur between them, inverting those changes, and then playing the animation by transitioning from the inverted state to the final state. By applying transforms and opacity changes in reverse, the elements appear as if they are still in the initial position. This technique is especially beneficial when responding to user interactions and animating elements accordingly.

<br />

***

<br />

## Actions <a href="#actions"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Actions act as functions that enable direct interaction with the DOM or facilitate side effects within components. They are commonly used for tasks such as manipulating elements, handling events, or integrating with external libraries. Although actions are not extensively employed, they provide a way to execute a function when an element is added to the DOM. In essence, actions can be seen as lifecycle hooks for individual DOM elements, like onMount or onDestroy, but tied specifically to the elements themselves rather than the entire components. 

To define an action, you can specify the DOM element as a parameter, along with any optional parameters you may need. 
The action function can then perform initialization logic on the element and optionally return an object that contains update and destroy handlers. These handlers allow you to manage any updates or clean-up operations related to the action. 

To apply an action to a specific element, the **use:** directive is used.

```js
export function resizeAction(node) {
    // node has been mounted
    function handleResize() {
        const { width, height } = node.style;

        if (!width || !height) {
            node.textContent = 'Resize Me';
            return;
        }

        node.textContent = `${width} x ${height}`;
    }

    const resizeObs = new ResizeObserver(handleResize);
    resizeObs.observe(node);
    node.textContent = 'Initial value';

    return {
        update: bgColor => {
            /** 
             * Resizing will not trigger this method, 
             *  only parameter changes.
             */
            node.style.backgroundColor = bgColor;
            console.log('Element parameter updated');
        },
        destroy: () => {
            /**
             * Node has been removed from the DOM, 
             *  setting node.textContent will not have any effect.
             */
            resizeObs.disconnect();
            console.log('Element destroyed');
        }
    }
}
```
*actions.js*

***

```svelte
<script>
    // @ts-nocheck
    import { resizeAction } from './actions';

    let visible = true;
    let bgColor;
</script>

<label>
    <input type='checkbox' bind:checked={visible} />
    Make Visible
</label>

<label>
    Background Color:
    <input type='color' bind:value={bgColor} />
</label>

{#if visible}
    <div use:resizeAction={bgColor}></div>
{/if}

<style>
    div {
        border: 2px solid #000;
        resize: both;
        overflow: auto;
    }
</style>
```
*ResizableRectangle.svelte*

> In the code example above, the component controls the visibility and background color of a resizable div element. It achieves this by utilizing the **resizeAction** function from the `actions.js` file, which handles resizing events. 

> The component includes a checkbox that allows to toggle the visibility of the div element, as well as a color input that enables the change of the div's background color. When the checkbox is checked, the div element is displayed and the **resizeAction** function is applied as a **Svelte action**.
 
> This function leverages the **ResizeObserver API** to track resize events and update the div's text content with its current width and height. Additionally, the component provides an **update** function that allows users to modify the background color, and a **destroy** function that disconnects the **ResizeObserver** when the div is removed from the DOM.

<br />

***

<br />

## CSS Preprocessor Integration <a name="css-preprocessors" href="#css-preprocessors"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

> CSS preprocessors like **SCSS/SASS**, **LESS**, and **Stylus** offer developers powerful tools to enhance their CSS workflow. 

> **SCSS/SASS** provide features such as variables, nesting, mixins, and functions, making CSS code more maintainable. **LESS**, another popular preprocessor, offers similar capabilities to SCSS/SASS but with a slightly different syntax. 

> **Stylus**, known for its minimalistic approach, focuses on simplicity and flexibility, using indentation-based syntax for concise and expressive code.

To integrate any of these preprocessors, install the compiler and indicate the preprocessor language in the component **style section** using the `lang` attribute, or **import** a preprocessor style file in the **script section**. This setup should seamlessly enable the preprocessor to function without the need for additional configuration steps.

Using a CSS preprocessor with Svelte can introduce additional complexity, potentially making your code harder to manage. It is important to consider whether the benefits of using a preprocessor outweigh the added complexity it may bring to your development process. 

```console
# SCSS/SASS
npm install -D sass

# LESS
npm install -D less

# Stylus:
npm install -D stylus
```
*Install CSS preprocessor*

***

```svelte
<script>
    // Import style file
    import './styles.scss';
    import './styles.sass';
    import './styles.less';
    import './styles.styl';
</script>

<!-- OR write component styles -->
<!-- Note, only one <style> tag per component is allowed -->
<style lang='scss'></style>
<style lang='sass'></style>
<style lang='less'></style>
<style lang='styl'></style>
<style lang='stylus'></style>
```
*Component.svelte*

<br />

***

<br />

## Tailwind CSS Integration <a name="tailwind-integration" href="#tailwind-integration"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

> **Tailwind CSS** is a utility-first CSS framework that sets itself apart from traditional frameworks by not offering pre-designed components. Instead, it provides a range of CSS utility classes that empower you to efficiently develop custom designs without being constrained by generic prebuilt components.

To integrate Tailwind CSS into a Svelte project, start by running `npm install -D tailwindcss postcss autoprefixer` in the terminal. 

**PostCSS** is a CSS transformation tool that operates with various plugins, with **Autoprefixer** being a plugin designed to automate the process of adding vendor prefixes to CSS code. These packages are typically required when integrating **Tailwind** into a project without utilizing the **Tailwind CLI**. Given that **Tailwind CSS** does not inherently support vendor prefixing, it is recommended to include **Autoprefixer** in the setup. **Autoprefixer** tracks **caniuse.com** for CSS properties that need prefixes to maintain consistent display across various browsers.

After installing the development dependencies, initialize Tailwind CSS by running `npx tailwindcss init -p` in the terminal. This command initializes Tailwind CSS and generates a **tailwind.config.js** file along with a postcss.config.js, allowing you to customize Tailwind's and PostCSS's configuration settings. 

In the **tailwind.config.js** file, add the `purge` option to eliminate unused CSS by specifying the relevant files.
```js
...
purge: ['./index.html', './src/**/*.{svelte,js,ts}'],
...
```
*tailwind.config.js*

In the **postcss.config.js** file, import **tailwindcss**, the **tailwind.config.js** file, and **autoprefixer**, and set up the plugins accordingly. 
```js
import tailwind from 'tailwindcss';
import tailwindConfig from './tailwind.config.js';
import autoprefixer from 'autoprefixer';

export default {
    plugins: [tailwind(tailwindConfig), autoprefixer]
};
```
*postcss.config.js*

Once these steps have been finished, the setup should be considered successful. To make use of Tailwind CSS, you can incorporate the Tailwind CSS styles in Svelte components **within the component's style section**. 
```svelte
<style>
    @tailwind base;
    @tailwind components;
    @tailwind utilities;
</style>
```
*Component.svelte*

Alternatively, they can be included in a **global CSS file**, which can then be imported in **main.js/main.ts**.
```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```
*app.css*

***

```js
import './app.css'
import App from './App.svelte'

const app = new App({
  target: document.getElementById('app'),
})

export default app
```
*main.js*

<br />

***

<br />

## Lazy Loading <a href="#lazy-loading"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Lazy loading is a technique that involves loading resources only when they are needed, rather than loading all resources at once when the page initially loads. This approach can help reduce the initial load time of a webpage by loading only the necessary resources first, with additional resources loading as the user interacts with the page. Lazy loading can be applied to components, images, and everything else that can be loaded on demand. 

One practical application of lazy loading is utilizing the **Intersection Observer API**, which allows you to respond to the intersection between the browser's viewport and an HTML element. **Viewport** refers to the visible area of a web page to the user, without requiring scrolling or zooming. By detecting when a user is about to interact with a resource, you can effectively implement lazy loading.

```svelte
<script>
    import { onMount } from 'svelte'

    let container = null;
    let isIntersecting = false;

    onMount(() => {
        const observer = new IntersectionObserver(entries => {
            entries.forEach(entry => {
                isIntersecting = entry.isIntersecting;
            });
        });

        observer.observe(container);
    });
</script>

<div bind:this={container}>
    {#if isIntersecting}
        <slot></slot>
    {/if}
</div>
```
*GenericLazyLoader.svelte*

***

```svelte
<script>
    import { onMount } from 'svelte';

    let message;

    onMount(() => {
        setTimeout(
            () => message = 'Hello, world',
            3000
        );
    });
</script>

<p>{message || 'Loading...'}</p>
```
*Component.svelte*

***

```svelte
<script>
    import Component from './Component.svelte';
    import GenericLazyLoader from './GenericLazyLoader.svelte';
</script>

<!-- 
    A substantial amount of text that 
      extends the page for scrolling.
-->

<GenericLazyLoader>
    <Component />
</GenericLazyLoader>

<GenericLazyLoader>
    <!-- svelte-ignore a11y-missing-attribute -->
    <img src='https://picsum.photos/200' />
</GenericLazyLoader>
```
*LazyLoading.svelte*

> In the code example above, 3 components are defined: **GenericLazyLoader**, **Component**, and **LazyLoading**, with LazyLoading serving as the entry-point.

> The **GenericLazyLoader** component implements lazy loading using the **Intersection Observer API** to determine when its content should be displayed. 

> The **Component** component renders a delayed message within a p element after 3 seconds. 

> The **LazyLoading** component acts as the main component, importing the other 2 components and managing the lazy loading of both the **Component** and an **image** within **GenericLazyLoader**.

> This setup ensures that components and images are loaded only when they are about to become visible in the viewport. The message in the **Component** will be displayed after a 3-second delay once it becomes visible on the page.

<br />

***

<br />

## Consuming APIs <a href="#consuming-apis"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

When it comes to consuming REST and GraphQL APIs, there is a variety of options available. For **REST APIs**, tools like the **Fetch API** or **HTTP clients such as Axios** are commonly used for handling HTTP requests. When working with **GraphQL APIs**, you can choose to utilize the **Fetch API** or the **Apollo Client library**. 

Integrating API calls **within the onMount** lifecycle function enables data retrieval when the component is loaded. Another method involves using **module context** to access data that can be shared across all instances of the component. Employing **{#await} blocks** is valuable for effectively managing asynchronous operations. Triggering API requests through **event handlers** offers a user-centric approach to fetching data.

Storing API responses in a **store** not only ensures state persistence across component remounts but also helps maintain smooth data management processes.

<br />

***

<br />

## Forms & Validation <a href="#forms-validation" name="forms-validation"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

In Svelte, you can easily handle form inputs, validation, and submission using reactive variables and event handlers. To implement form validation, you can track form field values with reactive variables and use conditional logic to check for errors based on validation rules. Error messages can be displayed based on validation results. Additionally, you can prevent the default form submission behavior and handle form submission asynchronously, validating inputs before submitting data. Svelte's reactivity makes it straightforward to update the UI based on user input and validation results, providing a seamless user experience.

```js
import { writable } from 'svelte/store';

export const isLoggedIn = writable(false);

export const userDetails = writable({});
```
*user.js*

***

```svelte
<script>
    import { isLoggedIn, userDetails } from './user';

    let values = {};
	let errors = {};

    async function register(data) {
        // Send data to server

        return new Promise(resolve => {
            setTimeout(
                () => {
                    isLoggedIn.set(true);
                    userDetails.set(data);
                    resolve();
                }, 
                1000
            );
        });
    }

    async function submitHandler() {
        // Implement validation
        // Use a validation library like Yup or Zod

        const { email, password } = values;
        let submit = true;

        if (!email) {
            errors.email = 'Email is required';
            values.email = '';
            submit = false;
        }

        if (email && !email.includes('@')) {
            errors.email = 'Invalid email format';
            values.email = '';
            submit = false;
        }

        if (!password) {
            errors.password = 'Password is required';
            values.password = '';
            submit = false;
        }

        if (password && password.length < 8) {
            errors.password = 'Password must have ' + 
                'at least 8 characters';
            values.password = '';
            submit = false;
        }
        
        if (!submit) return;

        errors = {};
        await register(values);
    }
</script>

<form on:submit|preventDefault={submitHandler}>
    <h2>Register</h2>

	<div>
	    <input 
                type='text' 
                name='email' 
                bind:value={values.email} 
                placeholder='Email' 
            />

            {#if errors.email}
                <span>{errors.email}</span>
            {/if}
	</div>

	<div>
	    <input 
                type='password' 
                name='password' 
                bind:value={values.password} 
                placeholder='Password' 
            />

            {#if errors.password}
                <span>{errors.password}</span>
            {/if}
	</div>

	<button type='submit'>Register</button>
</form>

<style>
    form {
        width: 50%;
        border: 2px dashed #000;
        display: flex;
        flex-direction: column;
        gap: 1em;
        justify-content: center;
        align-items: center;
    }

    input {
        width: 20em;
        display: block;
        padding: 0.5em;
    }

    button {
        margin: 1em;
    }

    span {
        display: block;
        color: red;
        margin-top: 0.2em;
        margin-left: 0.2em;
    }
</style>
```
*Register.svelte*

***

```svelte
<script>
    import { isLoggedIn, userDetails } from './user';

    function logout() {
        $isLoggedIn = false;
        $userDetails = {};
    }
</script>

{#if $isLoggedIn}
    <p>Email: {$userDetails?.email}</p>
    <button on:click={logout}>Logout</button>
{/if}
```
*Profile.svelte*

***

```svelte
<script>
    import Profile from './Profile.svelte';
    import Register from './Register.svelte';
    import { isLoggedIn } from './user';
</script>

{#if $isLoggedIn}
    <Profile />
{:else}
    <Register />
{/if}
```
*App.svelte*

> This code example showcases a simple user authentication system in a Svelte application. 

> In the **App** component, which is the main component, users are directed to either the **Profile** or **Register** component based on their login status.

> The **Register** component manages a form, validating user inputs, and simulating the registration process.

> The **Profile** component displays the user's email and provides a logout option. 

> The `user.js` file contains Svelte writable stores for tracking login status and storing user details. 

<br />

***

<br />

## Documenting <a href="#documenting"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

You can document your components by using specially formatted comments in editors that support the **Svelte Language Server**. Within the markup section of a component, the `@component` tag inside an HTML comment can be utilized to describe the component. This documentation will be displayed when you hover over the component element. **Markdown** formatting can be used within the documentation comment to offer clear and structured information about the component, including usage examples and code blocks. Following this format enables you to efficiently document your Svelte components for improved comprehension and maintenance.

![User.svelte](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b9hdqheqt809abuuqr3y.png)
*User.svelte*

***

```svelte
<script>
    import User from "./User.svelte";
</script>

<!-- Hover over "User" -->
<User username='admin' />
```
*HoverComment.svelte*

***

![Hovering over <User /> on VSCode](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vn4bejcctj11k0tovmf0.png)
*Hovering over `<User />` on VSCode*

<br />

***

<br />

## Debugging <a href="#debugging"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Using `console.log()` within the script section of a Svelte component is an effective way to log information to the console for debugging purposes. Additionally, by including the `{@debug}` tag in the markup, you can pause execution and inspect specific values directly in the browser's developer tools. These methods are practical for debugging and enhancing your understanding of the data flow within components.

> The following example code demonstrates `{@debug}`: 

```svelte
<script>
    const user = {
        firstName: 'John',
        lastName: 'Doe',
        location: {
            country: 'France',
            city: 'Paris'
        }
    };
</script>

<input bind:value={user.firstName} />
<input bind:value={user.lastName} />
<input bind:value={user.location.country} />
<input bind:value={user.location.city} />

{#if user}
    {@const { firstName, lastName, location } = user}
    {@const { country, city } = location}
    <p>{firstName} {lastName} from {city}, {country}</p>
{/if}

{@debug user}
```
*Debug.svelte*

<br />

***

<br />

## Testing <a href="#testing"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

In a Svelte application, there are typically 3 main types of tests, unit tests, component tests, and end-to-end (e2e) tests.

**Unit tests** focus on validating the business logic in isolation, checking individual functions and edge cases. **Component tests** ensure that a component behaves as expected throughout its lifecycle. To test components, a tool providing a Document Object Model (DOM) is necessary. **End-to-end tests** are essential for testing the application as a whole, replicating user interactions in a production-like environment. These tests interact with a deployed version of the application to simulate user behavior.

For unit testing, you can utilize **Vitest**. When it comes to component testing, combining **Vitest with svelte-testing-library** is recommended. The svelte-testing-library offers utilities for testing Svelte components in a way that mirrors user interactions. For e2e testing, consider using **Playwright** or **Cypress** to simulate user interactions across your application.

For more detailed information on how to setup testing, check [this post](https://dev.to/davipon/test-svelte-component-using-vitest-playwright-3o2o).

<br />

***

<br />

## Routing <a href="#routing"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Routing refers to the process of determining how the application's UI should change in response to a change in the URL. It enables navigation between different pages or views without the need for a full page reload. 

In Svelte, routing can be implemented using a routing library like svelte-routing or by manually managing the application state based on the URL. The **svelte-routing library** provides a declarative way to define routes and their corresponding components, making it easier to handle navigation within the application. To implement routing using svelte-routing, you would typically define routes using the Route component, specify the path and component to render for each route, and include a Router component to handle the routing logic. When a user navigates to a specific URL, the corresponding component defined in the route configuration will be rendered in the application.

For more information and examples about svelte-routing, visit [this GitHub repository](https://github.com/EmilTholin/svelte-routing).

```svelte
<script>
    function navigate() {
        window.location = '/#page';
    }
</script>

<p>Home</p>
<button on:click={navigate}>Go to Page</button>
```
*Home.svelte*

***

```svelte
<script>
    function navigate() {
        window.location = '/#';
    }
</script>

<p>Page</p>
<button on:click={navigate}>Go to Home</button>
```
*Page.svelte*

***

```svelte
<script>
    function navigate() {
        window.location = '/#';
    }
</script>

<p>404 - Page Not Found</p>
<button on:click={navigate}>Go to Home</button>
```
*404.svelte*

***

```svelte
<script>
    import { onMount } from 'svelte';
    import Error404 from './components/404.svelte';
    import Home from './components/Home.svelte';
    import Page from './components/Page.svelte';

    const routes = {
        '/': Home,
        'page': Page,
        '*': Error404
    };

    let currentRoute = '';

    function handleRoute() {
        const { hash } = window.location;
        currentRoute = hash ? hash.slice(1) : '/';
    }

    onMount(() => {
        handleRoute();
        window.addEventListener('hashchange', handleRoute);
    });

    $: Component = routes[currentRoute] || routes['*'];
</script>

<svelte:component this={Component} />
```
*Router.svelte*

***

```svelte
<script>
    import Router from './Router.svelte';
</script>

<Router />
```
*App.svelte*

> In the code example above, a simple SPA is implemented built using a custom **Router** component to navigate between components. The **Router** component defines the routing logic for the application. It sets up different routes mapping to specific components like **Home**, **Page**, and **Error404**. The current route is determined based on the hash part of the URL, and a listener is added to handle changes in the hash part.

> The **Home**, **Page**, and **404** components contain simple components with some text and a button. When the button is clicked, it triggers a function that changes the hash part of the URL, simulating navigation within the SPA. If the route does not exist, the **404** component is rendered.

> Overall, this example allows for basic client-side routing in a Svelte application.

<br />

***

<br />

## Typescript Limitations <a href="#ts-limitations" name="ts-limitations"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

When using TypeScript in a Svelte application, there are certain limitations to be aware of TypeScript usage directly within the markup is restricted, meaning that type declarations and assertions are invalid within the markup section. Additionally, trying to incorporate TypeScript syntax directly into reactive declarations by adding type declarations will not work as expected. To address this, it is advised to define variables with types independently before incorporating them into reactive declarations for proper functionality.

<br />

***

<br />

## Deploying <a href="#deploying"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

Deploying a Svelte application involves choosing a hosting provider that supports static sites or Node.js, setting up the hosting environment, and uploading the project. Well-known hosting providers such as **Netlify**, **Vercel**, **Heroku**, and **AWS** are favored options due to their tailored services for hosting Svelte applications effortlessly. These platforms offer efficient deployment procedures, scalability features, and additional tools to facilitate the seamless deployment and maintenance.

<br />

***

<br />

## Runes <a href="#runes"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

**Svelte 5**, currently in development and not yet available for production use, introduces runes as a set of primitives that help manage reactivity within components. **Runes** are symbol-like functions that provide instructions to the Svelte compiler, enabling the declaration of reactive state, derived state, and side effects.

For reactive state declarations, the `$state` rune ensures deep reactivity for objects and arrays. There is also the `$state.frozen` rune, designed for state that remains immutable, offering enhanced performance especially with large arrays or objects. Moreover, the `$derived` rune serves for derived state, while the `$effect` rune allows for executing side effects based on specific value changes.

The introduction of these features in Svelte 5 will provide developers with enhanced control over reactivity management within their components. For more detailed information and updates, visit [this link](https://svelte-5-preview.vercel.app/docs/runes).

<br />

***

<br />

## Conclusion <a href="#conclusion"></a> 
[<a href="#table-of-contents">Back to top ↑</a>]

In conclusion, this tutorial has provided a comprehensive overview of Svelte 4, covering a wide range of topics from project setup to advanced concepts like data binding, state management, and transitions.

While this tutorial does not include coverage of SvelteKit, the knowledge and skills acquired here serve as a valuable resource for developers looking to leverage the power and efficiency of Svelte in their projects. 

As you begin your exploration of Svelte, may the insights shared in this tutorial help you in developing dynamic, responsive, and efficient web applications effortlessly.