Storybook – Component Driven UI Development

By Richard O

If you are a React developer like me, you know that React “best practices” urge building components from the bottom up – starting with the smallest elements of a page like a button or a text input, then combining those elements into larger components and so on. But when you have a team of developers all with their hands in the same code repository, without excellent communication you risk duplication of effort and functional conflicts. Programmers recreate the same lowerlevel components or make components with competing or conflicting usage and style. This leads to bloated bundles that run slower and are prone to bugs. It also makes changes and refactoring more difficult.

While researching more effective and scalable UI development workflows, I came across a tool called Storybook that can help. Storybook is a tool that facilitates sharing and documentation of UI components. It organizes components, manages the process of component creation, and makes it easier to find reusable components that have already been created. The benefits of Storybook scale with the size and complexity of the code repository.

Developing with Storybook encourages good architecture by providing a sandbox for loose coupling of components as each component is developed independently. This means more isolated components that don’t have unrelated props passed to them which decreases the amount of cascading effects a change may have. You achieve this in Storybook by creating “stories” for components, which is just another way of describing and detailing different component states.

  • What does this button look like when it’s loading?
  • What does this form look like when it’s on a smaller screen?
  • What does this text input look like when I need to show an error?
  • What does a header look like when a user is logged in?

Usage

A simple button component and related story using React and TypeScript story might look like this:

// Button.tsx

import React from ‘react’;

import ‘./button.css’;

interface ButtonProps {

  primary?: boolean;

  backgroundColor?: string;

  size?: ‘small’ | ‘medium’ | ‘large’;

  label: string;

  onClick?: () => void;

}

export const Button = ({

  primary = false,

  size = ‘medium’,

  backgroundColor,

  label,

  …props

}: ButtonProps) => {

  const mode = primary ? ‘storybook-button–primary’ : ‘storybook-button–secondary’;

  return (

    <button

      type=”button”

      className={[‘storybook-button’, `storybook-button–${size}`, mode].join(‘ ‘)}

      style={{ backgroundColor }}

      {…props}

    >

      {label}

    </button>

  );

};

// Button.stories.tsx

import React from ‘react’;

import { ComponentStory, ComponentMeta } from ‘@storybook/react’;

import { Button } from ‘./Button’;

export default {

  title: ‘Example/Button’,

  component: Button,

  argTypes: {

    backgroundColor: { control: ‘color’ },

  },

} as ComponentMeta<typeof Button>;

const Template: ComponentStory<typeof Button> = (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’,

};

In the first snippet (Button.tsx), we’ve created a simple Button component that takes in 5 props:

  1. primary?: boolean;
  2. backgroundColor?: string;
  3. size?: ‘small’ | ‘medium’ | ‘large’;
  4. label: string;
  5. onClick?: () => void;

And then, in Button.stories.tsx, we’ve provided different test arguments like label and size that will render in the Storybook that looks something like this:

As you can see, all the props are displayed that were given to the component as well as different states that we can control. Here is a live Storybook created by the BBC: https://www.bbc.co.uk/iplayer/storybook/index.html?path=/story/style-guide–colours.

A simple workflow could be to start with designing out a basic structure using Figma, create the components in code, give back to the design team for feedback, and then integrate into the web page.

For additional resources into Storybook and component-driven development, here are some sites to get started:

https://storybook.js.org/docs/react/why-storybook
https://www.componentdriven.org/
https://storybook.js.org/tutorials/intro-to-storybook/react/en/get-started/