mirror of
https://github.com/LukeHagar/sveltesociety.dev.git
synced 2025-12-10 12:47:45 +00:00
Add date on recipes (#441)
* Add date on recipes * Use Intl.DateTimeFormat instead of date-fns lib
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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)).
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -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_
|
||||||
|
|||||||
@@ -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_
|
||||||
|
|||||||
@@ -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 we’d like to make many sizes for the icon, we can do so very easily:
|
Now, if we’d like to make many sizes for the icon, we can do so very easily:
|
||||||
@@ -88,7 +85,6 @@ Now, if we’d 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
|
||||||
|
|||||||
@@ -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/)._
|
||||||
|
|||||||
@@ -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).
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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).
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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._
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user