javascripttypescriptdomsvelte

Is it possible to make a bindable snippet in Svelte 5?


I have two components, a parent and a child. I want to define some content in the child that isn't rendered in its DOM hierarchy, but rather rendered by the parent in its own hierarchy.

My child component has a bindable prop that the snippet should get assigned to:

<script lang="ts">
    import { type Snippet } from "svelte";
    
    let {
        elementForParent = $bindable(),
    } : {
        elementForParent: () => Snippet;
    } = $props();
</script>

<p>Child content</p>

{#snippet elementForParent()}
    <button>Click me</button>
{/snippet}

Which is bound to and read in the parent:

<script lang="ts">
    import { type Snippet } from "svelte";
    import Child from "./Child.svelte";

    let elementFromChild: (() => Snippet) | null = $state(null);
</script>

<div>
    <p>Some parent content</p>
    <Child bind:elementForParent={elementFromChild}></Child>

    <div>
        <p>Somewhere else in the parent heirarchy, we want to put content defined by the child:</p>
        <div style="background-color: aqua;">
            {#if elementForParent !== null}
                {@render elementForParent()}
            {/if}
        </div>
    </div>
</div>

However, this doesn't work (REPL link). Am I missing something in the implementation, or is there another way to achieve this?


Solution

  • There are just two naming issues in this:

    (Adjusted Playground)