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

story-types.mddocs/

Story Definition and Types

Core types and interfaces for defining Angular component stories using Component Story Format (CSF) v2 and v3.

Capabilities

Meta Type

Metadata configuration for Angular component stories. This is the default export of a story file.

/**
 * Metadata to configure the stories for a component.
 * Used as the default export in story files.
 */
type Meta<TArgs = Args> = ComponentAnnotations<AngularRenderer, TransformComponentType<TArgs>>;

Usage Example:

import type { Meta } from "@storybook/angular";
import { ButtonComponent } from "./button.component";

const meta: Meta<ButtonComponent> = {
  title: "Example/Button",
  component: ButtonComponent,
  parameters: {
    layout: "centered",
  },
  argTypes: {
    backgroundColor: { control: "color" },
    size: {
      control: { type: "select" },
      options: ["small", "medium", "large"],
    },
  },
};

export default meta;

StoryFn Type (CSF v2)

Story function type that represents a component example using CSF v2 format.

/**
 * Story function that represents a CSFv2 component example.
 * Functions that return story configuration objects.
 */
type StoryFn<TArgs = Args> = AnnotatedStoryFn<AngularRenderer, TransformComponentType<TArgs>>;

Usage Example:

import type { Meta, StoryFn } from "@storybook/angular";
import { ButtonComponent } from "./button.component";

export const Primary: StoryFn<ButtonComponent> = (args) => ({
  props: args,
  template: `<app-button [primary]="primary" [label]="label"></app-button>`,
});

Primary.args = {
  primary: true,
  label: "Button",
};

StoryObj Type (CSF v3)

Story object type that represents a component example using CSF v3 format.

/**
 * Story object that represents a CSFv3 component example.
 * Objects with args, parameters, and other story configuration.
 */
type StoryObj<TArgs = Args> = StoryAnnotations<AngularRenderer, TransformComponentType<TArgs>>;

Usage Example:

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

const meta: Meta<ButtonComponent> = {
  title: "Example/Button",
  component: ButtonComponent,
};

export default meta;
type Story = StoryObj<typeof meta>;

export const Primary: Story = {
  args: {
    primary: true,
    label: "Button",
  },
};

export const Secondary: Story = {
  args: {
    label: "Button",
  },
  parameters: {
    docs: {
      description: {
        story: "Secondary button variant",
      },
    },
  },
};

Decorator Type

Type for story decorators that can modify or wrap story rendering.

/**
 * Function type for story decorators
 */
type Decorator<TArgs = StrictArgs> = DecoratorFunction<AngularRenderer, TArgs>;

Usage Example:

import type { Decorator } from "@storybook/angular";
import { moduleMetadata } from "@storybook/angular";

const withCommonModule: Decorator = moduleMetadata({
  imports: [CommonModule],
});

export const decorators: Decorator[] = [withCommonModule];

Loader Type

Type for story loaders that can load data before story rendering.

/**
 * Function type for story loaders
 */
type Loader<TArgs = StrictArgs> = LoaderFunction<AngularRenderer, TArgs>;

Usage Example:

import type { Loader } from "@storybook/angular";

const fetchUserData: Loader = async (context) => {
  const userId = context.args.userId;
  const userData = await fetch(`/api/users/${userId}`).then(res => res.json());
  return { userData };
};

export const WithUserData: Story = {
  loaders: [fetchUserData],
  render: (args, { loaded: { userData } }) => ({
    props: { ...args, userData },
    template: `<user-profile [user]="userData"></user-profile>`,
  }),
};

StoryContext Type

Context object passed to decorators, loaders, and render functions containing story information.

/**
 * Context object containing story information and parameters
 */
type StoryContext<TArgs = StrictArgs> = GenericStoryContext<AngularRenderer, TArgs>;

Usage Example:

const dynamicDecorator: Decorator = (storyFn, context) => {
  const story = storyFn();
  
  // Access story information
  console.log('Story ID:', context.id);
  console.log('Story args:', context.args);
  console.log('Story parameters:', context.parameters);
  
  return {
    ...story,
    template: `<div class="story-wrapper">${story.template}</div>`,
  };
};

Preview Type

Type for global preview configuration that applies to all stories.

/**
 * Global preview configuration type
 */
type Preview = ProjectAnnotations<AngularRenderer>;

Usage Example:

// .storybook/preview.ts
import type { Preview } from "@storybook/angular";
import { setCompodocJson } from "@storybook/addon-docs/angular";
import docJson from "../documentation.json";

setCompodocJson(docJson);

const preview: Preview = {
  parameters: {
    actions: { argTypesRegex: "^on[A-Z].*" },
    controls: {
      matchers: {
        color: /(background|color)$/i,
        date: /Date$/,
      },
    },
  },
  decorators: [
    moduleMetadata({
      imports: [CommonModule],
    }),
  ],
};

export default preview;

Component Type Transformation

Angular components with InputSignals and EventEmitters are automatically transformed for better type safety in stories.

Type Transformations

/**
 * Utility type that transforms InputSignal and EventEmitter types
 * for better story argument type safety
 */
type TransformComponentType<T> = TransformInputSignalType<
  TransformOutputSignalType<TransformEventType<T>>
>;

/**
 * Transform InputSignal<T> to T
 */
type TransformInputSignalType<T> = {
  [K in keyof T]: T[K] extends InputSignal<infer E>
    ? E
    : T[K] extends InputSignalWithTransform<any, infer U>
      ? U
      : T[K];
};

/**
 * Transform OutputEmitterRef<T> to (e: T) => void
 */
type TransformOutputSignalType<T> = {
  [K in keyof T]: T[K] extends OutputEmitterRef<infer E> ? (e: E) => void : T[K];
};

/**
 * Transform EventEmitter<T> to (e: T) => void
 */
type TransformEventType<T> = {
  [K in keyof T]: T[K] extends EventEmitter<infer E> ? (e: E) => void : T[K];
};

These transformations ensure that:

  • InputSignal<string> properties become string in story args
  • EventEmitter<MouseEvent> properties become (e: MouseEvent) => void in story args
  • OutputEmitterRef<number> properties become (e: number) => void in story args

Re-exported Types

The following types are re-exported from Storybook core for convenience:

type Args = Record<string, any>;
type ArgTypes = Record<string, ArgType>;
type Parameters = Record<string, any>;
type StrictArgs = Record<string, unknown>;

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