DEV Community

Cover image for Slots in LitElement for Dummies
The Open Coder
The Open Coder

Posted on • Edited on

Slots in LitElement for Dummies

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

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:

// 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>
    `;
  }
Enter fullscreen mode Exit fullscreen mode

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:

// 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>
    `;
  }
Enter fullscreen mode Exit fullscreen mode

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>:

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

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>.

// inside render function of <learning-card>
<div slot="content"><slot></slot></div>
Enter fullscreen mode Exit fullscreen mode

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

<learning-card>
    <ul>
        <li>I'm the first bullet</li>
        <li>I'm the second bullet</li>
    </ul>
</learning-card>
Enter fullscreen mode Exit fullscreen mode

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:

Open-wc Starter App

Built with open-wc recommendations

Quickstart

To get started:

npm init @open-wc
# requires node 10 & npm 6 or higher
Enter fullscreen mode Exit fullscreen mode

Scripts

  • start runs your app for development, reloading on file changes
  • start:build runs your app after it has been built using the build command
  • build builds your app and outputs it in your dist directory
  • test runs your test suite with Web Test Runner
  • lint runs the linter for your project
  • format fixes linting and formatting errors

Tooling configs

For most of the tools, the configuration is in the package.json to reduce the amount of files in your project.

If you customize the configuration a lot, you can consider moving them to individual files.

Top comments (0)