Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better docs for snippets-slots interop #13867

Open
rChaoz opened this issue Oct 24, 2024 · 2 comments · May be fixed by #13869
Open

Better docs for snippets-slots interop #13867

rChaoz opened this issue Oct 24, 2024 · 2 comments · May be fixed by #13869

Comments

@rChaoz
Copy link
Contributor

rChaoz commented Oct 24, 2024

Describe the bug

In the docs, the only mention of snippets-slots interop is:

In Svelte 4, content can be passed to components using slots. Svelte 5 replaces them with snippets which 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.

But it doesn't say exactly what that means. It is intuitive that you can use old components with slots from new snippet-based components, but not the other way around, and that slot props are passed using destructuring, as they are named, but I think this should be documented a bit.

For example:

<!-- Child.svelte -->
<slot name="named" />
<br>
<slot />


<!-- Parent.svelte -->
<Child>
  {#snippet named()}
    Named
  {/snippet}
  Default
</Child>

And with values:

<!-- Child.svelte -->
<script>
  let value = 0
</script>

<slot name="named" {value} />
<br>
<slot {value} />
<br>
<button on:click={() => value++}>Increment</button>


<!-- Parent.svelte -->
<Child>
  {#snippet named({ value })}
    Named: {value}
  {/snippet}
  {#snippet children({ value })}
    Default with value: {value}
  {/snippet}
</Child>

But the other way around doesn't work (except for default slots and without props), as it doesn't make sense to write Svelte 4 code using Svelte 5 code, but I think it can happen if upgrading to Svelte 5 libraries in a codebase that's not fully migrated:

<!-- Child.svelte -->
<script>
  let { children, named } = $props()
</script>

{@render children?.()}
<br>
{@render named?.()}


<!-- Parent.svelte -->
<Child>
  <!-- This doesn't get rendered -->
  <svelte:fragment slot="named">
    Named
  </svelte:fragment>
  Default
</Child>

Or:

<!-- Child.svelte -->
<script>
  let { children, named } = $props()
</script>

{@render children?.({ value: 123 })}


<!-- Parent.svelte -->
<!-- invalid_default_snippet Cannot use `{@render children(...)}` if the parent component uses `let:` directives. Consider using a named snippet instead in New.svelte in App.svelte  -->
<Child let:value>
  Value: {value}
</Child>
@rChaoz
Copy link
Contributor Author

rChaoz commented Oct 24, 2024

For sure, I didn't realise. But I do think this has a bit more details & condenses the other 2 issues as well.

@rChaoz rChaoz linked a pull request Oct 24, 2024 that will close this issue
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants