The Ksquare Group

Automated stories with Storybook and StencilJS

Automated stories with Storybook and StencilJS

Stencil is an incredible tool that helps you create web components which you can use with Vanilla Javascript and some frameworks like React, Vue, Angular …, and combine with storybook. You can offer an incredible tool for all our community. In this article, I will show you how to save time and create all your stories in an automatic way.

Note: For this project, we are assuming that you have some basic knowledge of StencilJS

Creating our project 

First, we need a stencil project for web components. You can do this by following the instructions on the Stencil page. Also, we need to install stencil/sass and clsx. Your project should look something like this in your browser:

Image for post

Stencil starter project

Now, we will create our own component and will call mine my-button. It will have five different props (color, disabled, elevation, shape and size). Feel free to use your own component. It should look something like this:

Image for post
my-button component

With the following style: 

my-button style
Image for post

Once you have it, use it on your index.html, and see the results. If you would have used my example you should see something like this:

Image for post
my-button component with the default props

Great!! Now, we have a component to start working on. 

… 

Installing and configuring storybook 

Let’s start with the storybook configuration, since the stencil option for web components is still in alpha, we will install the storybook for HTML. 

Use the following command on your project to install storybook: 

npx sb init

Note: For this project, we are using @storybook/html version ^6.1.2, down versions will not work. 

Once storybook is up and running, add the next dependencies: 

npm install npm-run-all @storybook/addon-essentials @storybook/addon-notes @storybook/addon-viewport case --save-dev 

We will use the addon-essentials to install controls, so that anyone can interact dynamically with our components; addon-notes to charge the documentation generated automatically by stencil; addon-viewport (optional) to check our components on different screen sizes; case and npm-run-all will be used for our script to generate each story, we will cover them later. Now, let’s go to the .storybook directory and modify the main.js file as follows:

.storybook/main.js

We have changed the default storybook webpack configuration to charge our automated stories in a correct way. Now, we need to build the last version of our components in order for them to work in our stories. For this purpose, we need to add the next scripts to our package.json:

"storybook.run": "start-storybook -p 6006 -s dist", 
"storybook": "npm-run-all --parallel build storybook.run", 
"build-storybook": "build-storybook -c ./.storybook -o ../public" 

If you run storybook now, you should have a readme file created by stencil inside each component, we will use them in our automated stories. To do this first we have to create a global.d.ts file inside your src directory with the next line inside:

global.d.ts

Our first story 

Our next step is to create our first story. Inside our my-button component directory, create a file called my-button.stories.tsx, add the next code:

my-button.stories.tsx

Here, we are importing our readme file to show it as the documentation, later we will see how storybook will manage it.

Creating our script to automate stories 

Now, let’s start working on the creation of our automated stories. For this purpose, we will create a script dedicated to this. Inside your .storybook directory, create a stories directory with a file called automatedStories.js. From now on we will be adding a lot of code inside this file, so let’s start. Our first step is to create the function that will be in charge of receiving each component and story created to complete with our base render. It should look like this:

.storybook/stories/automatedStories.js (part 1)

This function receives our configs and checks if we have an object (which is the way we will create the stories we want to be processed by our script) or a function. In case, it is a function, we will let storybook manage it, but the other way we want to use our own script. Now, let’s add our configs generator:

.storybook/stories/automatedStories.js (part 2)

Here, we are getting all our Stencil Components and object for each of them who will have our custom configuration. This configuration includes our Component; states, which will be use to write extra renders we want to add to our story; args, which will include our props; argTypes, which will specify the control (check addon-controls) we want to use for each arg; and notes which will load our readme files. We have to clean our notes because addon-notes has some issues rendering tables.

Now that we have our configs covered, we can write our function to create stories, add the next code:

.storybook/stories/automatedStories.js (part 3)

Here, we are adding each stories, creating first our automated story. We are getting our props from our controls (I will explain how to do this later in our getPropsWithControlValues), adding them for our first story. We are adding a children with the createNodes function so our component is not empty inside, notice that this is optional, and creating our component element to send them to our special template, to create our template add the next function:

.storybook/stories/automatedStories.js (part 4)

Notice that you have to add our args, argTypes and notes to our story options, so they connect to our story.

Now, let’s see how to get our controls generated checking each of the stencil properties’ types, the format for generate the controls, it can be checked here

.storybook/stories/automatedStories.js (part 5)

Rendering our stories 

Now, with all of this set we have our automatedStories script finished, our last step is to use this script. Storybook has the file called preview.js to control the way stories are rendered, find/create it inside our .storybook directory, we will modify it as follows, to load the stories the way we want to.

.storybook/preview.js

Lets analyze what are we doing? We are creating our collection (My Components) and getting all our previously build components and all our created stories. Once this is done, we are creating a function that will call each collection and use our script (buildStencilStories) to generate each story automatically.

Now, add the stories.js file to each component, following the example metioned before. Run storybook and see all your stories with its own controls generated automatically. The final result should look as follows:

Autogenerated story

If you are having problems reproducing this, you can check the original code on the repo (https://github.com/MagalyMJ/stencil-automated-stories). 

Written by 

Read more about our latest news and articles