UNPKG

2.46 kBTypeScriptView Raw
1/**
2 * Options for controlling the behavior of the argsToTemplate function.
3 *
4 * @template T The type of the keys in the target object.
5 */
6export interface ArgsToTemplateOptions<T> {
7 /**
8 * An array of keys to specifically include in the output.
9 * If provided, only the keys from this array will be included in the output,
10 * irrespective of the `exclude` option. Undefined values will still be excluded from the output.
11 */
12 include?: Array<T>;
13 /**
14 * An array of keys to specifically exclude from the output.
15 * If provided, these keys will be omitted from the output. This option is
16 * ignored if the `include` option is also provided
17 */
18 exclude?: Array<T>;
19}
20/**
21 * Converts an object of arguments to a string of property and event bindings and excludes undefined values.
22 * Why? Because Angular treats undefined values in property bindings as an actual value
23 * and does not apply the default value of the property as soon as the binding is set.
24 * This feels counter-intuitive and is a common source of bugs in stories.
25 * @example
26 * ```ts
27 * // component.ts
28 *ㅤ@Component({ selector: 'example' })
29 * export class ExampleComponent {
30 * ㅤ@Input() input1: string = 'Default Input1';
31 * ㅤ@Input() input2: string = 'Default Input2';
32 * ㅤ@Output() click = new EventEmitter();
33 * }
34 *
35 * // component.stories.ts
36 * import { argsToTemplate } from '@storybook/angular';
37 * export const Input1: Story = {
38 * render: (args) => ({
39 * props: args,
40 * // Problem1: <example [input1]="input1" [input2]="input2" (click)="click($event)"></example>
41 * // This will set input2 to undefined and the internal default value will not be used.
42 * // Problem2: <example [input1]="input1" (click)="click($event)"></example>
43 * // The default value of input2 will be used, but it is not overridable by the user via controls.
44 * // 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.
45 * template: `<example ${argsToTemplate(args)}"></example>`,
46 * }),
47 * args: {
48 * // In this Story, we want to set the input1 property, and the internal default property of input2 should be used.
49 * input1: 'Input 1',
50 * click: { action: 'clicked' },
51 * },
52 *};
53 * ```
54 */
55export declare function argsToTemplate<A extends Record<string, any>>(args: A, options?: ArgsToTemplateOptions<keyof A>): string;