svelte icon indicating copy to clipboard operation
svelte copied to clipboard

Slot forwarding doesn't work as it were

Open kkarpeev opened this issue 2 years ago • 6 comments
trafficstars

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

kkarpeev avatar Jun 20 '23 09:06 kkarpeev

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 avatar Jun 20 '23 09:06 dummdidumm

@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.

kkarpeev avatar Jun 20 '23 10:06 kkarpeev

@dummdidumm Will you answer, please? It's a quite critical bug that ruins basic svelte composition feature. Same for the default slot.

kkarpeev avatar Jun 21 '23 09:06 kkarpeev

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 avatar Jun 22 '23 17:06 hjalmar

@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.

Cybolic avatar Jun 23 '23 01:06 Cybolic

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

tanhauhau avatar Jul 11 '23 14:07 tanhauhau

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

#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

kkarpeev avatar Nov 27 '23 12:11 kkarpeev

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.

kkarpeev avatar Nov 27 '23 12:11 kkarpeev

Can you, please, make this work in any way, please?

kkarpeev avatar Nov 27 '23 12:11 kkarpeev