sveltejs / svelte

Cybernetically enhanced web apps
https://svelte.dev
MIT License
78.21k stars 4.09k forks source link

Slots information disappear, when using {#if} inside parent componet #7651

Open borgius opened 2 years ago

borgius commented 2 years ago

Describe the bug

If we put named slot in {#if} block on parent component, child will not receive the named slot, but only default slot. Please check NavBar.svelte $$slots Example:

App.svelte ```svelte
```
Header.svelte ```svelte
{#if left} {/if} {#if right} {/if}
```
NavBar.svelte ```svelte {JSON.stringify($$slots)} {#if $$slots.left} [Left slot] {/if} {#if title}

{title}

{/if} {#if $$slots.right} [Right slot] {/if} ```
Btn.svelte ```svelte [{text}] ```

Reproduction

https://svelte.dev/repl/c0de4395f6ad4f7c9093a660225e7110?version=3.48.0

Logs

No response

System Info

System:
    OS: macOS 12.4
    CPU: (8) x64 Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
    Memory: 196.32 MB / 16.00 GB
    Shell: 5.1.12 - /usr/local/bin/bash
  Binaries:
    Node: 16.15.0 - /usr/local/bin/node
    Yarn: 1.22.18 - ~/.local/bin/yarn
    npm: 6.14.16 - ~/.local/bin/npm
  Browsers:
    Brave Browser: 102.1.39.122
    Chrome: 104.0.5112.29
    Edge: 101.0.1210.53
    Firefox: 101.0
    Safari: 15.5
  npmPackages:
    svelte: ^3.48.0 => 3.48.0

Severity

annoyance

tanhauhau commented 2 years ago

Currently you can't dynamically pass in elements with slot attribute,

so, all of the

{#if left}
  <Btn slot="left" text="{left}" />
{/if} {#if right}
  <Btn slot="right" text="{right}" />
{/if}

in your example is considered as passed into the default

so, a workaround for this would be

{#if left && !right}
  <NavBar {title}>
    <Btn slot="left" text="{left}" />
  </NavBar>
{:else if !left && right}
  <NavBar {title}>
    <Btn slot="right" text="{right}" />
  </NavBar>
{:else if left && right}
  <NavBar {title}>
    <Btn slot="left" text="{left}" />
    <Btn slot="right" text="{right}" />
  </NavBar>
{:else if !left && !right}
  <NavBar {title} />
{/if}
borgius commented 2 years ago

Thank you for explanation and workaround, but workaround looks complicated, and will be more complicated with more props... So, may be we can convert it to feature request? That behavior looks logical and will be really useful for multiple scenarios. Thank you!