@storybook/angular
Version:
Storybook for Angular: Develop, document, and test UI components in isolation
145 lines (139 loc) • 7.25 kB
TypeScript
import { Args, ComponentAnnotations, AnnotatedStoryFn, StoryAnnotations, StrictArgs, DecoratorFunction, LoaderFunction, StoryContext as StoryContext$1, ProjectAnnotations, NamedOrDefaultProjectAnnotations, NormalizedProjectAnnotations } from 'storybook/internal/types';
export { ArgTypes, Args, Parameters, StrictArgs } from 'storybook/internal/types';
import * as AngularCore from '@angular/core';
import { Type } from '@angular/core';
import { A as AngularRenderer, N as NgModuleMetadata, I as ICollection } from '../types-3b0b7107.js';
export { P as AngularParameters, S as IStory } from '../types-3b0b7107.js';
import { ApplicationConfig } from '@angular/platform-browser';
/**
* Metadata to configure the stories for a component.
*
* @see [Default export](https://storybook.js.org/docs/formats/component-story-format/#default-export)
*/
type Meta<TArgs = Args> = ComponentAnnotations<AngularRenderer, TransformComponentType<TArgs>>;
/**
* Story function that represents a CSFv2 component example.
*
* @see [Named Story exports](https://storybook.js.org/docs/formats/component-story-format/#named-story-exports)
*/
type StoryFn<TArgs = Args> = AnnotatedStoryFn<AngularRenderer, TransformComponentType<TArgs>>;
/**
* Story object that represents a CSFv3 component example.
*
* @see [Named Story exports](https://storybook.js.org/docs/formats/component-story-format/#named-story-exports)
*/
type StoryObj<TArgs = Args> = StoryAnnotations<AngularRenderer, TransformComponentType<TArgs>>;
type Decorator<TArgs = StrictArgs> = DecoratorFunction<AngularRenderer, TArgs>;
type Loader<TArgs = StrictArgs> = LoaderFunction<AngularRenderer, TArgs>;
type StoryContext<TArgs = StrictArgs> = StoryContext$1<AngularRenderer, TArgs>;
type Preview = ProjectAnnotations<AngularRenderer>;
/** Utility type that transforms InputSignal and EventEmitter types */
type TransformComponentType<T> = TransformInputSignalType<TransformOutputSignalType<TransformEventType<T>>>;
type AngularInputSignal<T> = AngularCore.InputSignal<T>;
type AngularInputSignalWithTransform<T, U> = AngularCore.InputSignalWithTransform<T, U>;
type AngularOutputEmitterRef<T> = AngularCore.OutputEmitterRef<T>;
type AngularHasInputSignal = typeof AngularCore extends {
input: infer U;
} ? true : false;
type AngularHasOutputSignal = typeof AngularCore extends {
output: infer U;
} ? true : false;
type InputSignal<T> = AngularHasInputSignal extends true ? AngularInputSignal<T> : never;
type InputSignalWithTransform<T, U> = AngularHasInputSignal extends true ? AngularInputSignalWithTransform<T, U> : never;
type OutputEmitterRef<T> = AngularHasOutputSignal extends true ? AngularOutputEmitterRef<T> : never;
type TransformInputSignalType<T> = {
[K in keyof T]: T[K] extends InputSignal<infer E> ? E : T[K] extends InputSignalWithTransform<any, infer U> ? U : T[K];
};
type TransformOutputSignalType<T> = {
[K in keyof T]: T[K] extends OutputEmitterRef<infer E> ? (e: E) => void : T[K];
};
type TransformEventType<T> = {
[K in keyof T]: T[K] extends AngularCore.EventEmitter<infer E> ? (e: E) => void : T[K];
};
/**
* Function that sets the globalConfig of your storybook. The global config is the preview module of
* your .storybook folder.
*
* It should be run a single time, so that your global config (e.g. decorators) is applied to your
* stories when using `composeStories` or `composeStory`.
*
* Example:
*
* ```jsx
* // setup-file.js
* import { setProjectAnnotations } from '@storybook/angular';
*
* import projectAnnotations from './.storybook/preview';
*
* setProjectAnnotations(projectAnnotations);
* ```
*
* @param projectAnnotations - E.g. (import projectAnnotations from '../.storybook/preview')
*/
declare function setProjectAnnotations(projectAnnotations: NamedOrDefaultProjectAnnotations<any> | NamedOrDefaultProjectAnnotations<any>[]): NormalizedProjectAnnotations<AngularRenderer>;
declare const moduleMetadata: <TArgs = any>(metadata: Partial<NgModuleMetadata>) => DecoratorFunction<AngularRenderer, TArgs>;
/**
* Decorator to set the config options which are available during the application bootstrap
* operation
*/
declare function applicationConfig<TArgs = any>(
/** Set of config options available during the application bootstrap operation. */
config: ApplicationConfig): DecoratorFunction<AngularRenderer, TArgs>;
declare const componentWrapperDecorator: <TArgs = any>(element: Type<unknown> | ((story: string) => string), props?: ICollection | ((storyContext: StoryContext$1<AngularRenderer, TArgs>) => ICollection)) => DecoratorFunction<AngularRenderer, TArgs>;
/**
* Options for controlling the behavior of the argsToTemplate function.
*
* @template T The type of the keys in the target object.
*/
interface ArgsToTemplateOptions<T> {
/**
* An array of keys to specifically include in the output. If provided, only the keys from this
* array will be included in the output, irrespective of the `exclude` option. Undefined values
* will still be excluded from the output.
*/
include?: Array<T>;
/**
* An array of keys to specifically exclude from the output. If provided, these keys will be
* omitted from the output. This option is ignored if the `include` option is also provided
*/
exclude?: Array<T>;
}
/**
* Converts an object of arguments to a string of property and event bindings and excludes undefined
* values. Why? Because Angular treats undefined values in property bindings as an actual value and
* does not apply the default value of the property as soon as the binding is set. This feels
* counter-intuitive and is a common source of bugs in stories.
*
* @example
*
* ```ts
* // component.ts
* ㅤ@Component({ selector: 'example' })
* export class ExampleComponent {
* ㅤ@Input() input1: string = 'Default Input1';
* ㅤ@Input() input2: string = 'Default Input2';
* ㅤ@Output() click = new EventEmitter();
* }
*
* // component.stories.ts
* import { argsToTemplate } from '@storybook/angular';
* export const Input1: Story = {
* render: (args) => ({
* props: args,
* // Problem1: <example [input1]="input1" [input2]="input2" (click)="click($event)"></example>
* // This will set input2 to undefined and the internal default value will not be used.
* // Problem2: <example [input1]="input1" (click)="click($event)"></example>
* // The default value of input2 will be used, but it is not overridable by the user via controls.
* // Solution: Now the controls will be applicable to both input1 and input2, and the default values will be used if the user does not override them.
* template: `<example ${argsToTemplate(args)}"></example>`,
* }),
* args: {
* // In this Story, we want to set the input1 property, and the internal default property of input2 should be used.
* input1: 'Input 1',
* click: { action: 'clicked' },
* },
* };
* ```
*/
declare function argsToTemplate<A extends Record<string, any>>(args: A, options?: ArgsToTemplateOptions<keyof A>): string;
export { AngularRenderer, Decorator, Loader, Meta, Preview, StoryContext, StoryFn, StoryObj, applicationConfig, argsToTemplate, componentWrapperDecorator, moduleMetadata, setProjectAnnotations };