Skip to content

Instantly share code, notes, and snippets.

@arbaz52
Created December 21, 2021 07:23
Show Gist options
  • Save arbaz52/d07b4152df8f262ad9df9b2d6e3f7c96 to your computer and use it in GitHub Desktop.
Save arbaz52/d07b4152df8f262ad9df9b2d6e3f7c96 to your computer and use it in GitHub Desktop.
Setup Storybook for React project using alias imports

Storybook

Storybook streamlines the UI development, testing and documentation.

Setup Storybook

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 add webpackFinal: <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 install react-router@<replace-with-project's-react-router-dom-version>. For example, we're using react-router-dom@5.2.0 so we'll install react-router@5.2.0 by running the following command.

    yarn add react-router@5.2.0

    The reason behind this is storybook@v6 uses react-router@v6 and if the project is using an older version of react-router-dom, the react-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

Writing stories for your component

What is a story?

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment