I love Storybook and its vast addon ecosystem. Since they use Webpack the build time is pretty long though. With ES modules now supported everywhere, Snowpack is paving the way future apps will be built.
I wanted to see if I can make a tool like Storybook but on top of Snowpack so it builds fast and load fast. It also gave me an excuse to use the new routing hooks launched in React Router v6 (beta).
I'm pretty happy with how all of it turned out. So without further ado, I present to you Storycruise. 🥁🥁🥁
- Live Example- https://storycruise.vercel.app/stories
- Source Code- https://github.com/itaditya/storycruise
Storycruise was going to be a complicated project. To pull it off I had to break it into small milestones. Each milestone had a challenge attached to it. Let's look at the main three–
Setup an app which can run CSF files.
First of all I setup a React Router v6 app with Snowpack. I got a basic layout rendered on /stories/* path.
The next step was to take a story file like Button.stories.jsx and render it on the app. But wait what is this special stories file? Let me explain.
Documenting components usually requires a lot of boilerplate configuration to work. Storybook team came up with a new format to cut the effort in half. Storycruise provides the same ergonomics.
In the Button.stories.jsx file, first we default export a minimal config object to tell the path of button's stories page. Then in this file we create example components which renders the Button component. Now if we do a named export for these example components they will show up on the page.
Automatic routes for each story.
So far in the project I had to manually collect all the stories file in one giant export. This is not the ideal experience. To make it better, I created a custom Snowpack plugin.
When Snowpack runs, my plugin searches the project for all the files which end in .stories.jsx. Then it creates a virtual file which imports all these stories. This was the hardest part of the project since Snowpack is a new tool and not everything is documented.
After I had a dynamic list of imports, I was able to convert them into a list of routes. Then I fed this list to the useRouter hook.
As you can see below, when I create Button.stories.jsx file it shows up in Storycruise app instantly.
Another thing I really like in Storybook is the concept of args and controls. We can keep the template same but change the args of a story. These args can then be passed as props to our component.
This lets us document different behaviors of our component in a pretty succinct manner. Naturally I had to add it in Storycruise.
What makes it even cooler is that these args gets converted to a live editor. So people can select "lg" and the Button component will re-render with the new args.
Additional information like description and control type can be provided with argTypes. In future I'd work on getting as much information as possible from the static types of the props.
Thanks for reading. Catch you on the next one.