3

Simply would like to use angular-fontawesome with Storybook.js as a library (FaIconLibrary). In the following documentation https://github.com/FortAwesome/angular-fontawesome/blob/master/docs/usage/icon-library.md#using-the-icon-library i'm to add a property to the constructor. Only in the Storybook.js file (index.stories.ts) I see no way to add anything to the constructor because it's not there. Anyone resolve this or have a good work around? Thanks

Adam L
  • 177
  • 1
  • 1
  • 9

1 Answers1

6

One option is to use Angular's APP_INITIALIZER function to execute arbitrary code when storybook is loaded. In this particular case you can configure FaIconLibrary with the necessary icons during the app initialisation process.

Let's assume you have the below component which uses fa-icon and you want to use it inside the story book:

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

@Component({
  selector: 'app-user-detail',
  template: `
    <h1>
      <fa-icon icon="user"></fa-icon>
      {{ fullName }}
    </h1>
    <p>Full name: {{ fullName }}</p>
  `,
})
export class UserDetailComponent {
  @Input()
  fullName: string;
}

In a story book for this component you can provide an APP_INITIALIZER in the moduleMetadata call. This code will be executed when storybook is loaded and will configure FaIconLibrary:

import { APP_INITIALIZER } from '@angular/core';
import { FaIconLibrary, FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { faUser } from '@fortawesome/free-solid-svg-icons';
import { moduleMetadata, storiesOf } from '@storybook/angular';
import { UserDetailComponent } from '../app/user-detail.component';

storiesOf('User Detail', module)
  .addDecorator(
    moduleMetadata({
      imports: [ FontAwesomeModule ],
      declarations: [ UserDetailComponent ],
      // The key bit is the providers array below.
      providers: [
        {
          provide: APP_INITIALIZER,
          useFactory: (iconLibrary: FaIconLibrary) => {
            return async () => {
              // Add the necessary icons inside the initialiser body.
              iconLibrary.addIcons(faUser);
            };
          },
          // When using a factory provider you need to explicitly specify its 
          // dependencies.
          deps: [ FaIconLibrary ],
          multi: true,
        },
      ],
    }),
  )
  .add('default', () => {
    return {
      template: `<app-user-detail [fullName]="fullName"></app-user-detail>`,
      props: {
        fullName: 'John Doe',
      },
    };
  });

The full code can also be found on GitHub.

Yaroslav Admin
  • 13,880
  • 6
  • 63
  • 83