I'm considering using Storybook in Angular project. I want to generate story file for each component, but it is bothersome to make story file manually. So I want to generate story file automatically when I generate component. For that, I can restrict component generation from the cli.(ng generate component)
This is problem about command. So Angular schematics or script in package.json may be relevant.
You can achieve this by creating a custom Angular schematic that generates both the component and the corresponding Storybook file.
Here's a step-by-step guide:
npm install -g @angular-devkit/schematics-cli
schematics blank --name=my-component-storybook
cd my-component-storybook
Open the my-component-storybook
folder in your code editor. You will see a collection.json
file. This file is used to tell the Angular CLI what schematics your collection provides.
Update the collection.json
file to include a schematic for generating a component:
{
"$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
"schematics": {
"my-component": {
"description": "Create a component and its corresponding Storybook file",
"factory": "./my-component/index#myComponent"
}
}
}
Create a new folder named my-component
in the src
folder. Inside the my-component
folder, create an index.ts
file. This is where you will define the schematic.
In the index.ts
file, import the necessary modules and define the schematic:
import { Rule, SchematicContext, Tree, url, apply, template, mergeWith, SchematicsException, chain } from '@angular-devkit/schematics';
import { strings } from '@angular-devkit/core';
export function myComponent(options: any): Rule {
return (tree: Tree, _context: SchematicContext) => {
const sourceTemplates = url('./files');
const sourceParameterizedTemplates = apply(sourceTemplates, [
template({
...options,
...strings
})
]);
return mergeWith(sourceParameterizedTemplates);
};
}
files
in the my-component
folder. Inside the files
folder, create your component and Storybook files with placeholders for the dynamic parts:// __name__.component.ts
import { Component } from '@angular/core';
@Component({
selector: '<%= dasherize(name) %>',
templateUrl: './<%= dasherize(name) %>.component.html',
styleUrls: ['./<%= dasherize(name) %>.component.css']
})
export class <%= classify(name) %>Component {}
// __name__.component.stories.ts
export default {
title: '<%= classify(name) %>',
component: <%= classify(name) %>Component,
};
export const <%= classify(name) %> = () => ({
component: <%= classify(name) %>Component,
});
npm run build
npm link
ng generate my-component-storybook:my-component my-component-name
This will generate a new component with the name my-component-name
and a corresponding Storybook file.
Remember to replace my-component-name
with the actual name of your component.