Search code examples
componentsparameter-passingsvelte

Svelte props are not passed to slot


I have a component with a slot that I want to pass props to. However, while I can pass a variable from the parent directly to the slot, passing it directly from the component that has the slot does not work for some reason. Here is the REPL.

And the code:

<!-- App.svelte -->
<script>
    import Action from "./Action.svelte"
    import Icon from "./Icon.svelte"
    let size = 50;
</script>

<Action id="Home" isActive={true}>
  <Icon {size}/> <!-- works -->
</Action>
<!-- Action.svelte -->
<script>
    import { createEventDispatcher } from "svelte";
    const dispatch = createEventDispatcher();

    export let isActive = false;
    export let id = "unassigned";
    let size = 12;
    let strokeColor = "#f00";
    let fillColor= "#0f0";
    let fontColor = "#333";

    const enter = () => {
        if (isActive) {
            strokeColor = "#ccc";
            fillColor = "#999";
        }
    };

    const leave = () => {
        strokeColor = "#00f";
        fillColor = "#16e";
    };
</script>

<div on:mouseenter={enter} on:mouseleave={leave}>
    <slot strokeColor={strokeColor} fillColor={fillColor} test={id}/> <!-- does NOT work -->
    <div>action: {size}-{id}-{strokeColor}-{fillColor}</div>
</div>
<!-- Icon.svelte -->
<script lang="ts">
  export let size = 24;
  export let strokeColor = "#00f";
  export let fillColor = "#0f0";
  export let test = "def";

</script>

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" height={size} width={size}
  ><path
    d="M12 3L2 12h3v8h6v-6h2v6h6v-8h3L12 3zm6 15h-2v-6H9v6H7v-7.81l5-4.5 5 4.5V18z"
    fill={strokeColor} /><path
    d="M7 10.19V18h2v-6h6v6h2v-7.81l-5-4.5y"
    fill={fillColor} /></svg>
<div>
icon: {size}, {strokeColor}, {fillColor}, {test}    
</div>

{size} is correctly passed to the slot, while all the others from Action.svelte are ignored:

<slot strokeColor={strokeColor} fillColor={fillColor} test={id}/>

Any help would be appreciated!


Solution

  • That is not how slot properties work; slots can contain anything and the values are not just automatically passed to any and all contents.

    You have to declare the slot properties manually using let:... and pass them:

    <Action id="Home" isActive={true}
            let:strokeColor let:fillColor let:test>
      <Icon {size} {strokeColor} {fillColor} {test} />
    </Action>
    

    Docs