In the last two years there has been a monumental shift in how we approach the design and development of components for our various products. Storybook has been the catalyst for all of this. Before we had a custom documentation site for our components, or worse they were integrated directly into products/libraries that we produced. This led to a messy disorganized system where it was hard to find and use what you needed to. Storybook changed all of this and enabled use to create a “single source of truth” for both designers and developers to enable greater collaboration and code re-use.
We’ve take a very careful approach to the addons we use, those plugin’s target audience, and the way we structure our stories.
Here is an abbreviated list of the addons that we use in our Storybook and will be covered in this article:
Initially our stories weren’t organized at all. Whatever the developer writing the component thought would be a few good stories is what we went with. This lead to lots of great stories being written, but with no clear organization each component was a new documentation experience. With the help of a few addons we were able unify all of our components stories into 1 consistent pattern.
The following is how each one of our component’s stories looks in the sidebar:
Let’s breakdown what each section’s purpose is!
This page is the first thing that any developer or designer will see when browsing the Storybook. It is an “mdx-only” story that uses
@storybook-addon/docs to concatenate the top portion of the component's
README.md and any other MDX files that exist for that component. This file also heavily uses our design system to provide a cohesive experience across our component documentation.
Here is a sample
The user ends up seeing this:
This story is included with every one of our components. It utilizes
@storybook/addon-knobs to try to cover every possible use case that a component can represent. Other stories might contain some knobs usage but the
Playground is where you can see the full breadth of options.
When surveyed our users about what needed to change in our Storybook one standout piece of feedback we got from designers was that it was hard to tell what parts of a component were “flexible”. The “Visual Guide” solves this problem by using special utility component that calls out that part of the component is flexible. These utility components all render a pink box like the following:
We currently use the following set of pink box components:
FlexibleImage: A place an image or icon can be used
FlexibleTextArea: A place a text can be used
FlexibleInlineTextArea: A place an inline text can be used
FlexibleContentArea: A place where any content can be used
This folder contains all of the top-level features that are specced out in the designs we receive. Each story gets it’s own designer focused documentation that lives in the
This folder contains all other stories for a component that aren’t top-level features and tends to be developer focused examples. Some examples of what might live here:
- How two components interact
- How to integrate the component into common libraries (react-router)
- A visual test case for when we run our visual regression
- How to code a certain behavior using that component
Design Focused Addons
The main plugin that our design team utilizes is
@storybook-addon/docs. Through the
Docs tab we try to provide an experience that anyone can view and get a good understanding of the component.
Currently our design team has switched to Figma to create and share their designs. All of the specs also come with a Figma component that other teams can use to quickly build out experiences.
Before Figma we were heavily invested in Sketch and created
storybook-addon-sketch to enabled designers to download the current story as a sketch file. One really cool thing about this plugin is that the sketch file you download is whatever the current rendering of the story is. This means you can interact with the story, use
@storybook/addon-knobs or any other plugin to affect how the story renders, then when you go to download you get a sketch file representing that render!
Developer Focused Addons
We’ve talked a lot about how our Storybook serves our designers, but it also provides a great experience for developers as well.
When viewing a Storybook in
Canvas mode a user has access to the addon panel. The addon-panel is where all different facets of developer documentation live.
The first tab a user is greeted with in the addon panel is
@alisowski/addon-notes. This is a fork of the original
@storybook/addon-notes that I maintain because we use it so heavily. We use this addon to render the
README.md file for each of our components.
README.md s contain:
- A small blurb about the use for a component
- How we thought about the accessibility for that component
- Install instructions
- Detailed documentation about how to use the various code exports of the component
By rendering this info with
@alisowski/addon-notes we have top class documentation for developers too!
Our team uses typescript and jsDoc to document all of our props. Storybook will use either
react-docgen-typescript to generate the docs for your props. These can be displayed using
@storybook-addon/docs but since the
Docs tab is where our design docs live it doesn't make sense to include it there. That's why we use
storybook-addon-react-docgen to display the docgen in the addon panel. Since the prop documentation is heavily developer focused it makes most sense for us to render it there.
When it comes to displaying what is actually used to render the story there are two options
@storybook/addon-storysource shows the fuller picture of how the story is rendered it tends to be too much. Some of our stories aren't all that readable to an outside user and aren't the best way for developers to understand how to use the component.
This is where
storybook-addon-jsx shines. It only displays the JSX that is currently being used to render the story. The user gets a more focused experience and only sees the JSX needed to render and is easily copy-paste-able.
Another cool feature of
storybook-addon-jsx is that if they change any of the knobs that change is also reflected in the JSX tab!
Development Only Addons
Our “production” Storybook is meant to a great documentation site, but Storybook is also a great development tool! There are many Storybook addons that don’t make sense for a documentation website but do make sense for a development tool.
Some useful Storybook development tooling:
We use this handy trick to exclude these types of addons we use when making a production build of the Storybook. That way we can use them while developing, but our Storybook consumers aren’t bogged down by information that isn’t useful to them.
Storybook addons are easy to write! They are a powerful way to customize how Storybook works for you.
Our Storybook serves multiple products and each product has it’s own theme. We tried to find the best way to integrate a theme chooser into Storybook and landed on a toolbar addon. Toolbar addons are constantly on the screen and provide an easy way to select the theme at all times. Toolbar addons can even display when tabs other than
Canvas are showing so a user can modify the them while looking at the
Docs tab too! For this addon we store the selected theme so when you come back to the Storybook it renders with whatever theme you chose last.
How it works under the hood:
- Our themes are managed through React.Context
- It’s added as an addon in
- It also exports a decorator that wraps every story configured in
Read more about how we theme our components here.
Our journey using Storybook has come so far at this point. What started out as as a tech exploration has turned into the single source of truth for the handoff between design and development for TurboTax and related products. It’s an amazing tool that changes the way you look at component development, making you focus on creating the best components you can. The vibrant addon ecosystem means you can customize the tool to do almost anything you can think of. And if it doesn’t already exist it’s not all that hard to make your own addons!