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?
There are just two naming issues in this:
{#if elementFromChild !== null}
{@render elementFromChild()}
{/if}
let { elementForParent = $bindable() } = $props();
elementForParent = localSnippet;
<!-- ... -->
{#snippet localSnippet()}
<button>Click me</button>
{/snippet}