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:
I've broken this design into 4 elements:
- An icon element
- A banner element with header, subheader, and icon
- A scaffold / outline for the card
- 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>
`;
}
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>
`;
}
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>
`;
}
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>
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>
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
Quickstart
To get started:
npm init @open-wc
# requires node 10 & npm 6 or higher
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 yourdist
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)