* give this another try
* fix: lint
* fix: Forgot to save
* feat: it works boiiii
* look, ok, it did work, i just needed to update the snapshots
* bruh
* changeset
* feat: ok I think the client snippet block finally works
* feat: current tests pass; I'm sure I'm missing stuff for new things
* fix: snapshot
* feat: I think non-destructured rest should work now?
* chore: duplicated computation
* feat: Tests (passing and failing
* feat: it's... alive?
* chore: Clean up my messes
* chore: devtime stuff
* fix: fmt
* chore: see if this fixes repl
* chore: make naming more offensive
* fix: Don't throw on missing keys, return undefined as it usually would
* Update packages/svelte/src/compiler/phases/1-parse/state/tag.js
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* Update packages/svelte/src/compiler/phases/1-parse/state/tag.js
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* fix: Hopefully default param values now work
* dumb
* types
* feat: Test it
* fix: Turns out javascript parameters are optional
* feat: The Final Solution
* document function
* feat: Better bracket matching, unit tests
* feat: exclude test files from publish
* feat: More unit tests
* feat: Use more efficient parsing for @const
* Update .changeset/curvy-cups-cough.md
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* Update packages/svelte/package.json
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* Update packages/svelte/src/compiler/phases/1-parse/utils/bracket.js
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* fix: changesets
* chore: additional comments
* fix: kill foreach
* fix: foreach again
* feat: Docs
* Revert "fix: kill foreach"
This reverts commit 9a688cc543.
* fix: My own stupidity
* fix: style
* fix - maybe
* Update sites/svelte-5-preview/src/routes/docs/content/01-api/03-snippets.md
* Update tag.js
Co-authored-by: Rich Harris <richard.a.harris@gmail.com>
* Update .changeset/curvy-cups-cough.md
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* chore: Remove rest params
* Delete .changeset/eighty-rivers-wash.md
* fix: Honestly idk why it was broken but it's fixed now
* fix: var name lol
* fix: typegen
* fix: idk
* fix: It looks like a bunch of unformatted shit came in through main?? idk
* Revert "fix: It looks like a bunch of unformatted shit came in through main?? idk"
This reverts commit ab851d5627.
* fix: format again
* this is getting ridiculous
* Update tag.js
Co-authored-by: Rich Harris <richard.a.harris@gmail.com>
* fix errors
* simplify a bit
* use read_context
* use read_context for const as well
* remove unused code
* unused import
* unused export
* remove spread args. sorry elliott
* tidy up SnippetBlock interface
* fix test
* simplify
* tweak
* revert example, so that it matches the surrounding text
* move PropsWithChildren back to public.d.ts
* update typing docs, so that it flows from previous example
* temporarily revert const parsing changes, to get prettier working again (???)
* oops
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Co-authored-by: Rich Harris <richard.a.harris@gmail.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
@ -58,7 +58,7 @@ Snippets, and _render tags_, are a way to create reusable chunks of markup insid
{/each}
{/each}
```
```
A snippet can have at most one parameter. You can destructure it, just like a function argument ([demo](/#H4sIAAAAAAAAE5VTYW-bMBD9KyeiKYlEY4jWfSAk2n5H6QcXDmwVbMs2SzuL_z6DTRqp2rQJ2Ycfd_ced2eXtLxHkxRPLhF0wKRIfiiVpIl9V_PB_MTeoj8bOep6RkpTa67spRKV7dECH2iHBs7wNCOVdcFU1ui6gC2zVpmCEMVrMw4HxaSVhnzLMnLMsm26Ol95Y1kBHr9BDHnHbAHHO6ymynIpfF7LuAncwKgBCj0Xrx_5mMb2jh3f6KB6PNRy2AaXKf1fuY__KPfxj3KlQGikL5aQdpUxm-dTJUryUVdRsvwSqEviX2fIbYzgSvmCt7wbNe4ceMUpRIoUFkkpBBkw7ZfMZXC-BLKSDx3Q3p5djJrA-SR-X4K9DdHT6u-jo-flFlKSO3ThIDcSR6LIKUhGWrN1QGhs16LLbXgbjoe5U1PkozCfzu7uy2WtpfuuUTSo1_9ffPZrJKGLoyuwNxjBv0Q4wmdSR2aFi9jS2Pc-FIrlEKeilcI-GP4LfVtxOM1gyO1XSLp6vtD6tdNyFE0BV8YtngKuaNNw0RWQx_jKDlR33M9E5h-PQhZxfxEt6gIaLdWDYbSR191RvcFXv_LMb7p7obssXZ5Dvt_f9HgzdzZKibOZZ9mXmHkdTTpaefqsd4OIay4_hksd_I0fZMNbjk1SWD3i9Dz9BpdEPu8sBAAA)):
Snippet parameters can be destructured ([demo](/#H4sIAAAAAAAAE5VTYW-bMBD9KyeiKYlEY4jWfSAk2n5H6QcXDmwVbMs2SzuL_z6DTRqp2rQJ2Ycfd_ced2eXtLxHkxRPLhF0wKRIfiiVpIl9V_PB_MTeoj8bOep6RkpTa67spRKV7dECH2iHBs7wNCOVdcFU1ui6gC2zVpmCEMVrMw4HxaSVhnzLMnLMsm26Ol95Y1kBHr9BDHnHbAHHO6ymynIpfF7LuAncwKgBCj0Xrx_5mMb2jh3f6KB6PNRy2AaXKf1fuY__KPfxj3KlQGikL5aQdpUxm-dTJUryUVdRsvwSqEviX2fIbYzgSvmCt7wbNe4ceMUpRIoUFkkpBBkw7ZfMZXC-BLKSDx3Q3p5djJrA-SR-X4K9DdHT6u-jo-flFlKSO3ThIDcSR6LIKUhGWrN1QGhs16LLbXgbjoe5U1PkozCfzu7uy2WtpfuuUTSo1_9ffPZrJKGLoyuwNxjBv0Q4wmdSR2aFi9jS2Pc-FIrlEKeilcI-GP4LfVtxOM1gyO1XSLp6vtD6tdNyFE0BV8YtngKuaNNw0RWQx_jKDlR33M9E5h-PQhZxfxEt6gIaLdWDYbSR191RvcFXv_LMb7p7obssXZ5Dvt_f9HgzdzZKibOZZ9mXmHkdTTpaefqsd4OIay4_hksd_I0fZMNbjk1SWD3i9Dz9BpdEPu8sBAAA)):
@ -69,6 +69,8 @@ A snippet can have at most one parameter. You can destructure it, just like a fu
{/snippet}
{/snippet}
```
```
Like function declarations, snippets can have an arbitrary number of parameters, which can have default values. You cannot use rest parameters however.
## Snippet scope
## Snippet scope
Snippets can be declared anywhere inside your component. They can reference values declared outside themselves, for example in the `<script>` tag or in `{#each ...}` blocks ([demo](/#H4sIAAAAAAAAE12P0QrCMAxFfyWrwhSEvc8p-h1OcG5RC10bmkyQ0n-3HQPBx3vCPUmCemiDrOpLULYbUdXqTKR2Sj6UA7_RCKbMbvJ9Jg33XpMcW9uKQYEAIzJ3T4QD3LSUDE-PnYA4YET4uOkGMc3W5B3xZrtvbVP9HDas2GqiZHqhMW6Tr9jGbG_oOCMImcUCwrIpFk1FqRyqpRpn0cmjHdAvnrIzuscyq_4nd3dPPD01ukE_NA6qFj9hvMYvGjJADw8BAAA=))...
Snippets can be declared anywhere inside your component. They can reference values declared outside themselves, for example in the `<script>` tag or in `{#each ...}` blocks ([demo](/#H4sIAAAAAAAAE12P0QrCMAxFfyWrwhSEvc8p-h1OcG5RC10bmkyQ0n-3HQPBx3vCPUmCemiDrOpLULYbUdXqTKR2Sj6UA7_RCKbMbvJ9Jg33XpMcW9uKQYEAIzJ3T4QD3LSUDE-PnYA4YET4uOkGMc3W5B3xZrtvbVP9HDas2GqiZHqhMW6Tr9jGbG_oOCMImcUCwrIpFk1FqRyqpRpn0cmjHdAvnrIzuscyq_4nd3dPPD01ukE_NA6qFj9hvMYvGjJADw8BAAA=))...
@ -217,12 +219,45 @@ Any content inside the component tags that is _not_ a snippet declaration implic
> Note that you cannot have a prop called `children` if you also have content inside the component — for this reason, you should avoid having props with that name
> Note that you cannot have a prop called `children` if you also have content inside the component — for this reason, you should avoid having props with that name
## Typing snippets
Snippets implement the `Snippet` interface imported from `'svelte'`:
```diff
-<script>
- let { data, children, row } = $props();
+<scriptlang="ts">
+ import type { Snippet } from 'svelte';
+
+ let { data, children, row } = $props<{
+ data: any[];
+ children: Snippet;
+ row: Snippet<[any]>;
+ }>();
</script>
```
With this change, red squigglies will appear if you try and use the component without providing a `data` prop and a `row` snippet. Notice that the type argument provided to `Snippet` is a tuple, since snippets can have multiple parameters.
We can tighten things up further by declaring a generic, so that `data` and `row` refer to the same type:
```diff
-<scriptlang="ts">
+<scriptlang="ts"generics="T">
import type { Snippet } from 'svelte';
let { data, children, row } = $props<{
- data: any[];
+ data: T[];
children: Snippet;
- row: Snippet<[any]>;
+ row: Snippet<[T]>;
}>();
</script>
```
## Snippets and slots
## Snippets and slots
In Svelte 4, content can be passed to components using [slots](https://svelte.dev/docs/special-elements#slot). Snippets are more powerful and flexible, and as such slots are deprecated in Svelte 5.
In Svelte 4, content can be passed to components using [slots](https://svelte.dev/docs/special-elements#slot). Snippets are more powerful and flexible, and as such slots are deprecated in Svelte 5.
They continue to work, however, and you can mix and match snippets and slots in your components.
They continue to work, however, and you can mix and match snippets and slots in your components.
## Typing snippets
Right now, it's not possible to add types for snippets and their parameters. This is something we hope to address before we ship Svelte 5.