Skip to content

Add documentation for $$slots #5277

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Oct 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions site/content/docs/02-template-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -1317,6 +1317,31 @@ Named slots allow consumers to target specific areas. They can also have fallbac
</div>
```

#### [`$$slots`](slots_object)

---

`$$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 a present in `$$slots`. This allows components to render a slot (and other elements, like wrappers for styling) only if the parent provides it.

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.

```sv
<!-- App.svelte -->
<Card>
<h1 slot="title">Blog Post Title</h1>
</Card>

<!-- Card.svelte -->
<div>
<slot name="title"></slot>
{#if $$slots.description}
<!-- This slot and the <hr> before it will not render. -->
<hr>
<slot name="description"></slot>
{/if}
</div>
```

#### [`<slot let:`*name*`={`*value*`}>`](slot_let)

---
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<script>
import Project from './Project.svelte'
import Comment from './Comment.svelte'
</script>

<style>
h1 {
font-weight: 300;
margin: 0 1rem;
}

ul {
list-style: none;
padding: 0;
margin: 0.5rem;
display: flex;
}

@media (max-width: 600px) {
ul {
flex-direction: column;
}
}

li {
padding: 0.5rem;
flex: 1 1 50%;
min-width: 200px;
}
</style>

<h1>
Projects
</h1>

<ul>
<li>
<Project
title="Add Typescript support"
tasksCompleted={25}
totalTasks={57}
>
<div slot="comments">
<Comment name="Ecma Script" postedAt={new Date('2020-08-17T14:12:23')}>
<p>Those interface tests are now passing.</p>
</Comment>
</div>
</Project>
</li>
<li>
<Project
title="Update documentation"
tasksCompleted={18}
totalTasks={21}
/>
</li>
</ul>
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<script>
export let name;
export let postedAt;

$: avatar = `https://ui-avatars.com/api/?name=${name.replace(/ /g, '+')}&rounded=true&background=ff3e00&color=fff&bold=true`;
</script>

<style>
article {
background-color: #fff;
border: 1px #ccc solid;
border-radius: 4px;
padding: 1rem;
}

.header {
align-items: center;
display: flex;
}

.details {
flex: 1 1 auto;
margin-left: 0.5rem
}

h4 {
margin: 0;
}

time {
color: #777;
font-size: 0.75rem;
text-decoration: underline;
}

.body {
margin-top: 0.5rem;
}

.body :global(p) {
margin: 0;
}
</style>

<article>
<div class="header">
<img src={avatar} alt="" height="32" width="32">
<div class="details">
<h4>{name}</h4>
<time datetime={postedAt.toISOString()}>{postedAt.toLocaleDateString()}</time>
</div>
</div>
<div class="body">
<slot></slot>
</div>
</article>
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<script>
export let title;
export let tasksCompleted = 0;
export let totalTasks = 0;
</script>

<style>
article {
border: 1px #ccc solid;
border-radius: 4px;
position: relative;
}

article > div {
padding: 1.25rem;
}

article.has-discussion::after {
content: '';
background-color: #ff3e00;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
height: 20px;
position: absolute;
right: -10px;
top: -10px;
width: 20px;
}

h2,
h3 {
margin: 0 0 0.5rem;
}

h3 {
font-size: 0.875rem;
font-weight: 500;
letter-spacing: 0.08em;
text-transform: uppercase;
}

p {
color: #777;
margin: 0;
}

.discussion {
background-color: #eee;
border-top: 1px #ccc solid;
}
</style>

<article class:has-discussion={true}>
<div>
<h2>{title}</h2>
<p>{tasksCompleted}/{totalTasks} tasks completed</p>
</div>
<div class="discussion">
<h3>Comments</h3>
<slot name="comments"></slot>
</div>
</article>
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<script>
import Project from './Project.svelte'
import Comment from './Comment.svelte'
</script>

<style>
h1 {
font-weight: 300;
margin: 0 1rem;
}

ul {
list-style: none;
padding: 0;
margin: 0.5rem;
display: flex;
}

@media (max-width: 600px) {
ul {
flex-direction: column;
}
}

li {
padding: 0.5rem;
flex: 1 1 50%;
min-width: 200px;
}
</style>

<h1>
Projects
</h1>

<ul>
<li>
<Project
title="Add Typescript support"
tasksCompleted={25}
totalTasks={57}
>
<div slot="comments">
<Comment name="Ecma Script" postedAt={new Date('2020-08-17T14:12:23')}>
<p>Those interface tests are now passing.</p>
</Comment>
</div>
</Project>
</li>
<li>
<Project
title="Update documentation"
tasksCompleted={18}
totalTasks={21}
/>
</li>
</ul>
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<script>
export let name;
export let postedAt;

$: avatar = `https://ui-avatars.com/api/?name=${name.replace(/ /g, '+')}&rounded=true&background=ff3e00&color=fff&bold=true`;
</script>

<style>
article {
background-color: #fff;
border: 1px #ccc solid;
border-radius: 4px;
padding: 1rem;
}

.header {
align-items: center;
display: flex;
}

.details {
flex: 1 1 auto;
margin-left: 0.5rem
}

h4 {
margin: 0;
}

time {
color: #777;
font-size: 0.75rem;
text-decoration: underline;
}

.body {
margin-top: 0.5rem;
}

.body :global(p) {
margin: 0;
}
</style>

<article>
<div class="header">
<img src={avatar} alt="" height="32" width="32">
<div class="details">
<h4>{name}</h4>
<time datetime={postedAt.toISOString()}>{postedAt.toLocaleDateString()}</time>
</div>
</div>
<div class="body">
<slot></slot>
</div>
</article>
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<script>
export let title;
export let tasksCompleted = 0;
export let totalTasks = 0;
</script>

<style>
article {
border: 1px #ccc solid;
border-radius: 4px;
position: relative;
}

article > div {
padding: 1.25rem;
}

article.has-discussion::after {
content: '';
background-color: #ff3e00;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
height: 20px;
position: absolute;
right: -10px;
top: -10px;
width: 20px;
}

h2,
h3 {
margin: 0 0 0.5rem;
}

h3 {
font-size: 0.875rem;
font-weight: 500;
letter-spacing: 0.08em;
text-transform: uppercase;
}

p {
color: #777;
margin: 0;
}

.discussion {
background-color: #eee;
border-top: 1px #ccc solid;
}
</style>

<article class:has-discussion={$$slots.comments}>
<div>
<h2>{title}</h2>
<p>{tasksCompleted}/{totalTasks} tasks completed</p>
</div>
{#if $$slots.comments}
<div class="discussion">
<h3>Comments</h3>
<slot name="comments"></slot>
</div>
{/if}
</article>
Loading