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!
Contents
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.
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.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.
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:
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.htmlNow 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.tsOur component is ready! Let us now see how we can use the Storybook
to see it and play around with its inputs and outputs.
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.tsThis 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.
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.
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.tsStorybook
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 Type | Control | Description |
---|---|---|
boolean | boolean | Provides a toggle for switching between possible states.argTypes: { active: { control: 'boolean' }} |
number | number | Provides a numeric input to include the range of all possible values.argTypes: { even: { control: { type: 'number', min:1, max:30, step: 2 } }} |
range | Provides a range slider component to include all possible values.argTypes: { odd: { control: { type: 'range', min: 1, max: 30, step: 3 } }} | |
object | object | Provides a JSON-based editor component to handle the object’s values. Also allows edition in raw mode. argTypes: { user: { control: 'object' }} |
array | object | Provides a JSON-based editor component to handle the values of the array. Also allows edition in raw mode. argTypes: { odd: { control: 'object' }} |
file | Provides 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' } }} | |
enum | radio | Provides a set of radio buttons based on the available options.argTypes: { contact: { control: 'radio', options: ['email', 'phone', 'mail'] }} |
inline-radio | Provides a set of inlined radio buttons based on the available options.argTypes: { contact: { control: 'inline-radio', options: ['email', 'phone', 'mail'] }} | |
check | Provides a set of checkbox components for selecting multiple options.argTypes: { contact: { control: 'check', options: ['email', 'phone', 'mail'] }} | |
inline-check | Provides a set of inlined checkbox components for selecting multiple options.argTypes: { contact: { control: 'inline-check', options: ['email', 'phone', 'mail'] }} | |
select | Provides a drop-down list component to handle single value selection. argTypes: { age: { control: 'select', options: [20, 30, 40, 50] }} | |
multi-select | Provides a drop-down list that allows multiple selected values. argTypes: { countries: { control: 'multi-select', options: ['USA', 'Canada', 'Mexico'] }} | |
string | text | Provides a freeform text input.argTypes: { label: { control: 'text' }} |
color | Provides 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']} }} | |
date | Provides a datepicker component to handle date selection. argTypes: { startDate: { control: 'date' }} |
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.
As you become more comfortable with Angular
and Storybook
, you may want to explore advanced techniques to further enhance your development experience:
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.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.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.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 Gallery
: https://storybook.js.org/addons
To make the most of the Angular
and Storybook
integration, consider these best practices:
/
separator in the story title. This helps keep your stories organized and easy to navigate.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.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.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.