Boost your design system with Storybook Cartesian
As part of my investment in DesignOps, Iāve bumped into a common problem with a rather nice solution.
Storybook Cartesian is a library that automatically generates stories for all of your component variants and puts them back in your storybook in a clean and tidy way.
Having a great React component means having it take some properties and do something useful with it. Take a look at this button:
const Button = props =>(
<button
style={{color: props.color}}
enabled={!props.disabled}>
{props.text}
</button>)
To build stories for this component in your design system, you can use some common sense and want to test enabled / disabled, and a couple of colors. But what about empty text? what about a combination of disabled and empty text? does that create anything odd?
Instead of guessing all these combinations, you can generate them with storybook-cartesian.
Storybook Cartesian in action!
On the one hand, itās great to be able to click through all of the variants (instead of using knobs to force them out manually), but more importantly, if you have these stories layed out, you can get a massive test coverage with storyshots.
If youāre impatient, thereās a fully working example in the storybook-cartesian repository.
Quick Start
$ yarn add --dev storybook-cartesian
To integrate in your own project, add the following to your stories in your storybook files. Hereās a real life button being exercised to its fullest:
Understanding Cartesian Stories
The general structure for a cartesian
story is this:
cartesian(<stories>)
.add(
<seed function>,
<title renderer>,
<component renderer>,
<valid combination filter (optional)>,
<story apply function (optional)>
)
Which gets you this kind of story layout generated automatically (for now the last āAll/all variantsā is a story discussed:
Automatically generated with storybook-cartesian
Your seed
function is responsible to generate content in the form of:
Your titleRender
function gets an instance of your props and returns a string. This is where you get to build those fancy story titles that will make every generated story super visible.
const titleRender = props => `${props.one} / ${props.check}`
Your storyRender
function gets an instance of your props and returns a component. This is where you can just spread the props
out and have an easy win, or do something fancy and build out a storyfied component proper.
const componentRender = props => <Button {...props} />
And to make use of all of these with cartesian
we can now do:
cartesian(storiesOf('Button/Cartesian'))
.add(
seedfn,
titleRender,
componentRender
)
Last thing to rememberāāāyour seedfn
is a function. Currently it just returns a static bag of props, but itās a function for good reason. You can use tools like react-fake-props to generate this seed bag of props automatically as wellāāāwithout writing any verbatim seed code. In addition you can use this function to fetch content dynamically from a backend.### Validation and Advanced Rendering
Some times not all prop combinations make sense. For example if you have an isLoading
and a results
props it doesn't make sense to have both true
and results
populated:
// doesn't make sense
<SearchResults isLoading={true} results={['hello', 'world']}>
For this, we have a valid
function that we can add on top of what weāve seen until now. With it, the following will filter out this invalid combination:
cartesian(storiesOf('Button/Cartesian'))
.add(
seedfn,
titleRender,
componentRender,
props => !(props.isLoading && props.results)
)
The default valid
function, if not given, is simply returning true
always.
Some other times you might want to customize how stories get created. By default, react-cartesian
will add one story per variation. For some components types (such as a button) you might not want to āspendā an entire story.
For example, letās say you want just one story to contain all cartesian product items.
For this, we have another optional function that we can use, that gives you stories
and candidates
back with which you can do what ever you want:
Try it out!
Storybook Cartesian is a great way to get your design system going. It will allow you to spread out all these UI states that you havenāt considered with no effort at all. You can take a look on Github and youāre welcome to try it out (or submit pull requests!).
Have fun!