Storybook: Create Your Own UI Component Library with React

Gülşah Vural
ÇSTech
Published in
4 min readDec 21, 2022

In this article, I’ll talk about why we need Storybook and how to start using this tool within a React application.

What is Storybook?

Storybook is an open source tool to build and test UI components in an isolated environment. It integrates with the most popular JavaScript frameworks, such as React, Vue, and Angular.

Why we should use Storybook?

Components are the most important things when building user interfaces. Many UI libraries and frameworks support developing with components. Components solve many problems but also create some. They depend on each other, so a change in one component can affect another. These can be painful to debug because they’re entangled in business logic and app context. The Storybook lets you separate your components from your main project, APIs, or business logic.

This way, you can create your own reusable components without waiting for APIs. So you can save time and code.

“Storybook runs outside of the main app so users can develop UI components in isolation without worrying about app specific dependencies and requirements.”

What about in Practice?

Storybook has been an excellent tool for us to develop our own UI components. We can create data-independent components. We do custom development, and sometimes we can use the UI component of another library. We manage each package independently of the others. Also, we integrate it easily into different projects.

We can visually test PRs to ensure they meet design requirements. PR’s became easier and more fun to review.

Storybook has made it easier for us to write better code and share the components we make with designers and other teams. This allowed us to communicate better with other teams.

“Storybook has made developing components more streamlined by allowing us to easily include technical documentation within our design system!” (Taurie Davis – Author of Building Design Systems)

Let’s get building now!

designed by Elif Yardımcı

Assume that we create a project with React and install the Storybook package.

# Add Storybook:
npx storybook init

Let’s create a button component. We pass the parameters of variant, color and label to answer the design needs.

// Button.jsx

import React from "react";

export const Button = (props) => {
const { color, variant, label, ...rest } = props;

return (
<button
className={[
"storybook-button",
`storybook-button--${color}`,
`storybook-button--${variant}`,
].join(" ")}
{...rest}
>
{label}
</button>
);
};

After, we give our styles in accordance with the button design.

In the button.css file:

/* button.css */

.storybook-button {
font-size: 12px;
line-height: 1;
display: inline-block;
height: 50px;
padding: 10px 30px;
background-color: #51b549;
color: #ffffff;
border: 1px solid #51b549;
border-radius: 5px;
position: relative;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
text-decoration: none;
text-align: center;
}

/* Secondary */

.storybook-button--secondary {
background-color: #ffffff;
color: #51b549;
}

/* Danger */

.storybook-button--danger {
border-color: #e64e41;
background-color: #e64e41;
color: #ffffff;
}

/* Variant text */

.storybook-button--text {
background-color: transparent;
border-color: transparent;
color: #3597ec;
}

Now we can write a story in it. Let’s add Button.stories.jsx and write a few stories here:

import { Button } from "./Button";
import "./button.css";

// Button.stories.jsx

export default {
title: "Components/Button v",
component: Button,
argTypes: {
variant: {
defaultValue: "contained",
control: { type: "select" },
options: ["contained", "text", "outlined"],
},
color: {
defaultValue: "primary",
control: { type: "select" },
options: ["primary", "danger", "secondary"],
},
},
};

const Template = (args) => <Button {...args} />;

// Default
export const Default = Template.bind({});

Default.args = {
label: "Button",
};

// Color Primary
export const Primary = Template.bind({});

Primary.args = {
color: "primary",
label: "Button",
};

// Color Secondary
export const Secondary = Template.bind({});

Secondary.args = {
color: "secondary",
label: "Button",
};

// Color Danger
export const Danger = Template.bind({});

Danger.args = {
color: "danger",
label: "Button",
};

// Variant Text
export const Text = Template.bind({});

Text.args = {
variant: "text",
label: "Button",
};

I defined a custom argType for the color and variant properties in the example above. In this way, we can get the control we want. I decided to use select control for them because it contains multiple values. We can see the variant and color changes in the Storybook interface in real-time. If you don’t add control in argTypes, Storybook will choose a default control for each arg. It works well with variable types such as string or boolean, but has more restricted control in other cases.

Sooo … We can see our story in the Storybook:

In Storybook, we learned how to create UI components and why we should use this tool. It’s easy to have your own UI and Storybook is a good tool for that. You can check out the website here.

Thanks for your time.

Reference:

--

--