UNPKG

@storybook/angular

Version:

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

145 lines (139 loc) 7.25 kB
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 };