Slots in LitElement for Dummies
Published: 2021-10-24 18:25:00

Slots allow us to write very flexible web components. And no, I'm not talking about slot machines. I'm talking about the `<slot>` tag. 

If you've seen one of my other posts, I shared that I'm making a card component. Here's the design I'm following:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7wtot5nmb60fd5migufe.PNG)

I've broken this design into 4 elements:
1. An icon element
2. A banner element with header, subheader, and icon
3. A scaffold / outline for the card
4. Putting all of these together to make one card element

To keep the design flexible, we can use slots to pass any HTML into the header, subheader, and body content of the card. In order to achieve this we use the `name` attribute in the parent element and the `slot` attribute in the child. Here's what that looks like for the parent banner element:
```javascript
// render method for the <card-banner>
render() {
    return html`
      <div class="banner-wrapper" style="display: flex;">
        <card-icon type="${this.icon}" style="width: 100px"></card-icon>
        <div class="header-wrapper">
          <slot name="header"></slot>
          <slot name="subheader"></slot>
        </div>
      </div>
    `;
  }
```

Like I stated before, this banner is made up of an icon, `<card-icon>`, and a header and subheader which are the two slots inside `header-wrapper`. To pass HTML into these slots, we simply say `slot="header"` and `slot="subheader"`. Here's an example of how the HTML is slotted in the final card element that puts everything together:
```javascript
// render method for <learning-card>
render() {
    return html`
      <card-frame>
        <card-header slot="banner" type="${this.type}">
          <h2 slot="header">I'm the header</h2>
          <h3 slot="subheader">I'm the subheader</h3>
        </card-header>
        <div slot="content"><slot></slot></div>
      </card-frame>
    `;
  }
```

In this example, we pass an `<h2>` tag into the header and a `<h3>` tag into the subheader. You might also notice that I'm using slots to separate the banner and content parts of the card. You'll find that in the `<card-frame>`:

```javascript
// render method for <card-frame>
render() {
    return html`
      <div>
        <slot id="top-part" name="banner"></slot>
        <slot id="bottom-part" name="content"></slot>
      </div>
    `;
  }
```

So, the frame lets us pass HTML to a `banner` and `content` slot, and then we use `slot="header"` or `slot="subheader"` to pass the HTML we want into the `card-banner`. Finally, we have one last unnamed slot in the `<learning-card>`. 

```javascript
// inside render function of <learning-card>
<div slot="content"><slot></slot></div>
```

This inner slot let's us pass whatever we want into the `<learning-card>` content area. So when we call the card like:

```html
<learning-card>
    <ul>
        <li>I'm the first bullet</li>
        <li>I'm the second bullet</li>
    </ul>
</learning-card>
```

The `<ul>` will become the bottom content of the card similar to the bulleted lists in the design comp.


Here's the repo if you want to track the progress of this card, as it is almost finished:
{% github PenStat/penstat-project2 %}