Storybook streamlines the UI development, testing and documentation.
In order to setup storybook in an already existing react app, we will follow the following steps.
-
Use the storybook CLI to install it in a single command. Run the following command inside your existing project's root directory:
npx sb init
-
ALIAS IMPORTS: As we're using alias imports, we need to notify/tell storybook how to resolve alias imports. Inside the
.storybook/main.js
addwebpackFinal: <replace-with-alias-imports-resolver-function>
field inside the default export object. Example:/** .storybook/main.js */ const mapAlias = require("../config-overrides"); module.exports = { stories: [ "../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)", ], addons: [ "@storybook/addon-links", "@storybook/addon-essentials", "@storybook/preset-create-react-app", ], framework: "@storybook/react", webpackFinal: mapAlias, };
/** example config-overrides.js */ const rewireAlias = require("react-app-rewire-alias"); module.exports = function override(config) { return rewireAlias.alias({ components: "src/components", assets: "src/assets", styles: "src/styles", general: "src/general", context: "src/context", services: "src/services", configs: "src/configs", models: "src/models", routes: "src/routes", Layout: "src/Layout", })(config); };
-
OLDER VERSION OF REACT-ROUTER-DOM: If your project is using an older version of
react-router-dom
i.e. @v6, we'll need to installreact-router@<replace-with-project's-react-router-dom-version>
. For example, we're usingreact-router-dom@5.2.0
so we'll installreact-router@5.2.0
by running the following command.yarn add react-router@5.2.0
The reason behind this is
storybook@v6
usesreact-router@v6
and if the project is using an older version ofreact-router-dom
, thereact-router-dom
is updated to use the latest version. -
STYLED-COMPONENTS THEMING: If the project is using
styled-components
and utilizing its theming API, we need to wrap our component inside the story template with the theme provider. For example:/** stories/Volume.stories.tsx */ import Volume from "components/volume"; import { theme } from "assets/theme"; const Template: ComponentStory<typeof Volume> = (args) => { const [value, setValue] = useState(0); return ( <ThemeProvider theme={theme}> <Volume {...args} value={value} onChange={setValue} /> </ThemeProvider> ); };
-
Now to see if everything is working as intended, we need to run the storybook using the following command. When it has started, it will open storybook inside a new tab.
yarn storybook
To write stories for a component, create a file inside the stories/
directory. The file name should be the component's name followed by stories.tsx
. For example, Volume.stories.tsx
.
Inside the file we have just created, export ComponentMeta<typeof <replace-with-component-name>>
. For example:
/** stories/Volume.stories.ts */
// component we're writing stories for
import Volume from "components/Volume";
import { ComponentMeta } from "@storybook/react";
export default {
// component we're writing stories for
component: Volume,
// (optional) https://storybook.js.org/docs/react/get-started/whats-a-story
title: "components/Volume",
// (optional) https://storybook.js.org/docs/react/writing-stories/args
argTypes: {
// this prop accepts only two options, so we need a radio
variation: {
options: ["vertical", "horizontal"],
control: { type: "radio" },
},
},
} as ComponentMeta<typeof Volume>;
Now that we have written the meta information about the component/stories. We will write stories for it. To write stories, we first need to create a template that will act as a base to writing stories. Inside the file we exported meta information about the stories, we will add the template
/** stories/Volume.stories.ts */
import { ComponentStory } from "@storybook/react";
const Template: ComponentStory<typeof Volume> = (args) => {
const [value, setValue] = useState(0);
return (
<ThemeProvider theme={theme}>
<Volume {...args} value={value} onChange={setValue} />
</ThemeProvider>
);
};
Now that we have the template ready, we can start with writing stories. This document answers the question "What's a story?", but in short a story is basically how a component renders based on props it receives. It is a named export following PascalCase for naming. The props are passed to the stories by storing object containing the props inside the story's args
field.
/** stories/Volume.stories.ts */
export const Horizontal = Template.bind({});
Horizontal.args = {
variation: "horizontal",
};
export const Vertical = Template.bind({});
Vertical.args = {
variation: "vertical",
};
We're done with writing the stories. In order to view the stories, we need to start the storybook server if we have not yet. To start the server run:
yarn storybook
This when finished compiling, will open storybook inside a new tab on the default browser. You can update the stories at runtime and they will be updated as soon as you save the file(s).