Miloš Zeljko

Storybook and Angular: Winning Combination for Development of Interactive UIs

Miloš Zeljko
April 1, 2023 10 mins to read
Share

In today’s world of web development, creating interactive and visually appealing User Interfaces (UIs) is essential for the success of any application. With the exponential growth of web applications, it’s crucial to have tools that simplify and streamline the development process. This is where the powerful combination of Angular and Storybook comes into play.

Angular is a widely popular framework for building dynamic and responsive web applications. It is known for its ease of use and strong development community. Storybook is an open-source tool that enables developers to build and test UI components in isolation. Combined, these tools offer an excellent solution for creating and managing interactive UIs efficiently.

In this blog, we’ll explore how Storybook and Angular work together, their benefits in tandem, and a step-by-step guide to integrating Storybook into your Angular project. Additionally, we’ll delve into advanced techniques and best practices for using them together. Let’s dive in!

What is the Storybook?

Storybook is an open-source tool designed to help developers build, organize, and test UI components in isolation from the rest of the application. It serves as a sandbox environment, allowing developers to create and iterate on components without affecting the main application. This approach is beneficial for large-scale applications with complex UIs, where it’s crucial to maintain consistency and ensure components work well together.

Why use Storybook with Angular?

Integrating Storybook with Angular offers several advantages for developers, including:

  • Faster Development: By working on components independently, developers can iterate more quickly without impacting the main application. This results in faster development cycles and reduced time to market.
  • Consistent UI: Storybook encourages the creation of a “component library” that serves as a single source of truth for UI components. This helps maintain consistency across the application and ensures that components adhere to a unified design system.
  • Improved Collaboration: Since Storybook generates a visual catalog of components, designers and developers can collaborate more effectively, bridging the gap between design and implementation.
  • Simplified Testing: Storybook makes it easy to test components in isolation, ensuring that they function correctly before integrating them into the main application. This reduces the likelihood of introducing bugs and simplifies the debugging process.

Setting up an Angular project with Storybook

Now that we’ve discussed the benefits of using Storybook with Angular, let’s walk through the steps to set up an Angular project with Storybook:


1. Ensure that you have Node.js and npm installed on your system.
2. Install the Angular CLI globally by running the following command:

npm install -g @angular/cli

3. Create a new Angular project using the Angular CLI:

ng new my-angular-storybook-project

Replace my-angular-storybook-project with your desired project name. Follow the prompts to customize your project, and then navigate to the project directory:

cd my-angular-storybook-project

4. Initialize Storybook in your project:

npx storybook init

This command will automatically detect you are using Angular and set up the necessary configuration files and dependencies.

5. Start Storybook by running:

npm run storybook

Now, open your browser and navigate to http://localhost:6006 to see your Storybook instance up and running.

storybook 1

Creating and testing Angular components with Storybook

With the Angular project set up and Storybook running, let’s create an example component and see how to use Storybook to build and test it:

Generate a new Angular component using the Angular CLI:

ng generate component my-component

This command will create a new component with the associated files. Modify the HTML file to look like this:

<p [ngStyle]="{'color': labelColor}" (click)="clicked.emit($event)">{{label}}</p>
my-component.component.html

Now modify the typescript file:

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

@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.component.html',
  styleUrls: ['./my-component.component.scss']
})
export class MyComponentComponent {
  @Input() labelColor = '#000000';
  @Input() label = '';
  @Output() clicked = new EventEmitter<Event>();
}
my-component.component.ts

Our component is ready! Let us now see how we can use the Storybook to see it and play around with its inputs and outputs.

Create a new Storybook story for my-component:

Inside the src/app/my-component folder, create a new file named my-component.stories.ts. Add the following content to the file:

import { Meta, Story } from '@storybook/angular/';

import { MyComponentComponent } from './my-component.component';

export default {
  title: 'MyComponent',
  component: MyComponentComponent,
  argTypes: {
    label: { control: 'text' },
    labelColor: { control: 'color' },
    clicked: { action: 'User clicked me!'},
  }
} as Meta;

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

export const Primary = Template.bind({});
Primary.args = {
  label: 'First Variation',
};

export const Secondary = Template.bind({});
Secondary.args = {
  label: 'Second Variation',
  labelColor: '#ff0000'
};
my-component.stories.ts

This code defines two stories called Primary and Secondary for my-component, which present distinct default inputs for my-component, thereby simplifying the process for fellow developers on our team to grasp the complete capabilities of our components. This is achieved by enabling them to view the visual outcome within the Storybook‘s component catalog.

View the button component in Storybook:

With Storybook running, refresh your browser at http://localhost:6006. You should now see the MyComponent listed in Storybook‘s component catalog. Click on it to view the component and interact with it.

storybook 2

Under the Controls tab on the bottom panel, we can see a list of all inputs and outputs. We can modify those default values to see changes live on the canvas above. Each control can be assigned a type to help Storybook display the right control type to us, making it easier to modify the value of inputs. The type of control is defined inside argsType in the default export of the stories.ts file:

export default {
  title: 'MyComponent',
  component: MyComponentComponent,
  argTypes: {
    label: { control: 'text' },
    labelColor: { control: 'color' },
    clicked: { action: 'User clicked me!'},
  }
} as Meta;
my-component.stories.ts

Storybook will try to decide the type on his own, but we should help him and provide the type we expect him to use. Here is the list of all possible control types:

Data TypeControlDescription
booleanbooleanProvides a toggle for switching between possible states.
argTypes: { active: { control: 'boolean' }}
numbernumberProvides a numeric input to include the range of all possible values.
argTypes: { even: { control: { type: 'number', min:1, max:30, step: 2 } }}
rangeProvides a range slider component to include all possible values.
argTypes: { odd: { control: { type: 'range', min: 1, max: 30, step: 3 } }}
objectobjectProvides a JSON-based editor component to handle the object’s values.
Also allows edition in raw mode.
argTypes: { user: { control: 'object' }}
arrayobjectProvides a JSON-based editor component to handle the values of the array.
Also allows edition in raw mode.
argTypes: { odd: { control: 'object' }}
fileProvides a file input component that returns an array of URLs.
Can be further customized to accept specific file types.
argTypes: { avatar: { control: { type: 'file', accept: '.png' } }}
enumradioProvides a set of radio buttons based on the available options.
argTypes: { contact: { control: 'radio', options: ['email', 'phone', 'mail'] }}
inline-radioProvides a set of inlined radio buttons based on the available options.
argTypes: { contact: { control: 'inline-radio', options: ['email', 'phone', 'mail'] }}
checkProvides a set of checkbox components for selecting multiple options.
argTypes: { contact: { control: 'check', options: ['email', 'phone', 'mail'] }}
inline-checkProvides a set of inlined checkbox components for selecting multiple options.
argTypes: { contact: { control: 'inline-check', options: ['email', 'phone', 'mail'] }}
selectProvides a drop-down list component to handle single value selection. argTypes: { age: { control: 'select', options: [20, 30, 40, 50] }}
multi-selectProvides a drop-down list that allows multiple selected values. argTypes: { countries: { control: 'multi-select', options: ['USA', 'Canada', 'Mexico'] }}
stringtextProvides a freeform text input.
argTypes: { label: { control: 'text' }}
colorProvides a color picker component to handle color values.
Can be additionally configured to include a set of color presets.
argTypes: { color: { control: { type: 'color', presetColors: ['red', 'green']} }}
dateProvides a datepicker component to handle date selection. argTypes: { startDate: { control: 'date' }}
The data in the table is from the official documentation, the link is here

Under the Actions tab, we can see all events or outputs of my-component. For example, if we click on the component in canvas, we can see the event appearing on the list. This way we can debug events, to see if they are working properly and if they are passing the correct data around.

storybook 3

Advanced techniques for using Angular and Storybook together

As you become more comfortable with Angular and Storybook, you may want to explore advanced techniques to further enhance your development experience:

  1. Custom decorators: Use custom decorators to apply global styles, themes, or layout changes to your components within Storybook. This can help ensure consistency across all components and reduce boilerplate code.
  2. Component-driven development (CDD): CDD is an approach where you build your application from the bottom up, starting with individual components and gradually composing them into larger UI structures. By following CDD and using Storybook to build and test components in isolation, you can achieve better modularity and maintainability in your application.
  3. Integration with testing frameworks: Leverage Storybook‘s integration with popular testing frameworks, such as Jest and Cypress, to write unit and end-to-end tests for your components. This helps ensure the stability and reliability of your application.

Using Storybook addons for enhanced functionality

Storybook addons are plugins that extend the core functionality and allow you to customize and optimize your workflow. Some popular addons for Angular and Storybook include:

  • @storybook/addon-knobs: Enable dynamic values for component properties directly in the Storybook UI.
  • @storybook/addon-actions: Log actions, such as button clicks, directly in the Storybook UI.
  • @storybook/addon-notes: Add documentation or notes to your components.
  • @storybook/addon-a11y: Test the accessibility of your components.
  • @storybook/addon-viewport: Test your components in different viewport sizes and resolutions.
  • @storybook/addon-backgrounds: Apply different background colors or images to your components in Storybook.

To install and use an addon, follow the documentation provided for each addon in the Storybook Addon Galleryhttps://storybook.js.org/addons

Best practices for using Angular and Storybook effectively

To make the most of the Angular and Storybook integration, consider these best practices:

  • Organize your stories hierarchically by using the / separator in the story title. This helps keep your stories organized and easy to navigate.
  • Use the storiesOf API to create more complex stories with multiple states or variations. This allows you to showcase the full range of component behavior and interactions.
  • Implement a design system or pattern library to ensure consistent styling and component usage across your application. A design system helps maintain a unified visual language and can serve as a valuable reference for your team.
  • Regularly update your Storybook instance to take advantage of new features and improvements. Staying up to date with the latest version ensures you have access to the best tools and features available.
  • Document your components and stories to provide context and guidance for other developers. Good documentation makes it easier for team members to understand and work with your components.

Conclusion

In conclusion, the combination of Angular and Storybook offers a powerful solution for creating and managing interactive UIs. By integrating these tools, you can streamline your development process, maintain a consistent UI, improve collaboration, and simplify testing. With advanced techniques, best practices, and addons, you can further enhance your development experience and create high-quality, maintainable web applications.

So, start exploring this winning combination today and elevate your web development game to new heights! Embrace the benefits of Angular and Storybook, and watch your productivity soar as you create stunning, interactive UIs that delight users and stakeholders alike.

Leave a comment

Your email address will not be published. Required fields are marked *