CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-storybook--angular

Storybook for Angular: Develop, document, and test UI components in isolation

Pending
Overview
Eval results
Files

framework-config.mddocs/

Framework Configuration

Framework-specific configuration options and Storybook main configuration utilities for Angular projects.

Capabilities

StorybookConfig Interface

Main configuration interface for Storybook Angular projects, extending base Storybook configuration with Angular-specific options.

/**
 * The interface for Storybook configuration in `main.ts` files for Angular projects
 */
interface StorybookConfig extends Omit<
  StorybookConfigBase,
  keyof StorybookConfigWebpack | keyof StorybookConfigFramework
>, StorybookConfigWebpack, StorybookConfigFramework {
  framework: '@storybook/angular' | {
    name: '@storybook/angular';
    options: FrameworkOptions;
  };
}

interface StorybookConfigFramework {
  framework:
    | '@storybook/angular'
    | {
        name: '@storybook/angular';
        options: FrameworkOptions;
      };
  core?: StorybookConfigBase['core'] & {
    builder?:
      | '@storybook/builder-webpack5'
      | {
          name: '@storybook/builder-webpack5';
          options: BuilderOptions;
        };
  };
  typescript?: Partial<TypescriptOptionsBuilder & TypescriptOptionsReact> &
    StorybookConfigBase['typescript'];
}

Basic Configuration Example:

// .storybook/main.ts
import type { StorybookConfig } from '@storybook/angular';

const config: StorybookConfig = {
  stories: ['../src/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    '@storybook/addon-interactions',
  ],
  framework: '@storybook/angular',
  typescript: {
    check: false,
    reactDocgen: 'react-docgen-typescript',
    reactDocgenTypescriptOptions: {
      shouldExtractLiteralValuesFromEnum: true,
      propFilter: (prop) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true),
    },
  },
};

export default config;

FrameworkOptions Interface

Angular-specific framework configuration options.

/**
 * Options for configuring the Angular framework integration
 */
interface FrameworkOptions extends AngularOptions {
  /** Builder-specific options for webpack5 */
  builder?: BuilderOptions;
}

interface AngularOptions {
  /** Enable Angular Ivy renderer (default: true in Angular 12+) */
  enableIvy?: boolean;
}

Configuration with Framework Options:

// .storybook/main.ts
import type { StorybookConfig } from '@storybook/angular';

const config: StorybookConfig = {
  stories: ['../src/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
  addons: ['@storybook/addon-essentials'],
  framework: {
    name: '@storybook/angular',
    options: {
      enableIvy: true,
      builder: {
        useSWC: true,
      },
    },
  },
  core: {
    builder: {
      name: '@storybook/builder-webpack5',
      options: {
        fsCache: true,
        lazyCompilation: true,
      },
    },
  },
};

export default config;

defineMain Helper Function

Utility function for defining Storybook main configuration with type safety.

/**
 * Helper function for defining main configuration with type safety
 * @param config - Storybook configuration object
 * @returns Typed configuration object
 */
declare function defineMain(config: StorybookConfig): StorybookConfig;

Usage Example:

// .storybook/main.ts
import { defineMain } from '@storybook/angular/node';

export default defineMain({
  stories: ['../src/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    '@storybook/addon-interactions',
  ],
  framework: '@storybook/angular',
  typescript: {
    check: false,
  },
  // Full type safety and IntelliSense support
});

Configuration Examples

Basic Angular Project

Minimal configuration for a standard Angular project:

import type { StorybookConfig } from '@storybook/angular';

const config: StorybookConfig = {
  stories: ['../src/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
  ],
  framework: '@storybook/angular',
};

export default config;

Angular with Material Design

Configuration for projects using Angular Material:

import type { StorybookConfig } from '@storybook/angular';

const config: StorybookConfig = {
  stories: ['../src/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    '@storybook/addon-docs',
  ],
  framework: '@storybook/angular',
  staticDirs: ['../src/assets'],
  webpackFinal: async (config) => {
    // Custom webpack configuration for Angular Material
    config.module.rules.push({
      test: /\.scss$/,
      use: ['style-loader', 'css-loader', 'sass-loader'],
    });
    return config;
  },
};

export default config;

Angular with Custom Webpack Configuration

Advanced webpack customization:

import type { StorybookConfig } from '@storybook/angular';
import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin';

const config: StorybookConfig = {
  stories: ['../src/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
  addons: [
    '@storybook/addon-essentials',
    '@storybook/addon-interactions',
  ],
  framework: {
    name: '@storybook/angular',
    options: {
      builder: {
        useSWC: true,
      },
    },
  },
  core: {
    builder: {
      name: '@storybook/builder-webpack5',
      options: {
        fsCache: true,
        lazyCompilation: true,
      },
    },
  },
  webpackFinal: async (config) => {
    // Add TypeScript path mapping
    config.resolve.plugins = [
      ...(config.resolve.plugins || []),
      new TsconfigPathsPlugin({
        configFile: path.resolve(__dirname, '../tsconfig.json'),
      }),
    ];

    // Handle Angular specific loaders
    config.module.rules.push({
      test: /\.html$/,
      loader: 'html-loader',
      options: {
        minimize: true,
      },
    });

    return config;
  },
};

export default config;

Monorepo Configuration

Configuration for Angular monorepo (Nx, Lerna, etc.):

import type { StorybookConfig } from '@storybook/angular';
import { join, dirname } from 'path';

function getAbsolutePath(value: string): any {
  return dirname(require.resolve(join(value, 'package.json')));
}

const config: StorybookConfig = {
  stories: [
    '../../../libs/**/*.stories.@(js|jsx|ts|tsx|mdx)',
    '../src/**/*.stories.@(js|jsx|ts|tsx|mdx)',
  ],
  addons: [
    getAbsolutePath('@storybook/addon-links'),
    getAbsolutePath('@storybook/addon-essentials'),
    getAbsolutePath('@storybook/addon-interactions'),
  ],
  framework: {
    name: getAbsolutePath('@storybook/angular'),
    options: {},
  },
  typescript: {
    check: false,
    reactDocgen: 'react-docgen-typescript',
    reactDocgenTypescriptOptions: {
      shouldExtractLiteralValuesFromEnum: true,
      propFilter: (prop) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true),
    },
  },
};

export default config;

Performance Optimized Configuration

Configuration optimized for large Angular projects:

import type { StorybookConfig } from '@storybook/angular';

const config: StorybookConfig = {
  stories: ['../src/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
  addons: [
    '@storybook/addon-essentials',
    {
      name: '@storybook/addon-docs',
      options: {
        transcludeMarkdown: true,
      },
    },
  ],
  framework: {
    name: '@storybook/angular',
    options: {
      enableIvy: true,
      builder: {
        useSWC: true,
        fsCache: true,
      },
    },
  },
  core: {
    builder: {
      name: '@storybook/builder-webpack5',
      options: {
        fsCache: true,
        lazyCompilation: true,
      },
    },
    disableTelemetry: true,
  },
  typescript: {
    check: false, // Disable type checking for faster builds
    reactDocgen: false, // Disable docgen for faster builds
  },
  features: {
    storyStoreV7: true,
    argTypeTargetsV7: true,
  },
};

export default config;

TypeScript Configuration

Angular-Specific TypeScript Options

interface AngularTypeScriptConfig {
  typescript?: {
    /** Enable/disable TypeScript type checking */
    check?: boolean;
    /** Skip TypeScript compilation in favor of Angular's compiler */
    skipCompiler?: boolean;
    /** React docgen configuration (inherited from webpack builder) */
    reactDocgen?: 'react-docgen-typescript' | 'react-docgen' | false;
    /** Options for react-docgen-typescript */
    reactDocgenTypescriptOptions?: {
      shouldExtractLiteralValuesFromEnum?: boolean;
      propFilter?: (prop: any) => boolean;
    };
  };
}

TypeScript Configuration Example:

const config: StorybookConfig = {
  // ... other options
  typescript: {
    check: true,
    skipCompiler: false,
    reactDocgen: 'react-docgen-typescript',
    reactDocgenTypescriptOptions: {
      shouldExtractLiteralValuesFromEnum: true,
      propFilter: (prop) => {
        if (prop.parent) {
          return !/node_modules/.test(prop.parent.fileName);
        }
        return true;
      },
    },
  },
};

Preset Configuration

The Angular framework automatically includes necessary presets:

// Automatically included presets:
const presets = [
  require.resolve('./server/framework-preset-angular-cli'),
  require.resolve('./server/framework-preset-angular-ivy'),
];

Preview Annotations

Automatic preview configuration:

// Automatically configured preview annotations:
const previewAnnotations = [
  '@storybook/angular/dist/client/config.mjs',
  // Conditionally added based on options:
  '@storybook/angular/dist/client/preview-prod.mjs', // if enableProdMode
  '@storybook/angular/dist/client/docs/config.mjs', // if docs enabled
];

Environment-Specific Configuration

Development Configuration

const config: StorybookConfig = {
  // ... base config
  core: {
    builder: {
      name: '@storybook/builder-webpack5',
      options: {
        lazyCompilation: true,
        fsCache: true,
      },
    },
  },
  typescript: {
    check: true, // Enable checking in dev
  },
};

Production/CI Configuration

const config: StorybookConfig = {
  // ... base config
  core: {
    disableTelemetry: true,
    builder: {
      name: '@storybook/builder-webpack5',
      options: {
        fsCache: false, // Disable for reproducible builds
      },
    },
  },
  typescript: {
    check: false, // Disable checking for faster CI builds
  },
};

Install with Tessl CLI

npx tessl i tessl/npm-storybook--angular

docs

cli-builders.md

decorators.md

framework-config.md

index.md

portable-stories.md

story-types.md

template-utilities.md

tile.json