How to make interactive components in Storybook (ReactJS) with ‘controls’ module the fast way
Step by step guide on how to install and make the most of the controls add-on including customization and powered documentation.
For this article, I will assume that you already have set up your Storybook and want to add some interactivity to them. But if you would like to read about a more basic step-by-step guide on Storybook, please feel free to leave a comment about it 💬.
Long-story-short
- You can quickly add interactive controls to your Storybook by just adding the
controls
add-on to it. Everything will happen automatically. - You can make it even cooler by defining custom controls for each of them, description or categories for your tables through the
argTypes
object in the export default of your story. - Use
propTypes
anddefaultProps
in your components to get part of the above even faster. - Enjoy cool, interactive, and complete documentation automatically generated by Storybook based on the above.
Now, let go dive deep into these…
What about Knobs?
Adding some interactivity to our components is not something new in Storybook. Storybook offered this functionality before with the “knobs” add-on.
Knobs were (and are for some use cases) the best way of adding interactivity to our component’s stories in Storybook. It allowed live customization like this:
Whenever we wanted to add one of these dynamic options to our code, we had to write something like this in our code:
You first had to import the knobs you needed. Then you must specify which knobs are applied to each variable and what values it should take.
Although this functionality was ok, it takes some extra work. The ‘controls’ add-on allows us to do this faster, and super faster if you combine it with React.PropTypes.
Adding ‘controls’ to the storybook
This add-on is now part of the Storybook Essentials, so maybe you already have it. Check your package.json to see if it has been already installed.
In case it doesn’t, just download the npm/yarn package as a devDependency:
npm i -D @storybook/addon-controlsyarn add @storybook/addon-controls --dev
After installing, you need to manually export the add-on in the .storybook/main.js
file.
module.exports = {
addons: ['@storybook/addon-controls'],
};
Using controls
So, once you have installed the add-on you really do not need to do anything else to have an interactive component. Controls
will automatically detect your variables and make controls out of them.
Our component will receive some arguments, which is what controls detects and creates controls for.
For a story like this:
Storybook will automatically generate this:
Did you notice how I used the args
property in the export default
? This is also another cool functionality that Storybook gives us.
args
are mostly a default template of initial values for the controls we are going to use. They are passed on to the component as an argument, and you do not need to write anything extra (check the example above).
I will write a more detailed post about how to use args
in a customized way in the near future. But for now, let’s take a look at how to make the stories even cooler.
Customizing controls
Besides the automatic creation of the interactive controls, you also have the power to customize them. For instance, let’s say you have size
variable to play with. Controls will automatically create a string field for this. But wouldn’t it be nice to have a radio button that let the user choose between the options?
That's where the argTypes
property comes into the scene. This property allows you to:
- Choose a custom type of control different from the default (like a radio button instead of a text field)
- Classify the controls in categories to make them look tidier.
- Disable controls for properties you do not want the users to play with.
- Add a description (this comes really handy regards the documentation).
- Add custom controls that are not really a part of your component but helps to test and using it. Think of an icon or a list selector that interacts with your component in a way.
Let’s look at a clear example of the custom format for our controls. Check out how our controls are now categorized, and how the size
property is now shown with radio-buttons instead of a text field.
The code below is how it is achieved. Through the argTypes
property. You just need to define the property name. If it coincides with an actual property of your component the add-on will map it.
Pay special attention to the size
property and see how I defined that I wanted a radio button with options.
This part of the customization is a bit more laborious, but it’s still easier and more complete than what knobs offered.
An even faster way
If you include propTypes in the component file, you will be not also adding some type-based control to your component, but also telling controls
the exact types it should display for each case (not applicable for colour-picking though!).
For instance, when adding the propTypes for our size
prop, the add-on automatically shows it as a radio-button with the defined options. For instance:
You would only need to specify a control in the argTypes
prop of your story when:
- You want to disable a control
- You want a different control that the specified.
Same for the default values! If your component has the defaultProps
defined, ‘controls’ will automatically detect them and drop this info into the documentation.
Powered documentation
I know that setting up a fancy story as I mentioned is a bit laborious. But there is a really cool side-effect to it: documentation.
Remember that description
prop we’ve added to argTypes
? Take a look at the documentation tab of our component after defining the argTypes
:
How cool is that?! A complete but also interactive documentation. All this info in the documentation tab has been directly taken from the argTypes
property. So even though we have to take some time to define the object, we have a double benefit.
See that ‘Default’ column? That comes directly from the defaultProps
defined in our component.
Wow! that was long, yet complete I hope! Go ahead and boost your storybooks with this awesome functionality.
Peace and Code,
Nadine.