Current section: Slots 30 exercises
lesson

Intro to Slots

Loading lesson

Transcript

00:00 Sometimes you have an enormous number of components in your component library or maybe it's an internal component library that you have and you don't want to have an individual component for every single set of those compound components that you're exposing.

00:17 For example, we have this checkbox group, we have a label for that, but then you also have a combo box, you have a label for that, and then you have text that's for different things and you have a text for just a lot of combinations of different components. You don't want to have an individual compound component for every single one of these.

00:34 Well maybe you do, maybe you don't, but that's what the slots API or pattern is all about. It's for allowing you to have a single component that can be reused across all of your other reusable compound component sets. So the one liner here is slots allow you to specify an element which takes on a particular

00:53 role in the overall collection of components or compound components there. So here's our checkbox group and here's our label component. This label is going to access some special state from this checkbox group.

01:09 So the checkbox group will know how to expose the necessary information if a label happens to be rendered as one of its children. And then we've got our checkboxes that will, you know, that's all compound components here. You have your text that also is going to need the ID for the thing that it's being a description for, stuff like that.

01:28 And so this checkbox group will expose different properties and then these different elements will go and grab those properties and say, oh, okay, I need this, I need that, I need that, and then boom, I'm going to render my thing. And the slot prop, not always required, the label has an implicit slot here, but this

01:44 will say, hey, this is the role that you're supposed to take in this collection of components. So another example of this is the combo box and these examples actually are coming from React ARIA. React ARIA, as far as I'm aware, is the only library that I've seen that implements this

02:01 pattern and most likely is the creator of this pattern. Slots is actually a bit of an overloaded term because in other ecosystems, a slot is a different thing. You've got like web components and view. They have a different meaning for a slot.

02:18 Slots are a bit different than that idea. But yeah, so if you take a look at any of the example components that they have, like here we've got a list box, list box item, if we just search for slot, then here we've

02:35 got a text label, here's our description, bunch of different types of slots that you can have. And we're going to be implementing all of these things in this exercise. And this can be nested all the way down.

02:50 So the way that this is implemented, or just a way to think about this as we're getting into this, is just with context. So we've got this number field, it takes our children, we set up our state, our events, whatever, and then we create our slots object.

03:05 And so we're saying here are the possible slots that elements can fill when they're rendering inside of this number field. I can have a label, I can have a decrement and an increment slot, I have a description slot, and I have an input slot. And here are the properties, if they want to take on that role, here are the properties that they're going to need.

03:24 And then we render this special slot context. Here's our slots, and then we render out our children. And then our children will render inside of that, and they will use this special hook called Use Slot Props. We accept the props that the user is providing to us. So as we're using this, we have our value, and we have our children, and stuff like that.

03:44 So we're going to accept those props. We're going to pass those along to the special Use Slot Props hook. And we're going to say, hey, my default slot is input. So if they don't provide a slot prop for me, like here, we don't have a slot on this label, but we do have a slot prop on the text.

04:00 So if they don't provide one, then this is my default slot name. And so I want to take on the role of this input, because that's the type of component I am. And then we will return the input with all of those props. And so this Use Slot Props, that hook is responsible for going to the slot context,

04:19 grabbing all of the slot information. It's going to look up this input, and it's going to find this, and it's going to say, okay, here, great. There's my object of all of the props. I'm going to merge that with the props I've been given, so that the props I've been given can override some of those things if we need to for some reason.

04:37 Or I'm going to merge them together, so that callbacks are going to be called together, stuff like that. And then I'm going to return a new props object that the input can then use. And so you'll have a whole bunch of components that are like this, that are all slottable, that can take on a role in a set of compound components.

04:56 And then you can reuse these in a bunch of different sets of compound components, wherever they are. Pretty powerful and flexible pattern. Maybe a bit of a mind bend in some ways, but I think that you can manage this, and I'm looking forward to getting into it. So let's do.