Story for an Angular Directive V2
Tags: addons, storybook, angular, directives
Published: 2022-02-13 17:01:35

---
title: Story for an Angular Directive V2
published: true
date: 2022-02-12 12:33:20 UTC
tags: addons,storybook,angular,directives
canonical_url: https://medium.com/@redin.gaetan/story-for-an-angular-directive-v2-a83a3a56f2db
---

#### Storybook and Angular

![](https://cdn-images-1.medium.com/max/564/1*UVhoCifbPsKuiwgKnTMGTA.png)

Now, I have a bit more experience about making stories for Angular. I would like to share with you how I write a story for an Angular directive. I have already written an article when I started with storybook. I will make here some adjustments.

Context: Angular 13, StoryBook 6.5.0-alpha.36

### First draft

I presume you already have installed storybook, if you don’t just go [here](https://storybook.js.org/docs/angular/get-started/install).

Let’s use this button directive:

```
// button.directive.ts
@Directive({
  selector: 'button[groButton]',  
host: {
    _class_: 'gro-button',
    '[class.gro-small]': 'size === "small"',
    '[class.gro-medium]': 'size === "medium"',
    '[class.gro-large]': 'size === "large"',
    '[class.gro-outlined]': 'outlined',
    '[class.gro-primary]': 'color === "primary"',
    '[class.gro-accent]': 'color === "accent"',
    '[class.gro-warn]': 'color === "warn"',
  },
})
_export class_ ButtonDirective {
  @Input()
  _public_ size: 'small' | 'medium' | 'large' = 'medium';

  @Input()
  @CoerceBoolean()
  _public_ outlined?: _boolean_;

  @Input()
  _public_ color: 'primary' | 'accent' | 'warn' = 'primary';
}
```

I know there is a debate about using a directive or a component for button element. But that’s not the point here :-)

Now, this is the minimal story example for it:

```
// button.stories.ts
_import_ { _Meta_, _Story_ } _from_ '@storybook/angular';
_import_ { ButtonDirective } _from_ './button.directive';

_export default_ {
  title: 'atoms/button',
  component: ButtonDirective,
} _as Meta_<ButtonDirective>;

_const_ template: _Story_<ButtonDirective> = (args: ButtonDirective) => ({
  props: {
    size: args.size,
    outlined: args.outlined,
    color: args.color,
  },
  template: `<button groButton [size]="size" [outlined]="outlined" [color]="color">Click</button>`,
});

_export const_ Default = template.bind({});
```

With this stories you could test all cases for the button directive.

I suggest you to have a look on the _“props”_ properties for the template. Personally, I use the [addon-docs](https://storybook.js.org/addons/@storybook/addon-docs) which works with [compodoc](https://compodoc.app/). It allows to extract the documentation in the “Docs” tab. When you use it, if you set the _“props”_ properties like this:

```
props: {
  ...args
}
```

You will get some troubles. In fact, all properties of your directive/component will be overrode, not only the _@Input_ properties. This can lead to some unexpected behaviors. So, you should prefer to only specify the properties you want to set.

That’s what you get with this story:

![](https://cdn-images-1.medium.com/max/827/1*Yf2FPZYHTO-LCwAEVUboQw.png)

### Final Story

Now, let’s improve this story with some special addons offered by storybook.

#### addon-controls

Thanks to this addon, we can play with our components/directives from a graphical UI.

```
// .storybook/main.js
module.exports = {
  stories: [],
  addons: [
    '@storybook/addon-docs',
    '@storybook/addon-essentials', // check this line
  ],
  core: {
    builder: 'webpack5',
  },
  webpackFinal: (config) => {
    _return_ config;
  },
};
```

Have a look on the _argTypes_ property:

```
// button.stories.ts
_export default_ {
  title: 'atoms/button',
  component: ButtonDirective,  
argTypes: {
    color: { // directive input name
      control: { type: 'inline-radio' },
    },
    size: { // directive input name
      control: { type: 'inline-radio' },
    },
  },
} _as Meta_<ButtonDirective>;
```

Thanks to this, that’s what we get in our Storybook:

![](https://cdn-images-1.medium.com/max/740/1*BQ_9rqAIyQNg8a3wlmyzWA.png)

In all recent version of Storybook, this addon is a part of [essentials](https://storybook.js.org/docs/react/essentials/introduction) and is installed by default.

If you want to get more information about it go [here](https://storybook.js.org/addons/@storybook/addon-controls/).

#### addon-jest

I use [Jest](https://jestjs.io/fr/) to test my code. It’s sometime useful knowing what is tested without going in the code. For this, you have to install the [addon-jest](https://storybook.js.org/addons/@storybook/addon-jest/).

To install it:

```
(yarn|npm) (add|install) -D @storybook/addon-jest
```

Add the addon:

```
// .storybook/main.js
module.exports = {
  stories: [],
  addons: [
    '@storybook/addon-docs',
    '@storybook/addon-essentials',
    '@storybook/addon-jest', // check here
  ],
  core: {
    builder: 'webpack5',
  },
  webpackFinal: (config) => {
    _return_ config;
  },
};
```

In package.json file add the following:

```
// don't forget to add .jest-test-results.json to .gitignore
"scripts": {
  "test:generate-output": "jest --json --outputFile=.jest-test-results.json"
}
```

Add test at the global level of your Storybook:

```
// .storybook/preview.js

import { withTests } from '@storybook/addon-jest';

import results from '../.jest-test-results.json';

export const decorators = [
  withTests({
    results,
  }),
];
```

In your story:

```
_export default_ {
  title: 'atoms/button',
  component: ButtonDirective,
  parameters: {
    jest: ['button.directive.spec'], // check here
  },
  argTypes: {
    color: {
      control: { type: 'inline-radio' },
    },
    size: {
      control: { type: 'inline-radio' },
    },
  },
} _as Meta_<ButtonDirective>;
```

You will now can see this:

![](https://cdn-images-1.medium.com/max/1024/1*U80TuVRM7AxaRknDmAQyyQ.png)

That’s the minimal setup I can suggest you. There are a lot of other addons that you can check [here](https://storybook.js.org/addons/). All of them cannot be used for Angular but it’s always noticed.

### Conclusion

Now you can have a nice Storybook, and more you can improve it with a lot of other addons. In a next chapter, I will show you how to test your Storybook. Why? Because Storybook is really powerful but when you add code into your applications/libraries you couldn’t know if you have broken something…

To be following…

Thanks for reading.

### Learn More

- [Install Jest for Angular](https://dev.to/gaetanrdn/jest-and-angular-install-fg3)
- [How to Undo a GIT Commit](https://dev.to/gaetanrdn/how-to-undo-a-git-commit-36lp)
- [TypeScript Function Overloads](https://dev.to/gaetanrdn/typescript-function-overloads-1eeo)
- [Angular for everyone: All about it](https://medium.com/@redin.gaetan/angular-for-every-one-table-of-contents-d24232940dd4)