@storybook-extras/angular
TypeScript icon, indicating that this package has built-in type declarations

0.0.68 • Public • Published
logo

Storybook Angular Extras

Storybook addon that adds few features to the original Angular Storybook integration.

Table of Contents

Getting started

  1. Install the addon:
yarn add @storybook-extras/angular -D
  1. Add the addon
// .storybook/main.ts
import { StorybookConfig } from '@storybook/angular';
import { ExtrasConfig } from '@storybook-extras/preset';

const config: StorybookConfig & ExtrasConfig = {
    ...
    "addons": [
        "@storybook-extras/angular",
        ...
    ],
    ...
}

export default config;
  1. Refer to the sections below for the documentation of the built-in features.

Demo/Chromatic

Find the published demo storybook on chromatic here

Features

  • ⚡️ Zero config setup.
  • 📚 Supports latest Storybook v7.
  • 🅰️ Supports latest Angular v15.
  • 🙌 Introduce must-have features for Storybook on Angular .
  • 🐈‍ Integrate as much nice-to-have features as possible.
  • 📔 Coverage Instrumentation for Test-Runner
  • 🧪 Auto injector for Angular services
  • 🦥 Lazy loading documentation
  • 💬 Source code display
  • 🌯 Story Wrappers selector toolbar

Test Runner Coverage Instrumentation

We've recently moved from @jsdevtools/coverage-istanbul-loader to one of our own created libraries webpack-plugin-istanbul to ensue it is working better with the latest versions of Storybook and Angular and specifically with the proper versions of webpack and istanbul-lib-instrument.

Read more about the coverage instrumentation in the official Test Runner documentation here.

Simply running test-storybook --coverage will show you test results coverage in the terminal and also will save the coverage results into coverage/storybook.

Angular Services Unit Testing

  • This feature is for developers who want their testing to all run in the same place.
  • Particulary this is helpful when you want to move business logic from components into services.
  • But you still want to test it through Storybook.
  • This feature does not require any setup. It relies on the official @storybook/angular implementation.
  • It simply injects the service into an APP_INITIALIZER which runs before the Angular application starts.
  • When the initializer runs, it puts the service instance into parameters.providers which you can retrieve in the play function like so:
const meta: Meta = {
    title: 'Services/AppService',
    decorators: [
        moduleMetadata({
            imports: [AppModule, CommonModule],
            providers: [AppService],
        }),
    ],
};

export default meta;

export const Primary: StoryObj = {
    play: async ({ parameters: { providers } }) => {
        const appService: AppService = providers.AppService;

        expect(appService).toBeTruthy();
    },
};

Documentation Lazy Loading

  • This feature uses fetch to load the documentation.json file during runtime, specifically in the preview iframe before the load of each story.
  • This is very helpful if you are doing active development and your documentation is being updated regularly.
  • This is also helpful if your application is already published along with its documentation and you need to load that remotely served documentation.

Here is a simple example of the first scenario:

  • execute compodoc into a specific directory
    compodoc -e json -d dist/docs
    
  • Make sure to include static dir like so
// .storybook/main.ts
import { StorybookConfig } from '@storybook/angular';
import { ExtrasConfig } from '@storybook-extras/preset';

const config: StorybookConfig & ExtrasConfig = {
    staticDirs: [{ from: '<DOCS_DIR_PATH>', to: '/<DOCS_SERVE_DIR>' }],
}

export default config;
  • Next, enable the documentation lazy loading in the preview.@(js|ts) file like so:
export const parameters = {
    ...
    docs: {
        inlineStories: true,
        ...
        fetch: '<DOCS_SERVE_DIR>/documentation.json'
    }
}

The url property here can be a full url like http://example.com/storybook/docs/documentation.json or a relative path to the current storybook instance like ../dist/docs/documentation.json.

You can also provide compodoc property to be something like require('<DOCS_DIR_PATH>/documentation.json') or have it imported already with import compodoc from '<DOCS_DIR_PATH>/documentation.json, this way you don't need to call setCompodocJson method, it will be called automatically on your behalf, and the docs will be stored in memory for later usage.

Source Code

  • This feature relies on the documentation loaded previously from compodoc to display the source code of the components and/or services that exists in the moduleMetadata.
  • You don't need to re-declare your main component in the declarations section of moduleMetadata, it will be added directly.
  • Basically, the addon will retrieve the source code of any class under declarations or providers, along with templates & styles for the components if they exist.
  • No setup is needed for this feature, it is enabled by default.
  • You can disable it by using global or story parameters like so:
    parameters: {
        sourceCode: {
            disable: true;
        }
    }

Wrappers Selector

  • This feature uses componentWrapperDecorator from the official @storybook/angular to render wrapper elements dynamically around stories.
  • This simply reads a list of pre-defined wrapper elements from the global parameters or each individual story parameters.
  • This allows you to change the wrapper element during runtime instead of having static decorator all the time.
  • This is very helpful specially if you want to see how your components render inside a root component with header and footer, or just simply inside a specific parent element.

Configuration

  • This toolbar menu works very similar to the official @storybook/addon-backgrounds addon.
  • The configuration looks something like this:

In preview.js or preview.ts:

export const parameters = {
    wrappers: {
        disable: false,
        default: 'None',
        values: [
            { name: 'None', value: '' },
            { name: 'Container', value: 'app-container' },
            { name: 'Root', value: 'app-root' },
        ],
    },
};

In a story file like button.stories.ts:

import { type StoryObj, type Meta } from '@storybook/angular';
import Button from './button.component';

const meta: Meta<Button> = {
    title: 'Example/Button',
    component: Button,
    parameters: {
        wrappers: {
            default: 'None',
            values: [
                { name: 'None', value: '' },
                {
                    name: 'Button Container',
                    value: 'btn-container',
                    options: {
                        class: 'small',
                        style: 'padding:5px;',
                    },
                },
                { name: 'Container', value: 'app-container' },
                { name: 'Root', value: 'app-root' },
            ],
        },
    },
};

export default meta;

The wrapper item can also contain an options property which will be translated into HTML attributes for the wrapper. For example; the configuration above will render the following if Button Container is selected:

<btn-container class="small" style="padding:5px;"></btn-container>

Roadmap

Please feel free to request features, I will try to add them as soon as humanly possible. Currently the following features are in my pipeline:

  • UI representation of Angular Service.
  • UI representation for Issues/Pull Requests (Github/Bitbucket/Jira).
  • Coverage Enhancements.
  • Story Source representation.

Package Sidebar

Install

npm i @storybook-extras/angular

Weekly Downloads

21

Version

0.0.68

License

MIT

Unpacked Size

184 kB

Total Files

276

Last publish

Collaborators

  • mosherif87