Add date on recipes (#441)

* Add date on recipes

* Use Intl.DateTimeFormat instead of date-fns lib
This commit is contained in:
MacFJA
2023-11-12 12:57:42 +01:00
committed by GitHub
parent 88b0e005f5
commit 1cb43b2239
26 changed files with 77 additions and 41 deletions

View File

@@ -6,6 +6,8 @@
import Seo from '$lib/components/Seo.svelte'; import Seo from '$lib/components/Seo.svelte';
export let title; export let title;
export let published;
export let updated;
</script> </script>
<Seo {title} /> <Seo {title} />
@@ -30,6 +32,18 @@
<article> <article>
<h1>{title}</h1> <h1>{title}</h1>
<slot /> <slot />
{#if published}<footer>
<div>
Published: <time datetime={published}
>{new Intl.DateTimeFormat([], { dateStyle: 'full' }).format(new Date(published))}</time
>
</div>
{#if updated}<div>
Last update: <time datetime={updated}
>{new Intl.DateTimeFormat([], { dateStyle: 'full' }).format(new Date(updated))}</time
>
</div>{/if}
</footer>{/if}
</article> </article>
</main> </main>
@@ -40,6 +54,16 @@
align-content: flex-start; align-content: flex-start;
} }
article > footer {
margin-top: 1em;
border-top: 1px solid var(--gray);
padding-top: 1em;
}
time {
color: var(--dark-gray);
}
strong { strong {
font-size: var(--font-500); font-size: var(--font-500);
} }

View File

@@ -7,6 +7,8 @@
const childrenNodes = $categories.find((c) => c.path === $page.url.pathname).children || []; const childrenNodes = $categories.find((c) => c.path === $page.url.pathname).children || [];
export let title; export let title;
export let published;
export let updated;
</script> </script>
<Seo {title} /> <Seo {title} />
@@ -34,6 +36,18 @@
</li> </li>
{/each} {/each}
</ul> </ul>
{#if published}<footer>
<div>
Published: <time datetime={published}
>{new Intl.DateTimeFormat([], { dateStyle: 'full' }).format(new Date(published))}</time
>
</div>
{#if updated}<div>
Last update: <time datetime={updated}
>{new Intl.DateTimeFormat([], { dateStyle: 'full' }).format(new Date(updated))}</time
>
</div>{/if}
</footer>{/if}
</article> </article>
</main> </main>
@@ -43,7 +57,15 @@
grid-template-columns: minmax(0, 1fr); grid-template-columns: minmax(0, 1fr);
align-content: flex-start; align-content: flex-start;
} }
article > footer {
margin-top: 1em;
border-top: 1px solid var(--gray);
padding-top: 1em;
}
time {
color: var(--dark-gray);
}
strong { strong {
font-size: var(--font-500); font-size: var(--font-500);
} }

View File

@@ -1,6 +1,7 @@
--- ---
title: Transpiling ES6 to ES5 for Legacy Browser (IE11) Support with Babel title: Transpiling ES6 to ES5 for Legacy Browser (IE11) Support with Babel
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
--- ---
Svelte outputs modern JavaScript, therefore for legacy browser support, you need to transpile this output back to ES5 (or older). The main strategy people adopt is having 2 builds: Svelte outputs modern JavaScript, therefore for legacy browser support, you need to transpile this output back to ES5 (or older). The main strategy people adopt is having 2 builds:

View File

@@ -1,6 +1,7 @@
--- ---
title: Using Future JS Syntax in Svelte with Babel title: Using Future JS Syntax in Svelte with Babel
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
--- ---
The other, less common but still handy usecase for Babel with Svelte is transpiling _future_ syntax inside `<script>` tags. For example, the [Stage 3 Optional Chaining proposal](https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining) is popular, but not yet in browsers, and more relevantly, is not yet understood by [Acorn](https://github.com/acornjs/acorn), which is what Svelte uses to parse `<script>` tags. The other, less common but still handy usecase for Babel with Svelte is transpiling _future_ syntax inside `<script>` tags. For example, the [Stage 3 Optional Chaining proposal](https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining) is popular, but not yet in browsers, and more relevantly, is not yet understood by [Acorn](https://github.com/acornjs/acorn), which is what Svelte uses to parse `<script>` tags.
@@ -23,7 +24,6 @@ Example usage:
<main> <main>
<h1>Hello {sub}!</h1> <h1>Hello {sub}!</h1>
</main> </main>
``` ```
When we try to run this, Acorn throws a `ParseError: Unexpected token` error. When we try to run this, Acorn throws a `ParseError: Unexpected token` error.

View File

@@ -1,6 +1,7 @@
--- ---
title: Using PostCSS with Svelte title: Using PostCSS with Svelte
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
--- ---
**Option 1 - Write your own** **Option 1 - Write your own**
@@ -76,7 +77,6 @@ and you can write SCSS/SASS in your Svelte template:
color: $color; color: $color;
} }
</style> </style>
``` ```
The same is true for PostCSS as well, which also applies to any PostCSS plugins, like TailwindCSS (see [Tailwind demo here](https://github.com/tailwindcss/setup-examples/tree/master/examples/sapper)). The same is true for PostCSS as well, which also applies to any PostCSS plugins, like TailwindCSS (see [Tailwind demo here](https://github.com/tailwindcss/setup-examples/tree/master/examples/sapper)).

View File

@@ -1,6 +1,8 @@
--- ---
title: Using TypeScript with Svelte title: Using TypeScript with Svelte
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
updated: 2022-09-13T16:29:38+02:00
--- ---
**It is a common misconception that Svelte doesn't work with TypeScript**. Svelte is, of course, written in TypeScript, so the project strongly believes in the value of typing. An [offical blog post](https://svelte.dev/blog/svelte-and-typescript) announced full support for it in mid 2020. Here is how to get started: **It is a common misconception that Svelte doesn't work with TypeScript**. Svelte is, of course, written in TypeScript, so the project strongly believes in the value of typing. An [offical blog post](https://svelte.dev/blog/svelte-and-typescript) announced full support for it in mid 2020. Here is how to get started:
@@ -44,7 +46,6 @@ Then you can write your Svelte components with TypeScript:
<template> <template>
<div>Hello {hello}</div> <div>Hello {hello}</div>
</template> </template>
``` ```
More information from community blogposts: More information from community blogposts:

View File

@@ -1,6 +1,7 @@
--- ---
title: Writing Your Own Preprocessors title: Writing Your Own Preprocessors
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
--- ---
> This article references `svelte.preprocess` throughout but you may be more familiar with the `preprocess` option of `svelte-loader` or `rollup-plugin-svelte`. This `preprocess` option calls `svelte.preprocess` internally. The bundler plugin gives you easy access to it, so you don't need to transform your components before compilation manually. > This article references `svelte.preprocess` throughout but you may be more familiar with the `preprocess` option of `svelte-loader` or `rollup-plugin-svelte`. This `preprocess` option calls `svelte.preprocess` internally. The bundler plugin gives you easy access to it, so you don't need to transform your components before compilation manually.
@@ -44,7 +45,6 @@ p Hello World!
color: red; color: red;
} }
</style> </style>
``` ```
We need to run it through Svelte to generate JavaScript, not HTML: We need to run it through Svelte to generate JavaScript, not HTML:
@@ -231,7 +231,6 @@ p Hello World!
color: red; color: red;
} }
</style> </style>
``` ```
This guarantees no ambiguity when you have a Svelte codebase that is a mix of Pug and HTML templates. In order to process this you will have to add some checking and preprocessing: This guarantees no ambiguity when you have a Svelte codebase that is a mix of Pug and HTML templates. In order to process this you will have to add some checking and preprocessing:

View File

@@ -1,6 +1,7 @@
--- ---
title: Form Validation with Svelte title: Form Validation with Svelte
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
--- ---
### Form Validation with Yup ### Form Validation with Yup
@@ -51,5 +52,4 @@ We can use `bind:value` to bind input value, and validate the form using `schema
<button type="submit">Register</button> <button type="submit">Register</button>
</div> </div>
</form> </form>
``` ```

View File

@@ -1,6 +1,7 @@
--- ---
title: Getting references to Components generated in an each block title: Getting references to Components generated in an each block
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
--- ---
Using `bind:this` allows a component to store a reference to it's children, this can also be used when generating a series of components in an `{#each}` block. Using `bind:this` allows a component to store a reference to it's children, this can also be used when generating a series of components in an `{#each}` block.
@@ -22,7 +23,6 @@ This method simply binds the generated component to an array element based on it
{#each array as item, i} {#each array as item, i}
<Child title={item.title} bind:this={children[i]} /> <Child title={item.title} bind:this={children[i]} />
{/each} {/each}
``` ```
**Method 2: Using an object as a hashtable** **Method 2: Using an object as a hashtable**
@@ -42,5 +42,4 @@ An alternative is to use an _unique_ key and bind the component to an object, ef
{#each array as item, i (item.id)} {#each array as item, i (item.id)}
<Child title={item.title} bind:this={children[item.id]} /> <Child title={item.title} bind:this={children[item.id]} />
{/each} {/each}
``` ```

View File

@@ -1,6 +1,7 @@
--- ---
title: Passing attributes to component DOM element title: Passing attributes to component DOM element
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
--- ---
When you want to "forward" any attributes that you can't control before compile time or that changes between each use of the component, like `class` or `style`, to your component wrapper DOM element (instead of declaring variables), use `$$restProps`, like the code below. However, be aware that it isn't generally recommended to use this approach, as it is difficult for Svelte to optimize it, since it doesn't know how many atributes it will receive. When you want to "forward" any attributes that you can't control before compile time or that changes between each use of the component, like `class` or `style`, to your component wrapper DOM element (instead of declaring variables), use `$$restProps`, like the code below. However, be aware that it isn't generally recommended to use this approach, as it is difficult for Svelte to optimize it, since it doesn't know how many atributes it will receive.
@@ -11,7 +12,6 @@ When you want to "forward" any attributes that you can't control before compile
<!-- App.svelte --> <!-- App.svelte -->
<Component class="li-item-class">{name}</Component> <Component class="li-item-class">{name}</Component>
``` ```
[Svelte Playground here](https://svelte.dev/repl/24139d8599d348b9bcad5c0a1f471230?version=3.23.0). See [relevant part of docs](https://svelte.dev/docs#Attributes_and_props) for more. [Svelte Playground here](https://svelte.dev/repl/24139d8599d348b9bcad5c0a1f471230?version=3.23.0). See [relevant part of docs](https://svelte.dev/docs#Attributes_and_props) for more.

View File

@@ -1,6 +1,8 @@
--- ---
title: Using Fetch to Consume APIs with Svelte title: Using Fetch to Consume APIs with Svelte
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
updated: 2022-03-22T23:11:24+01:00
--- ---
Working with external data in Svelte is important. Here's a guide. Working with external data in Svelte is important. Here's a guide.
@@ -26,7 +28,6 @@ We can declare a `data` variable and use the `onMount` lifecycle to fetch on mou
<pre> <pre>
{JSON.stringify(data, null, 2)} {JSON.stringify(data, null, 2)}
</pre> </pre>
``` ```
You can further improve this implementation by showing a placeholder while `data` is undefined and also showing an error notification if an error occurs. You can further improve this implementation by showing a placeholder while `data` is undefined and also showing an error notification if an error occurs.
@@ -53,7 +54,6 @@ This example is exactly equal to Method 1 above:
{:catch error} {:catch error}
<!-- optionally show something while promise was rejected --> <!-- optionally show something while promise was rejected -->
{/await} {/await}
``` ```
Here you can see that it is very intuitive where to place your loading placeholder and error display. Here you can see that it is very intuitive where to place your loading placeholder and error display.
@@ -86,7 +86,6 @@ If we don't want to immediately load data on component mount, we can wait for us
<pre> <pre>
{JSON.stringify(data, null, 2)} {JSON.stringify(data, null, 2)}
</pre> </pre>
``` ```
The user now has an intuitive way to refresh their data. The user now has an intuitive way to refresh their data.
@@ -118,7 +117,6 @@ It would be better to make all these commonplace UI idioms declarative. Await bl
{:catch error} {:catch error}
<!-- optionally show something while promise was rejected --> <!-- optionally show something while promise was rejected -->
{/await} {/await}
``` ```
The trick here is we can simply reassign the `promise` to trigger a refetch, which then also clears the UI of stale data while fetching. The trick here is we can simply reassign the `promise` to trigger a refetch, which then also clears the UI of stale data while fetching.
@@ -153,7 +151,6 @@ Of course, it is up to you what UX you want - you may wish to keep displaying st
{:catch error} {:catch error}
<!-- optionally show something while promise was rejected --> <!-- optionally show something while promise was rejected -->
{/await} {/await}
``` ```
**Method 4: Data Stores** **Method 4: Data Stores**
@@ -197,7 +194,6 @@ export function getNewCount() {
<pre> <pre>
{$count} {$count}
</pre> </pre>
``` ```
This has the added benefit of keeping state around if the component gets remounted again with no need for a new data fetch. This has the added benefit of keeping state around if the component gets remounted again with no need for a new data fetch.

View File

@@ -1,6 +1,7 @@
--- ---
title: Authentication with Svelte title: Authentication with Svelte
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
--- ---
Figuring out how to authenticate with Svelte can be tricky business. The official docs for Sapper, the Server-Side Rendering platform designed for Svelte, recognize that session management should be handled by some other service such as [express-session](https://github.com/expressjs/session), but you are not limited to using any backend with Svelte. Moreover, Sapper does not have native support for persistent sessions (as of April 2020). Figuring out how to authenticate with Svelte can be tricky business. The official docs for Sapper, the Server-Side Rendering platform designed for Svelte, recognize that session management should be handled by some other service such as [express-session](https://github.com/expressjs/session), but you are not limited to using any backend with Svelte. Moreover, Sapper does not have native support for persistent sessions (as of April 2020).
@@ -96,5 +97,4 @@ It is important to note that this example includes `preventDefault` to prevent t
{/await} {/await}
{/if} {/if}
</div> </div>
``` ```

View File

@@ -1,6 +1,7 @@
--- ---
title: Routing with Svelte title: Routing with Svelte
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
--- ---
_to be written_ _to be written_

View File

@@ -1,6 +1,7 @@
--- ---
title: Server-side Rendering title: Server-side Rendering
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
--- ---
_some content_ _some content_

View File

@@ -1,6 +1,7 @@
--- ---
title: Editable SVG Icon Systems with Svelte and Heroicons title: Editable SVG Icon Systems with Svelte and Heroicons
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
--- ---
There are many ways to create an SVG Icon System, but one method that takes advantage of Svelte's capabilities is to create editable inline icons as components. Some of the advantages of this way of working is: There are many ways to create an SVG Icon System, but one method that takes advantage of Svelte's capabilities is to create editable inline icons as components. Some of the advantages of this way of working is:
@@ -35,7 +36,6 @@ The next step is to create a base icon component (`Icon.svelte`). Start with the
<slot /> <slot />
</g> </g>
</svg> </svg>
``` ```
You can use this `Icon` component as is - the only thing you might need to update is the `viewBox` depending on the `viewBox` of the icons you are using. The `width`, `height`, `color`, and `name` props of the icon will allow the icon to be dynamically updated. You can use this `Icon` component as is - the only thing you might need to update is the `viewBox` depending on the `viewBox` of the icons you are using. The `width`, `height`, `color`, and `name` props of the icon will allow the icon to be dynamically updated.
@@ -51,7 +51,6 @@ Our script will look like this:
export let name = ''; export let name = '';
export let color = 'currentColor'; export let color = 'currentColor';
</script> </script>
``` ```
The default `color` prop is set to `currentColor` so the icon will inherit the color of whatever text surrounds it. Of course, this csn be overridden with a specific color. The default `color` prop is set to `currentColor` so the icon will inherit the color of whatever text surrounds it. Of course, this csn be overridden with a specific color.
@@ -67,14 +66,12 @@ To use it, say we had a Svelte component called `PencilAlt.svelte` that containe
d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z" d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"
clip-rule="evenodd" clip-rule="evenodd"
/> />
``` ```
We can use the `Icon` component as follows: We can use the `Icon` component as follows:
```svelte ```svelte
<Icon name="pencil-alt"><PencilAlt /></Icon> <Icon name="pencil-alt"><PencilAlt /></Icon>
``` ```
Now, if wed like to make many sizes for the icon, we can do so very easily: Now, if wed like to make many sizes for the icon, we can do so very easily:
@@ -88,7 +85,6 @@ Now, if wed like to make many sizes for the icon, we can do so very easily:
<!-- or bump up the size, too --> <!-- or bump up the size, too -->
<Icon width="30" height="30" name="pencilAlt"><PencilAlt /></Icon> <Icon width="30" height="30" name="pencilAlt"><PencilAlt /></Icon>
</p> </p>
``` ```
### Additional Notes ### Additional Notes

View File

@@ -1,6 +1,7 @@
--- ---
title: Dockerize a Sapper App title: Dockerize a Sapper App
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
--- ---
_This example is taken from the [https://svelte.dev/](https://svelte.dev/)._ _This example is taken from the [https://svelte.dev/](https://svelte.dev/)._

View File

@@ -1,6 +1,7 @@
--- ---
title: Dockerize a Svelte App title: Dockerize a Svelte App
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
--- ---
Let's pull down the [basic svelte template](https://github.com/sveltejs/template) using [degit](https://github.com/Rich-Harris/degit). Let's pull down the [basic svelte template](https://github.com/sveltejs/template) using [degit](https://github.com/Rich-Harris/degit).

View File

@@ -2,6 +2,8 @@
title: Stores title: Stores
layout: recipeCategory layout: recipeCategory
icon: database icon: database
published: 2021-06-14T11:30:41-07:00
updated: 2023-01-27T20:05:46-08:00
--- ---
<script>import Warning from '../../../lib/components/recipes/Warning.svelte'</script> <script>import Warning from '../../../lib/components/recipes/Warning.svelte'</script>

View File

@@ -1,6 +1,7 @@
--- ---
title: Looping title: Looping
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
--- ---
`{#each}` block allows you to loop only **array** or **array-like object** (i.e. it has a `.length` property). `{#each}` block allows you to loop only **array** or **array-like object** (i.e. it has a `.length` property).
@@ -24,7 +25,6 @@ You can use spread operator `[...value]` for [Map](https://developer.mozilla.org
{key}: {value} {key}: {value}
</div> </div>
{/each} {/each}
``` ```
Both [`Map.keys()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys) and [`Map.values()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values) method return an iterable. To use `{#each}` with iterable, you can use spread operator `[...value]` on the iterable. Both [`Map.keys()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys) and [`Map.values()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values) method return an iterable. To use `{#each}` with iterable, you can use spread operator `[...value]` on the iterable.
@@ -48,7 +48,6 @@ Both [`Map.keys()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe
{value} {value}
</div> </div>
{/each} {/each}
``` ```
### Looping a set ### Looping a set
@@ -65,7 +64,6 @@ You can use spread operator `[...value]` for [Set](https://developer.mozilla.org
{item} {item}
</div> </div>
{/each} {/each}
``` ```
### Looping a string ### Looping a string
@@ -82,7 +80,6 @@ You can use spread operator `[...value]` for [Set](https://developer.mozilla.org
{character} {character}
</div> </div>
{/each} {/each}
``` ```
### Looping a generator function ### Looping a generator function
@@ -104,7 +101,6 @@ To use `{#each}` with generator function, you can use spread operator `[...value
{item} {item}
</div> </div>
{/each} {/each}
``` ```
### Binding to a spread item ### Binding to a spread item
@@ -123,7 +119,6 @@ Once you spread a Map, Set, Generator, or any Iterable, you are creating a new a
<!-- You can't change the value of the input, nor the value in the map --> <!-- You can't change the value of the input, nor the value in the map -->
<input bind:value /> <input bind:value />
{/each} {/each}
``` ```
To workaround this, you can use `on:input` listener To workaround this, you can use `on:input` listener
@@ -145,5 +140,4 @@ To workaround this, you can use `on:input` listener
}} }}
/> />
{/each} {/each}
``` ```

View File

@@ -1,6 +1,8 @@
--- ---
title: Using the `immutable` Compiler Option title: Using the `immutable` Compiler Option
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
updated: 2022-08-31T22:24:38+01:00
--- ---
`<svelte:options immutable>` is a performance optimization you can add to your Svelte components. `<svelte:options immutable>` is a performance optimization you can add to your Svelte components.

View File

@@ -1,6 +1,8 @@
--- ---
title: Passing data between components title: Passing data between components
layout: recipe layout: recipe
published: 2022-08-30T00:07:30+02:00
updated: 2022-10-12T23:14:11+02:00
--- ---
<script> <script>

View File

@@ -1,6 +1,7 @@
--- ---
title: Passing values from JS to CSS title: Passing values from JS to CSS
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
--- ---
You can easily read in CSS media query values into JS with [`window.matchMedia`](https://developer.mozilla.org/en/docs/Web/API/Window/matchMedia). However, sometimes you want to pass information from JS to CSS variables, or have CSS Variables read into JS. You can easily read in CSS media query values into JS with [`window.matchMedia`](https://developer.mozilla.org/en/docs/Web/API/Window/matchMedia). However, sometimes you want to pass information from JS to CSS variables, or have CSS Variables read into JS.
@@ -40,7 +41,6 @@ To set CSS Variables on an element, you can use the `style` attribute.
width: var(--width); width: var(--width);
} }
</style> </style>
``` ```
Alternatively, you can have a custom action to do this. This is already available with [svelte-css-vars](https://github.com/kaisermann/svelte-css-vars). Alternatively, you can have a custom action to do this. This is already available with [svelte-css-vars](https://github.com/kaisermann/svelte-css-vars).

View File

@@ -1,6 +1,8 @@
--- ---
title: Reactivity title: Reactivity
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
updated: 2022-02-05T22:15:51-08:00
--- ---
### Reactive assignments ### Reactive assignments
@@ -24,7 +26,6 @@ The following works as expected and update the dom:
<button on:click={updateNum}>Update</button> <button on:click={updateNum}>Update</button>
<p>{num}</p> <p>{num}</p>
``` ```
Svelte can see that there is an assignment to a top-level variable and knows to re-render after the `num` variable is modified. Svelte can see that there is an assignment to a top-level variable and knows to re-render after the `num` variable is modified.
@@ -45,7 +46,6 @@ The following example causes the array and, subsequently, the DOM to be updated:
{#each list as item} {#each list as item}
<button on:click={() => (item.n *= 2)}>{item.n}</button> <button on:click={() => (item.n *= 2)}>{item.n}</button>
{/each} {/each}
``` ```
This, however, will not: This, however, will not:
@@ -58,7 +58,6 @@ This, however, will not:
{#each list as item} {#each list as item}
<button on:click={() => (item *= 2)}>{item}</button> <button on:click={() => (item *= 2)}>{item}</button>
{/each} {/each}
``` ```
The easiest workaround is to just reference the array item by index from inside the each block: The easiest workaround is to just reference the array item by index from inside the each block:
@@ -71,7 +70,6 @@ The easiest workaround is to just reference the array item by index from inside
{#each list as item, index} {#each list as item, index}
<button on:click={() => (list[index] *= 2)}>{item}</button> <button on:click={() => (list[index] *= 2)}>{item}</button>
{/each} {/each}
``` ```
#### Variables not values #### Variables not values
@@ -94,7 +92,6 @@ This is the sort of problem you may run into when dealing with objects. Since ob
<button on:click={updateNum}>Update</button> <button on:click={updateNum}>Update</button>
<p>{obj.num}</p> <p>{obj.num}</p>
``` ```
In this example, when we reassign `o.num` we are updating the value assigned to `obj` but since we are not updating the actual `obj` variable Svelte does not trigger an update. Svelte does not trace these kinds of values back to a variable defined at the top level and has no way of knowing if it has updated or not. Whenever you want to update the local component state, any reassignments must be performed on the _actual_ variable, not just the value itself. In this example, when we reassign `o.num` we are updating the value assigned to `obj` but since we are not updating the actual `obj` variable Svelte does not trigger an update. Svelte does not trace these kinds of values back to a variable defined at the top level and has no way of knowing if it has updated or not. Whenever you want to update the local component state, any reassignments must be performed on the _actual_ variable, not just the value itself.
@@ -116,7 +113,6 @@ Another situation that can sometimes cause unexpected results is when you reassi
<button on:click={() => updateNum(obj)}>Update</button> <button on:click={() => updateNum(obj)}>Update</button>
<p>{num}</p> <p>{num}</p>
``` ```
This example behaves the same as the previous example, except it is perhaps even more confusing. In this case, the `obj` variable is being _shadowed_ while inside the function, so any assignments to `obj` inside this function are assignments to the function parameter rather than the top-level `obj` variable. It refers to the same value, and it has the same name, but it is a _different_ variable inside the function scope. This example behaves the same as the previous example, except it is perhaps even more confusing. In this case, the `obj` variable is being _shadowed_ while inside the function, so any assignments to `obj` inside this function are assignments to the function parameter rather than the top-level `obj` variable. It refers to the same value, and it has the same name, but it is a _different_ variable inside the function scope.
@@ -135,7 +131,6 @@ In addition to the assignment-based reactivity system, Svelte also has special s
</script> </script>
<button on:click={() => (n += 1)}>{n_squared}</button> <button on:click={() => (n += 1)}>{n_squared}</button>
``` ```
Whenever Svelte sees a reactive declaration, it makes sure to execute any reactive statements that depend on one another in the correct order and only when their direct dependencies have changed. A 'direct dependency' is a variable that is referenced inside the reactive declaration itself. References to variables inside functions that a reactive declaration _calls_ are not considered dependencies. Whenever Svelte sees a reactive declaration, it makes sure to execute any reactive statements that depend on one another in the correct order and only when their direct dependencies have changed. A 'direct dependency' is a variable that is referenced inside the reactive declaration itself. References to variables inside functions that a reactive declaration _calls_ are not considered dependencies.
@@ -150,7 +145,6 @@ Whenever Svelte sees a reactive declaration, it makes sure to execute any reacti
</script> </script>
<button on:click={() => (n += 1)}>{n_squared}</button> <button on:click={() => (n += 1)}>{n_squared}</button>
``` ```
In the above example, `n_squared` will _not_ be recalculated when `n` changes because Svelte is not looking inside the `squareIt` function to define the reactive declaration's dependencies. In the above example, `n_squared` will _not_ be recalculated when `n` changes because Svelte is not looking inside the `squareIt` function to define the reactive declaration's dependencies.

View File

@@ -1,6 +1,7 @@
--- ---
title: Scoped global CSS title: Scoped global CSS
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
--- ---
Sometimes your template code doesn't match your CSS. If you generate html via `{@html}` or have some un-styled elements inside child components, you might want to style it. However, Svelte won't let you write CSS that doesn't exist in the templates. You might feel forced to use `:global()` to make the CSS work, but that would leak it out to the rest of your app. So, instead you could try this trick: Sometimes your template code doesn't match your CSS. If you generate html via `{@html}` or have some un-styled elements inside child components, you might want to style it. However, Svelte won't let you write CSS that doesn't exist in the templates. You might feel forced to use `:global()` to make the CSS work, but that would leak it out to the rest of your app. So, instead you could try this trick:
@@ -17,7 +18,6 @@ Sometimes your template code doesn't match your CSS. If you generate html via `{
margin-top: 1rem; margin-top: 1rem;
} }
</style> </style>
``` ```
Now that `p` styling will be output by Svelte, AND it won't leak out to the rest of your app. Now that `p` styling will be output by Svelte, AND it won't leak out to the rest of your app.

View File

@@ -1,6 +1,7 @@
--- ---
title: Benchmarking Svelte Components title: Benchmarking Svelte Components
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
--- ---
_This is a stub, if you are interested in this topic please reach out [via GitHub](https://github.com/svelte-society/sveltesociety.dev/issues/60) and lets work on this together._ _This is a stub, if you are interested in this topic please reach out [via GitHub](https://github.com/svelte-society/sveltesociety.dev/issues/60) and lets work on this together._

View File

@@ -1,6 +1,8 @@
--- ---
title: Unit Testing Svelte Components title: Unit Testing Svelte Components
layout: recipe layout: recipe
published: 2021-06-14T11:30:41-07:00
updated: 2023-07-16T10:12:46-05:00
--- ---
_Some assumptions here, this was pulled from something I wrote and the context was different. Edits will be required._ _Some assumptions here, this was pulled from something I wrote and the context was different. Edits will be required._
@@ -79,7 +81,6 @@ Slots are more difficult to test as there is no programmatic interface for worki
<svelte:component this={Component}> <svelte:component this={Component}>
<h1 data-testid="slot">Test Data</h1> <h1 data-testid="slot">Test Data</h1>
</svelte:component> </svelte:component>
``` ```
Then the component you wish to test can be passed to the constructor as a prop in order to mount the component correctly: Then the component you wish to test can be passed to the constructor as a prop in order to mount the component correctly:
@@ -115,7 +116,6 @@ As with slots, there is no programmatic interface for the Context API (setContex
</script> </script>
<svelte:component this={Component} /> <svelte:component this={Component} />
``` ```
The component we wish to test looks something like this: The component we wish to test looks something like this:
@@ -128,7 +128,6 @@ The component we wish to test looks something like this:
</script> </script>
<button>{ctx.title}</button> <button>{ctx.title}</button>
``` ```
We can test this like so: We can test this like so: