This recipe assumes that you already have an Angular app using @angular/material and have just set up Storybook >= 7.0 using the getting started guide. Don't have this? Follow the Angular material setup instructions then run:
# Add Storybook:
npm create storybook@latest@angular/material depends on two fonts to render as intended, Google’s Roboto and Material Icons. While you can load these fonts directly from the Google Fonts CDN, bundling fonts with Storybook is better for performance.
To get started, install the fonts as dependencies.
yarn add @fontsource/roboto @fontsource/material-iconsThen include the fonts in your angular.json file.
// angular.json
{
// Snipped for brevity
"storybook": {
"builder": "@storybook/angular:start-storybook",
"options": {
"configDir": ".storybook",
"browserTarget": "angular-latest:build",
"compodoc": true,
"compodocArgs": ["-e", "json", "-d", "."],
"port": 6006,
"styles": [
"@angular/material/prebuilt-themes/indigo-pink.css",
"@fontsource/roboto/300.css",
"@fontsource/roboto/400.css",
"@fontsource/roboto/500.css",
"@fontsource/roboto/700.css",
"@fontsource/material-icons",
"src/styles.scss"
]
}
},
"build-storybook": {
"builder": "@storybook/angular:build-storybook",
"options": {
"configDir": ".storybook",
"browserTarget": "angular-latest:build",
"compodoc": true,
"compodocArgs": ["-e", "json", "-d", "."],
"styles": [
"@angular/material/prebuilt-themes/indigo-pink.css",
"@fontsource/roboto/300.css",
"@fontsource/roboto/400.css",
"@fontsource/roboto/500.css",
"@fontsource/roboto/700.css",
"@fontsource/material-icons",
"src/styles.scss"
],
"outputDir": "storybook-static"
}
}
}Now that you have Storybook set up, you can start writing stories for your components. Let's start with a NavBarComponent. For Standalone components, any Material components that you import through the @Component decorator will be available to your component in Storybook.
// src/app/nav-bar/nav-bar.component.ts
import { Component, Input } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatToolbarModule } from '@angular/material/toolbar';
@Component({
selector: 'app-nav-bar',
standalone: true,
imports: [MatToolbarModule, MatButtonModule, MatIconModule],
template: `
<mat-toolbar color="primary">
<span>{{pageTitle}}</span>
</mat-toolbar>
`,
styles: ``,
})
export class NavBarComponent {
@Input()
pageTitle?: string;
}This means that you can just supply the NavBarComponent to the component property of the Meta object in your stories file.
// src/app/nav-bar/nav-bar.component.stories.ts
import type { Meta, StoryObj } from '@storybook/angular';
import { NavBarComponent } from './nav-bar.component';
const meta: Meta<NavBarComponent> = {
title: 'Toolbar',
component: NavBarComponent,
};
export default meta;
type Story = StoryObj<NavBarComponent>;
export const Default: Story = {
args: {
pageTitle: 'Example Title',
},
};For Module components, you will need to import the Material components that you want to use in your stories file. You can supply them to Storybook using the moduleMetadata decorator in the Meta object of the stories file.
// src/app/nav-bar/nav-bar.component.stories.ts
import type { Meta, StoryObj } from '@storybook/angular';
import { moduleMetadata } from '@storybook/angular';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
import { NavBarComponent } from './nav-bar.component';
const meta: Meta<NavBarComponent> = {
title: 'Toolbar',
decorators: [
moduleMetadata({
declarations: [NavBarComponent],
imports: [MatToolbarModule, MatButtonModule, MatIconModule],
}),
],
};
export default meta;
type Story = StoryObj<NavBarComponent>;
export const Default: Story = {
args: {
pageTitle: 'Example Title',
},
render: (args) => ({
props: args,
template: `
<app-nav-bar pageTitle={{pageTitle}}>
</app-nav-bar>
`,
}),
};