Skip to content

[Angular | Storybook] Tailwind, Directives, Content Projection, Icons and i18n

Georg Höller
Georg Höller
2 min read
[Angular | Storybook] Tailwind, Directives, Content Projection, Icons and i18n
Photo by Kaitlyn Baker / Unsplash

Install packages

npm i -D @nx/storybook
npm i -D @storybook/angular

Create config

nx g @nx/storybook:configuration <project-name>

I created the config inside the main app to share some configs/modules. My stories are located at libs/shared/ui. That's why I had to add these lines to the config files.

// .storybook/main.ts
const config: StorybookConfig = {
  stories: [
    '../src/app/**/*.stories.@(js|jsx|ts|tsx|mdx)',
    '../../../libs/shared/**/*.stories.@(js|jsx|ts|tsx|mdx)', 👈
  ],
  ...
};

// .storybook/tsconfig.json
{
  ...
  "include": [
    "../../../libs/shared/**/*.stories.ts", 👈
    "../src/**/*.stories.ts",
  ]
}

Switch to the preview.ts file - this file is like the root module. I would recommend importing all your global available modules - like translation or icons. I'm using ngx-translate and fontawesome - so I imported them here to use it in any story.

import { Preview, moduleMetadata } from '@storybook/angular';

const preview: Preview = {
  decorators: [
    moduleMetadata({
      imports: [
        ImportFontawesomeModule,
        HttpClientModule,
        TranslateModule.forRoot({
          loader: {
            provide: TranslateLoader,
            useFactory: HttpLoaderFactory,
            deps: [HttpClient],
          },
        }),
      ],
      providers: [TranslateService],
    }),
  ],
};

export default preview;

Tailwind

To get tailwind working you have to import the default tailwind directives.

@tailwind base;
@tailwind components;
@tailwind utilities;

If you imported the directives in the global styles.scss you can refernce this file in the project.json storybook sections.

    "storybook": {
      ...
      "options": {
        ...
        "styles": [
          "apps/compler/.storybook/storybook-default.css",
          "apps/compler/src/styles.scss" 👈
        ]
      },
      
    "build-storybook": {
      ...
      "options": {
        ...
        "styles": [
          "apps/compler/.storybook/storybook-default.css",
          "apps/compler/src/styles.scss" 👈
        ]
      },
project.json

Directives

The easiest way to describe the story for a directive is to look at the code:

import { Meta, StoryFn, moduleMetadata } from '@storybook/angular';
import { GhButtonDirective } from './gh-button.directive';
import { GhButtonContentComponent } from './gh-button-content/gh-button-content.component';

export default {
  title: 'GhButtonDirective',
  decorators: [
    moduleMetadata({
      // import the directive itself and etc.
      imports: [GhButtonDirective, GhButtonContentComponent],
    }),
  ],
  argTypes: {
    // define input controls
    btnStyle: {
      options: ['primary', 'secondary', 'soft', 'circular'],
      control: {
        type: 'radio',
      },
    },
    btnLabel: {
      control: 'text',
    },
    prefixIcon: {
      control: 'text',
    },
    suffixIcon: {
      control: 'text',
    },
  },
  args: {
    btnLabel: 'Save',
    btnStyle: 'primary',
  },
} as Meta<GhButtonDirective>;

const customizable = (): StoryFn => (args) => ({
  props: args,
  // use your directive in the template
  // inputs can be used with the variables defined in the args above
  template: `
  <button ghButton [btnStyle]="btnStyle"> 
    <gh-button-content [prefixIcon]="prefixIcon" [suffixIcon]="suffixIcon">
      {{ btnLabel | translate }}
    </gh-button-content>
  </button>`,
});
export const Primary = customizable();

Content Projection

Found this working answer in the storybook github issue section:

[Angular] How to render a component that has <ng-content> in the template · Issue #2817 · storybookjs/storybook
Issue details I’m pretty new to Angular so this is probably a noob question. I have a button component that uses the tags to project content passed into it when it is used: Component template: <but…

If you have further questions about this topic or need help with a problem in general, please write a comment or simply contact me at yesreply@georghoeller.dev :)
AngularTailwind

Comments


Related Posts

Members Public

[Angular | RxJS] BehaviorSubject with custom states

Whenever I call an api, often my frontend has to go through some different visualization steps. Imagine you have some kind of search input and a list which displays the results but you want to show an loading indicator, an error hint and something different when the result is empty.

[Angular | RxJS] BehaviorSubject with custom states
Members Public

[Angular] Dynamic App Config and Translations in a Submodule

When I'm setting up a new angular application, I always start with translation support and an external app config json loader. You should never start a new app without an internationalization (i18n) system - even if you only support one language! We are going to use the package

[Angular] Dynamic App Config and Translations in a Submodule
Members Public

[Capacitorjs | Angular] Back Swipe Support for iOS and Android

Recently I recognized that capacitorjs apps does not have a native back swipe support. Little bit weird I thought but the solution is quite simple! iOS - Native To enable the iOS back swipe we need to write a capacitor plugin. I tried it without a plugin but inside the

[Capacitorjs | Angular] Back Swipe Support for iOS and Android