Storybook is a set of libraries that lets us create components and preview them by passing in various attributes to them. The recent release of Storybook 6 included many convenient new features. Without further ado, let’s take a look at the new features and how to use them.
Listen to our podcast episode on Storybook here.
Zero-config setup
With Storybook 6, we can build a Storybook with ease: all we have to do is run npx sb init
on our project and we have Storybook added.
If we wanted to add Storybook to a React project created with create-react-app, for example, we’d just use that command. Do note, however, that npx sb init
only works with existing projects and can’t be used on an empty project folder.
So, to use Storybook with a React project, we first run:
npx create-react-app storybook-project
This creates the storybook-project
React project. Then, we go to the storybook-project
folder and run npx sb init
to add Storybook to it.
To upgrade an existing Storybook project to the latest version, we run npx sb upgrade
to install it. We’d then run yarn add @storybook/addon-essentials --dev
to install the addons, which render the content we see below the preview of the component.
The Storybook Essentials package has a few useful addons for changing the viewport in which we can preview our component. It also has an addon that allows us to document our component using either JSX or MDX code. (MDX is a mix of Markdown and JSX.)
Other addons include:
- The actions addon: Lets us log event objects emitted from various events, such as clicks, mouseover, keyboard events, etc.
- The backgrounds addon: Lets us set the background to our preferred color when previewing our component
- The toolbars addon: Lets us customize the toolbar at the top of the Storybook screen with our own preferences
TypeScript support is also built-in with Storybook 6, so we can immediately use TypeScript out of the box without extra configuration.
Args for stories
In Storybook, args are attributes that we pass into our components to change it. This lets us make preset configurations for our component so that we can preview them.
We can set the args in the story files. For example, if we have a React Storybook project, we can create our components and stories as follows:
//src/stories/Button.js import React from 'react'; import PropTypes from 'prop-types'; import './button.css'; export const Button = ({ primary, backgroundColor, size, label, ...props }) => { const mode = primary ? 'button-primary' : 'button-secondary'; return ( <button type="button" className={['button', `button-${size}`, mode].join(' ')} style={backgroundColor && { backgroundColor }} {...props} > {label} </button> ); }; Button.propTypes = { primary: PropTypes.bool, backgroundColor: PropTypes.string, size: PropTypes.oneOf(['small', 'medium', 'large']), label: PropTypes.string.isRequired, onClick: PropTypes.func, }; Button.defaultProps = { backgroundColor: null, primary: false, size: 'medium', onClick: undefined, };
//src/stories/button.css .button { font-weight: 700; border: 0; border-radius: 3em; cursor: pointer; display: inline-block; line-height: 1; } .button-primary { color: white; background-color: #1ea7fd; } .button-secondary { color: #333; background-color: transparent; } .button-small { font-size: 12px; padding: 10px; } .button-medium { font-size: 14px; padding: 11px; } .button-large { font-size: 16px; padding: 12px; }
//src/stories/Button.stories.js import React from 'react'; import { Button } from './Button'; export default { title: 'Example/Button', component: Button, argTypes: { backgroundColor: { control: 'color' }, }, }; const Template = (args) => <Button {...args} />; export const Primary = Template.bind({}); Primary.args = { primary: true, label: 'Button', }; export const Secondary = Template.bind({}); Secondary.args = { label: 'Button', }; export const Large = Template.bind({}); Large.args = { size: 'large', label: 'Button', }; export const Small = Template.bind({}); Small.args = { size: 'small', label: 'Button', };
The Button.js
file has the component file, and the button.css
has the styles for the Button
component.
The Button
components takes several props:
- The
primary
prop lets us set the class for to style the button in various ways backgroundColor
set the background colorsize
sets the sizelabel
sets the button text
The rest of the props are passed into the button
element.
Below that, we add some prop type validations so that we can set our args properly and let Storybook pick the controls for the args. primary
is a Boolean, so it’ll be displayed as a checkbox button. backgroundColor
is a string.
size
can be one of three values, so Storybook will create a dropdown for it automatically to let us select the value. label
is a string prop, so it’ll show as a text input. The input controls are in the Controls tab of the Storybook screen below the component preview.
The args are set in the Button.stories.js
file, which is a file with the stories. Storybook will pick up any file that ends with stories.js
or stories.ts
as a story files.
The argTypes
property lets us set the control for our args. In our example, we set the backgroundColor
prop to be controlled with the 'color'
control, which is the color picker.
Below that, we have our stories code. We create a template from the Button
component with our Template
function. It takes the args we pass in and passes them all off to the Button
.
Then, we call Template.bind
to let us pass the args as props to Button
by setting the args
property to an object with the props.
More great articles from LogRocket:
- Don't miss a moment with The Replay, a curated newsletter from LogRocket
- Learn how LogRocket's Galileo cuts through the noise to proactively resolve issues in your app
- Use React's useEffect to optimize your application's performance
- Switch between multiple versions of Node
- Discover how to use the React children prop with TypeScript
- Explore creating a custom mouse cursor with CSS
- Advisory boards aren’t just for executives. Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Template.bind
returns a story object, which we can configure with args. This is a convenient way to set the props that we want to preview in our story.
Live-edit UI components
The Controls tab has all the form controls that we can use to set our component’s props. Storybook picks up the props and displays the controls according to the prop type.
Also, we can set the form control type as we wish in the stories file, as we’ve seen in the argTypes
property in the previous sections’ example. With this, we can set the props live in the Storybook screen and see what the output looks like in the Canvas tab.
The backgroundColor
prop’s value is changed with a color picker. The primary
prop is changed with a toggle button that lets us set it to true
or false
. And the size
prop is controlled with a dropdown since it can only be one of three values.
Storybook does the work automatically unless we change the control types ourselves. This is a very useful feature that lets us change our component without changing any code.
Combine multiple Storybooks
Storybook 6 introduces the ability to combine multiple Storybook projects by referencing different Storybook projects in another project.
We can do this by adding the following code in the .storybook/main.js
file:
module.exports = { //... refs: { react: { title: "React", url: 'http://localhost:6007' }, angular: { title: "Angular", url: 'http://localhost:6008' } } }
This lets us load multiple Storybook projects’ stories in one project. Now, if we run npm run storybook
, we’ll see all the Storybook stories displayed from both projects on the left sidebar.
The title
value is displayed in the left sidebar, and the url
has the URL to reach the Storybook project.
Conclusion
Storybook 6 comes with many useful new features. Storybook setup in existing projects can now be done with one command if you have a project that Storybook supports. We can use args to preset props in stories and preview them easily, and we can reference another Storybook project from another with minimal configuration.
Get set up with LogRocket's modern error tracking in minutes:
- Visit https://logrocket.com/signup/ to get an app ID
- Install LogRocket via npm or script tag.
LogRocket.init()
must be called client-side, not server-side - (Optional) Install plugins for deeper integrations with your stack:
- Redux middleware
- NgRx middleware
- Vuex plugin
$ npm i --save logrocket
// Code:
import LogRocket from 'logrocket';
LogRocket.init('app/id');
Add to your HTML:
<script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
<script>window.LogRocket && window.LogRocket.init('app/id');</script>