Check out a free preview of the full Svelte Fundamentals course

The "Slots" Lesson is part of the full, Svelte Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:

Rich discusses using and naming slot elements to define where child components are accepted. Slot fallbacks, slot props, and checking slot content are also covered in this segment.


Transcript from the "Slots" Lesson

>> Okay, so just like elements can have children, like an example here where a div has a paragraph inside it certain components. But before a component can accept children it needs to know where it should put them. And for that we use the slot element, inside our card.svelte we'll add a slot, like so I can now put the things inside the card component in app.svelte.

That was what we call a default slot. So anything that goes directly inside the card component goes into the default slot element. But sometimes you need more control over placement and for those cases we have something called named slots. Inside the card.svelte component we've got sorry inside here, we've got a span slot = telephone and a span slot = company and a span slot = address.

We need to create corresponding slots for all of that content inside card.svelte. At the top we'll add this header element. Got one for the telephone, one for the company. And then below the default slot we'll add a footer. With a slot for the address. Now this card is pretty close to what we want but we have in the top right the name of the company has a small element inside it and the small element is expressed in app.svelte here.

And because that's where the element lives, that's where the styles also need to go. Are the contents of the card component inherit styles that are declared in the style tag of card.svelte, but ultimately, the styles belong to the component where the elements live. So if you wanna add some styles for that small element, we're gonna need to do it in the style tag of app.svelte.

We wanna add a display = block so that it falls onto its own line. Then we need to give it a smaller font size and wanna align it to the right. Like so. Alternatively, we could have used the global modifier and put the styles inside the card.svelte to target all small elements inside the inside the div with the .card class.

It really depends on who you want to be in control of that styling. Now we have two of these cards, in one of them we have some content. And then in the other one we haven't yet specified any content and a component can specify fallbacks for any slots that are left empty by just putting it inside the slot element so over in card.svelte inside the slot we can add.

Some fallback content reminding you to put the telephone number on the card. If we make that a little bit bigger, you can see it there in the top left. And we'll do the same thing for the company name. Do it for the default slot. And finally, for the address And then, of course, in app.svelte if we start filling these details out, it will use the values that are passed in instead of the fallback.

Right, they don't have any question about the component composition API's. Okay, so in some situations you will need to pass data from a component back into the parent that is passing in the slotted content, which is a little bit of a head scratcher until you see it in action.

So here we have a component called FilterableList, which given some data, allows us to filter the contents of that data based on the field that we've provided. So here we have a whole bunch of CSS named colors, this is every, I believe CSS named color with its corresponding hex value.

And we wanna be able to filter this list like find all of the orange colors for example, which almost works. There are three orange colors, but they're not being rendered correctly. And that's because we're not passing data from the FilterableList back in to the app. First thing we need to do is pass the data into the slot.

So inside our FilterableList we're gonna pass the item into there, just like any component prop. And then on the other side of the equation, where it's being used in app.svelte, we need to add something called the let binding, let:item = row. And what you'll find now is that all of the data is being rendered inside the FilterableList.

And if I take the word orange, we'll see that there are in fact three orange colors, DarkOrange, Orange, and OrangeRed. And finally up here, we began by using Alice Blue for everything which is the first row in that array of data, we can now get rid of that because it's not being referenced anywhere.

So you can do the same thing with named slots, you put the let binding on the element with the slot attribute as opposed to on the component itself. And this allows you to compose components in fairly complex ways. Finally, in some cases, you might want to vary the contents of the component based on whether slotted content has been provided.

So for example, in app.svelte, we have this header which is providing this banner at the top here if we get rid of that, then it will no longer render, but we're left with this ugly double border effect because inside FilterableList, we're rendering div class = header regardless of whether or not it was provided.

And we can fix that using the special $$slots variable, which is available to components. If the header slot was provided, then that will be true, if not, then it is not true and we've got rid of that double border.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now