Adding Storybook into Your Nx Monorepo

Sergei Kendis
Beta Blog
Published in
4 min readFeb 19, 2023
image by https://github.com/storybookjs/brand

When your project scaling up, it’s becoming increasingly important to have a single source of truth which contains all the knowledge about your UI components.

To achieve this goal we will use Storybook. it’s a popular open-source tool that provides a centralized environment for showcasing components, testing them, and documenting their use and behavior.

Prerequisites:

Creating Nx workspace

run the following command in order to create a new Nx workspace

npx create-nx-workspace@latest my-workspace

choose the following options in the interactive cli (based on v15.7.0):

  • what to create: integrated monorepo
  • What to create in the new workspace: Angular
  • Application name: your angular app name for example client-app
  • Would you like to use Standalone Components in your application? no
  • Would you like to add routing? yes
  • Default stylesheet format: Sass
  • Enable distributed caching to make your CI faster: No

now grab a cup of coffee while the cli installs all the dependancies and creates your workspace.

For the example we are going to create a single button component inside an Angular library.
Create a new library by running the following command:

if @nrwl/cli not installed globally on your machine run the following command npm i -g @nrwl/cli@latest

nx g @nrwl/angular:library ui-lib --publishable --importPath @my-workspace/ui-lib

Setting Up Storybook

first we are going to install @nrwl/storybook package
open terminal in your workspace directory and run the following command:

npm install -D @nrwl/storybook

now we will generate storybook configuration to our project.

nx g @nrwl/storybook:configuration ui-lib --tsConfiguration=true

choose the following options in the interactive cli:

  • What UI framework plugin should storybook use: @storybook/angular
  • Configure a cypress e2e app to run against the storybook instance: true
  • Which Storybook builder do you want to use: Webpack

Nx will take care about all the installation and configuration, so seat back and relax.

Creating first story in storybook

in order serve storybook locally, run the following command:

nx run ui-lib:storybook

now your should be able to navigate to http://localhost:4400 and see an empty storybook

storybook running locally

lets create our button component inside ui-lib library

nx g @nrwl/angular:component button --project ui-lib

and generate story by running the following command:

nx g @nrwl/angular:stories ui-lib

choose the following options in the interactive cli:

  • do you want to generate Cypress specs as well? yes

UI component implementation

button.component.ts:

import { Component, Input } from '@angular/core';

@Component({
selector: 'my-workspace-button',
template: `<button [disabled]="isDisabled">{{ btnText }}</button> `,
styleUrls: ['./button.component.scss'],
})
export class ButtonComponent {
@Input() isDisabled = false;
@Input() btnText = '';
}

button.component.scss:

:host {
button {
height: 43px;
border-radius: 24.5px;
font-size: 16px;
min-width: 200px;
min-height: 45px;
background-color: #c61f13;
color: #fff;
border: none;
cursor: pointer;
&:disabled {
cursor: not-allowed;
filter: grayscale(100%);
}
}
}

button.component.stories.ts:

import { moduleMetadata, Story, Meta } from '@storybook/angular';
import { ButtonComponent } from './button.component';

export default {
title: 'ButtonComponent',
component: ButtonComponent,
decorators: [
moduleMetadata({
imports: [],
}),
],
} as Meta<ButtonComponent>;

const Template: Story<ButtonComponent> = (args: ButtonComponent) => ({
props: args,
});

export const Primary = Template.bind({});
Primary.args = {
isDisabled: false,
btnText: 'Learn More',
};

export const Disabled = Template.bind({});
Disabled.args = {
isDisabled: true,
btnText: 'Learn More',
};

we are passing button Inputs by args property:

Primary.args = {
isDisabled: true,
btnText: 'Learn More',
};

and the end result should be:

disabled state of the button
enabled state of the button

Conclusion

Storybook provides a powerful platform for creating, reviewing and testing UI components. By using it as a single source of truth for the project UI components, it allows to build and maintain a consistent design system.
In this article, we’ve seen how to integrate Storybook into Nx monorepo, create a new UI component, and configure Storybook to display different states of the UI component.

--

--