svelte
svelte copied to clipboard
Slot forwarding doesn't work as it were
Describe the bug
Slot forwarding doesn't work as it were in 3.28. When middle component merely forwards named (or even default) slot, deeper component thinks that this slot is occupied. But it's not.
Reproduction
Correct behavior Broken in 3.29
Logs
No response
System Info
System:
OS: Linux 5.19 Ubuntu 22.04.2 LTS 22.04.2 LTS (Jammy Jellyfish)
CPU: (8) x64 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
Memory: 3.72 GB / 15.36 GB
Container: Yes
Shell: 5.1.16 - /bin/bash
Binaries:
Node: 16.20.0 - /usr/bin/node
Yarn: 3.5.0 - /usr/bin/yarn
npm: 8.19.4 - /usr/bin/npm
Browsers:
Chrome: 114.0.5735.133
Chromium: 114.0.5735.106
Firefox: 113.0.2
npmPackages:
svelte: 3.53.1 => 3.53.1
webpack: 5.76.2 => 5.76.2
Severity
blocking an upgrade
I'm honestly not sure what the more correct behavior is - arguably that slot is taken, by the component passing things through, so you could make the argument that the one passing through now should take care of the fallback.
@dummdidumm It is slot forwarding (not a nesting) that worked in specific way from the start until .29 in the same Svelte 3. Breaking changes in slot behavior are clearly not correct. Not to mention it breaks composition.
@dummdidumm Will you answer, please? It's a quite critical bug that ruins basic svelte composition feature. Same for the default slot.
I just tried it using a fragment instead and that seems to work so it seems to be an inconsistent behavior at least?
@kkarpeev Maybe this works as a workaround for you? https://svelte.dev/repl/6c5c247ba9eb4cd8941d72cc57376a35?version=3.59.1
@hjalmar The way I see it, your example does one forward (using the slot) and one assignment (using the svelte:fragment).
As I understand the issue, it's specifically that forwarding currently breaks any if blocks that use $$slots as well as any fallback slot contents, as demonstrated here: https://svelte.dev/repl/e07f09d9fd9d4fde8dd32a42bf4cd110?version=3.59.1
The second use of Component1 in this example doesn't actually use any of the slots, but the default slot content still isn't shown and the if test shows that $$slots property, incorrectly, is true.
https://github.com/sveltejs/svelte/issues/2079 may also be relevant.
well, in 3.28 it didnt work completely as you think too, as shown in:
https://svelte.dev/repl/2cdf3c12fda14ff980bcc8426179dd4f?version=3.28.0
you would not be able to pass content from App all the way into Component2 through slot forwarding.
the problem that you are pointing out is that Component2 has no idea if there's no actual content passed from a slot content from Component1, so i think one of the solutions for this is to have a conditional slot content:
<Component2>
{#if $$slots['1']}
<slot name="1" slot="2" />
{/if}
</Component2>
though the conditional slot is currently undecided as the team is still settling down what would be for svelte 5
https://github.com/sveltejs/svelte/pull/8304
well, in
3.28it didnt work completely as you think too, as shown in:https://svelte.dev/repl/2cdf3c12fda14ff980bcc8426179dd4f?version=3.28.0
you would not be able to pass content from
Appall the way intoComponent2through slot forwarding.the problem that you are pointing out is that
Component2has no idea if there's no actual content passed from a slot content fromComponent1, so i think one of the solutions for this is to have a conditional slot content:<Component2> {#if $$slots['1']} <slot name="1" slot="2" /> {/if} </Component2>though the conditional slot is currently undecided as the team is still settling down what would be for svelte 5
#8304
No, this doesn't work for a default slot. It just ignores {#if} around <slot/>.
proof
upd: and what's undecided about svelte 3 (I'm using 3, not 5)? It's it your docs
I just tried it using a fragment instead and that seems to work so it seems to be an inconsistent behavior at least?
@kkarpeev Maybe this works as a workaround for you? https://svelte.dev/repl/6c5c247ba9eb4cd8941d72cc57376a35?version=3.59.1
Nope, it's not a workaround for a default slot either.
Can you, please, make this work in any way, please?