How to combine Web Components with Storybook; a match made in heaven

Stijn Koopal
Storybook
Published in
4 min readMar 16, 2018

So you have been designing and implementing beautiful standalone web components. Yet, you were only able see them at work in your app itself, only in combination with other components. Doesn’t that defeat the purpose of a standalone component? And wouldn’t it be way easier if you could implement components one by one? Meet Storybook.

Storybook allows you to develop and test your components in isolation. To quote their github:

Storybook is a development environment for UI components. It allows you to browse a component library, view the different states of each component, and interactively develop and test components.

A UI component in this case is framework independent. Storybook supports React (+Native), Angular, Vue and as of v3.4.0 it also supports Polymer 2! Go Web Components✨✨

At my current client we are using Polymer 2.5 with Storybook, it works like a sunshine! This post will show you what this setup looks like. On this GitHub repo you can find the source code.

I expect some knowledge of the Web Components standard in this post.

Getting started

Let’s get to it! Storybook comes with a CLI that is capable of detecting the framework used in the current working directory. We need this CLI as a global dependency, and we need a version of at least v.3.4.0. After the CLI has been installed, the getstorybook command will install Storybook for your project. Run the following commands from your command line:

This will install Storybook through npm (even though you use bower for Polymer). It will also generate a .storybook directory that contains Storybook configuration.

To start storybook run npm storybookand open uphttp://localhost:6006.

Your first story!

Allrighty, that was easy. Time to build our first story.

Simple story of a progress-bar

Let’s assume that we have a web component progress-bar with a few properties:
value: the percentage of the filled bar; a number between 0 and 100.
reverse: whether the bar is from right-to-left.
hidePercentage: whether the percentage text is hidden.

To add a storybook for this component, we add a file progress-bar.stories.js with the following contents.

Two important things to notice here. We import the html file of the component itself. This could as well be a js file if you intend to use the template() function.

Notice that we return the component as an HTML string. This is the first -and most simple- scenario that Storybook supports for rendering web components.

Dynamic component state and eventing

The second option that Storybook supports is rendering an instantiated Element. We can build an element with document.createElement. It will create an element based on the tag-name you give it. In our case, we can provide progress-bar as the tag-name.

This example will yield the exact same result as the simple scenario where we provided an HTML string.

The story with document.createElement is more verbose and tedious, but it provides for more flexibility. We can now not only pass more complex types to properties, but we can also attach event handlers.

Let’s explore a more complex example with Storybook actions and knobs.

This story provides buttons and sliders within Storybook to configure the displayed component. It will also show a panel with actions dispatched from the component. More specifically, in this case it will listen for the value-change event.

Story of a progress-bar with knobs.

Styling

Our progress-bar component can be styled from outside the component by utilizing CSS custom properties. To set those variables from a story, one can use the following code.

Styled progress-bar

Slots

Slots are part of the web component standard. They are placeholders in your component that can be filled with markup from outside the component. Think of child components in React.

Using the method above, we have to create an element for every slot that we need to fill. Below you can find an example of that. Note that we assign the slot property to the child element that fills a specific slot.

Creating a configured component with slots and CSS custom propertiesis quite tedious. But do not grieve, there is a solution!

BONUS: lit-html

With the introduction of Polymer 3 (preview), also came the introduction of lit-html.

lit-html lets you write HTML templates with JavaScript template literals, and efficiently render and re-render those templates to DOM.

As of v4.0.0-alpha4 lit-htmlis incorporated in the core of Storybook. Consider the following example.

Whoop, that’s a big improvement over previous examples! Way more concise and less verbose, and we added both some CSS custom properties and slots. Great job :)

That’s it! If you want to experiment yourself, please find some examples on GitHub and try for yourself.

You like this post? Use the Clap and/or share buttons below!

--

--