pull/13756/head
Rich Harris 2 years ago
parent c0fbb24ecb
commit d6f4618040

@ -2,85 +2,75 @@
title: <slot> title: <slot>
--- ---
```svelte In Svelte 5, content can be passed to components in the form of [snippets](snippet) and rendered using [render tags](@render).
<slot><!-- optional fallback --></slot>
```
```svelte In legacy mode, content inside component tags is considered _slotted content_, which can be rendered by the component using a `<slot>` element:
<slot name="x"><!-- optional fallback --></slot>
```
```svelte ```svelte
<slot prop={value} /> <!--- file: App.svelte --->
``` <script>
import Modal from './Modal.svelte';
Components can have child content, in the same way that elements can. </script>
The content is exposed in the child component using the `<slot>` element, which can contain fallback content that is rendered if no children are provided. <Modal>This is some slotted content</Modal>
```
```svelte ```svelte
<!-- Widget.svelte --> <!--- file: Modal.svelte --->
<div> <div class="modal">
<slot> <slot></slot>
this fallback content will be rendered when no content is provided, like in the first example
</slot>
</div> </div>
<!-- App.svelte -->
<Widget />
<!-- this component will render the default content -->
<Widget>
<p>this is some child content that will overwrite the default slot content</p>
</Widget>
``` ```
Note: If you want to render regular `<slot>` element, You can use `<svelte:element this="slot" />`. > [!NOTE] If you want to render a regular `<slot>` element, you can use `<svelte:element this={'slot'} />`.
> [!NOTE]
> In Svelte 5+, use snippets instead
## `<slot name="`_name_`">` ## Named slots
Named slots allow consumers to target specific areas. They can also have fallback content. A component can have _named_ slots in addition to the default slot. On the parent side, add a `slot="..."` attribute to an element, component or [`<svelte:fragment>`](legacy-svelte-fragment) directly inside the component tags.
```svelte ```svelte
<!-- Widget.svelte --> <!--- file: App.svelte --->
<div> <script>
<slot name="header">No header was provided</slot> import Modal from './Modal.svelte';
<p>Some content between header and footer</p>
<slot name="footer" /> let open = true;
</div> </script>
<!-- App.svelte --> {#if open}
<Widget> <Modal>
<h1 slot="header">Hello</h1> This is some slotted content
<p slot="footer">Copyright (c) 2019 Svelte Industries</p>
</Widget> +++<div slot="buttons">+++
<button on:click={() => open = false}>
close
</button>
+++</div>+++
</Modal>
{/if}
``` ```
Components can be placed in a named slot using the syntax `<Component slot="name" />`. On the child side, add a corresponding `<slot name="...">` element:
In order to place content in a slot without using a wrapper element, you can use the special element `<svelte:fragment>`.
```svelte ```svelte
<!-- Widget.svelte --> <!--- file: Modal.svelte --->
<div> <div class="modal">
<slot name="header">No header was provided</slot> <slot></slot>
<p>Some content between header and footer</p> <hr>
<slot name="footer" /> +++<slot name="buttons"></slot>+++
</div> </div>
```
<!-- App.svelte --> ## Fallback content
<Widget>
<HeaderComponent slot="header" /> If no slotted content is provided, a component can define fallback content by putting it inside the `<slot>` element:
<svelte:fragment slot="footer">
<p>All rights reserved.</p> ```svelte
<p>Copyright (c) 2019 Svelte Industries</p> <slot>
</svelte:fragment> This will be rendered if no slotted content is provided
</Widget> </slot>
``` ```
## `<slot key={`_value_`}>` ## Passing data to slotted content
Slots can be rendered zero or more times and can pass values _back_ to the parent using props. The parent exposes the values to the slot template using the `let:` directive. Slots can be rendered zero or more times and can pass values _back_ to the parent using props. The parent exposes the values to the slot template using the `let:` directive.
@ -122,3 +112,5 @@ Named slots can also expose values. The `let:` directive goes on the element wit
<p slot="footer">Copyright (c) 2019 Svelte Industries</p> <p slot="footer">Copyright (c) 2019 Svelte Industries</p>
</FancyList> </FancyList>
``` ```

@ -2,27 +2,26 @@
title: $$slots title: $$slots
--- ---
`$$slots` is an object whose keys are the names of the slots passed into the component by the parent. If the parent does not pass in a slot with a particular name, that name will not be present in `$$slots`. This allows components to render a slot (and other elements, like wrappers for styling) only if the parent provides it. In runes mode, we know which [snippets](snippet) were provided to a component, as they're just normal props.
Note that explicitly passing in an empty named slot will add that slot's name to `$$slots`. For example, if a parent passes `<div slot="title" />` to a child component, `$$slots.title` will be truthy within the child. In legacy mode, the way to know if content was provided for a given slot is with the `$$slots` object, whose keys are the names of the slots passed into the component by the parent.
```svelte ```svelte
<!-- Card.svelte --> <!--- file: Card.svelte --->
<div> <div>
<slot name="title" /> <slot name="title" />
{#if $$slots.description} {#if $$slots.description}
<!-- This <hr> and slot will render only if a slot named "description" is provided. --> <!-- This <hr> and slot will render only if `slot="description"` is provided. -->
<hr /> <hr />
<slot name="description" /> <slot name="description" />
{/if} {/if}
</div> </div>
```
<!-- App.svelte --> ```svelte
<!--- file: App.svelte --->
<Card> <Card>
<h1 slot="title">Blog Post Title</h1> <h1 slot="title">Blog Post Title</h1>
<!-- No slot named "description" was provided so the optional slot will not be rendered. --> <!-- No slot named "description" was provided so the optional slot will not be rendered. -->
</Card> </Card>
``` ```
> [!NOTE]
> In Svelte 5+, this concept is obsolete, as you pass snippets as component props and can check whether or not that prop is set

@ -5,14 +5,20 @@ title: <svelte:fragment>
The `<svelte:fragment>` element allows you to place content in a [named slot](/docs/special-elements#slot-slot-name-name) without wrapping it in a container DOM element. This keeps the flow layout of your document intact. The `<svelte:fragment>` element allows you to place content in a [named slot](/docs/special-elements#slot-slot-name-name) without wrapping it in a container DOM element. This keeps the flow layout of your document intact.
```svelte ```svelte
<!-- Widget.svelte --> <!--- file: Widget.svelte --->
<div> <div>
<slot name="header">No header was provided</slot> <slot name="header">No header was provided</slot>
<p>Some content between header and footer</p> <p>Some content between header and footer</p>
<slot name="footer" /> <slot name="footer" />
</div> </div>
```
```svelte
<!--- file: App.svelte --->
<script>
import Widget from './Widget.svelte';
</script>
<!-- App.svelte -->
<Widget> <Widget>
<h1 slot="header">Hello</h1> <h1 slot="header">Hello</h1>
<svelte:fragment slot="footer"> <svelte:fragment slot="footer">

@ -2,26 +2,12 @@
title: <svelte:component> title: <svelte:component>
--- ---
```svelte In runes mode, `<MyComponent>` will re-render if the value of `MyComponent` changes.
<svelte:component this={expression} />
```
The `<svelte:component>` element renders a component dynamically, using the component constructor specified as the `this` property. When the property changes, the component is destroyed and recreated. In legacy mode, it won't — we must use `<svelte:component>`, which destroys and recreates the component instance when the value of its `this` expression changes:
If `this` is falsy, no component is rendered.
```svelte ```svelte
<svelte:component this={currentSelection.component} foo={bar} /> <svelte:component this={MyComponent} />
``` ```
> [!NOTE] If `this` is falsy, no component is rendered.
> In Svelte 5+, this concept is obsolete, as you can just reference `$state` or `$derived` variables containing components
> ```svelte
> <script>
> let Component = $derived(currentSelection.component);
> </script>
>
> <Component />
> <!-- or -->
> <currentSelection.component foo={bar} />
> ```

@ -20,14 +20,14 @@ It cannot appear at the top level of your markup; it must be inside an if or eac
``` ```
> [!NOTE] > [!NOTE]
> This concept is obsolete, as you can just self-import components > This concept is obsolete, as components can import themselves:
> ```svelte > ```svelte
> <!--- file: App.svelte ---> > <!--- file: App.svelte --->
> <script> > <script>
> import Self from './App.svelte' > import Self from './App.svelte'
> export let count; > export let count;
> </script> > </script>
> >
> {#if count > 0} > {#if count > 0}
> <p>counting down... {count}</p> > <p>counting down... {count}</p>
> <Self count={count - 1} /> > <Self count={count - 1} />

@ -2,6 +2,8 @@
title: Imperative component API title: Imperative component API
--- ---
In Svelte 3 and 4, the API for interacting with a component is different than in Svelte 5. Note that this page does _not_ apply to legacy mode components in a Svelte 5 application.
## Creating a component ## Creating a component
```ts ```ts
@ -156,7 +158,7 @@ Unlike client-side components, server-side components don't have a lifespan afte
A server-side component exposes a `render` method that can be called with optional props. It returns an object with `head`, `html`, and `css` properties, where `head` contains the contents of any `<svelte:head>` elements encountered. A server-side component exposes a `render` method that can be called with optional props. It returns an object with `head`, `html`, and `css` properties, where `head` contains the contents of any `<svelte:head>` elements encountered.
You can import a Svelte component directly into Node using [`svelte/register`](/docs/svelte-register). You can import a Svelte component directly into Node using `svelte/register`.
```js ```js
// @noErrors // @noErrors

Loading…
Cancel
Save