Set up Storybook using Typescript, Material UI and Styled Components
Tags: storybook, typescript, materialui, mdx
Published: 2020-03-09 20:33:40

### Overview

In this tutorial you'll learn how to create a basic foundation for Storybook using Typescript, Material UI and Styled Components.

MDX will be used as the syntax for Storybook stories.

#### Basic React Setup

First Create React App must be installed. The following command will generate a Create React App with Typescript support:

```
npx create-react-app storybook --template typescript
```


#### Initialize Storybook

Add Storybook to the project:

```
cd storybook
npx -p @storybook/cli sb init --story-format=csf-ts
```


#### Add and configure Storybook docs

Storybook docs will add support for the Docs tab and the MDX format.

```
npm install -D @storybook/addon-docs 
```

Inside the `.storybook` folder you have to update the `main.js` file in order to support Storybook docs:

```
module.exports = {
  stories: ["../src/stories/**/*.stories.(ts|tsx|js|jsx|mdx)"],
  addons: [
    '@storybook/preset-create-react-app',
    '@storybook/addon-actions',
    '@storybook/addon-links',
    {
      name: "@storybook/addon-docs",
      options: {
        configureJSX: true
      }
    }
  ],
};

```

#### Add Material UI and Styled Components

```
npm install @material-ui/core styled-components
```

#### Check if Storybook runs correctly:

```
npm install
npm run storybook
```

You should be able to see the default stories.

#### Add a Button component

As an example, create a `components` folder inside `src` and add a `Button.tsx` file inside:

```
import styled from 'styled-components';
import Button from '@material-ui/core/Button';

const StyledButton = styled(Button)`
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border-radius: 3px;
`;

export default StyledButton;
```

Here the `Button` component from Material UI is being styled using Styled Components.

#### Add Button story

Create a `Button.stories.mdx` file inside the `stories` folder:

```
import { action } from '@storybook/addon-actions';
import { Meta, Story, Preview, Props } from "@storybook/addon-docs/blocks";
import Button from "../components/Button";

<Meta title="Material Button" />

Here's some _markdown_!

# Preview

<Preview>
  <Story name="Default">
    <Button variant="contained" onClick={action("Default button clicked")}>Default</Button>
  </Story>
  <Story name="Primary">
    <Button variant="contained" color="primary" onClick={action("Primary button clicked")}>Primary</Button>
  </Story>
  <Story name="Secondary">
    <Button variant="contained" color="secondary" onClick={action("Secondary button clicked")}>Secondary</Button>
  </Story>
</Preview>

# Props

<Props of={Button} />
```

#### Fix CSS injection order using a decorator.

Styled Components styles will be overrided by Material UI, in order to fix this a decorator must be added. 

Create a `config.js` file inside `.storybook` folder:

```
import React from "react";
import { StylesProvider } from "@material-ui/styles";
import { addDecorator, configure } from '@storybook/react';

const StylesDecorator = storyFn => (
  <StylesProvider injectFirst>
    {storyFn()}
  </StylesProvider>
);

addDecorator(StylesDecorator);
```

### Conclusion

Congrats! If you followed these steps you should now have a good foundation to start creating your own stories with a solid Storybook initial configuration.

You can find the complete code in this [github repository](https://github.com/amalv/storybook-foundation)