John Au-Yeung I'm a web developer interested in JavaScript stuff.

What’s new in Storybook 6

4 min read 1214

What's New In Storybook 6

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 color
  • size sets the size
  • label 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:


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:

  1. Visit https://logrocket.com/signup/ to get an app ID
  2. Install LogRocket via npm or script tag. LogRocket.init() must be called client-side, not server-side
  3. $ 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>
  4. (Optional) Install plugins for deeper integrations with your stack:
    • Redux middleware
    • NgRx middleware
    • Vuex plugin
Get started now
John Au-Yeung I'm a web developer interested in JavaScript stuff.

Leave a Reply