1 | ;
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.argsToTemplate = void 0;
|
4 | /**
|
5 | * Converts an object of arguments to a string of property and event bindings and excludes undefined values.
|
6 | * Why? Because Angular treats undefined values in property bindings as an actual value
|
7 | * and does not apply the default value of the property as soon as the binding is set.
|
8 | * This feels counter-intuitive and is a common source of bugs in stories.
|
9 | * @example
|
10 | * ```ts
|
11 | * // component.ts
|
12 | *ㅤ@Component({ selector: 'example' })
|
13 | * export class ExampleComponent {
|
14 | * ㅤ@Input() input1: string = 'Default Input1';
|
15 | * ㅤ@Input() input2: string = 'Default Input2';
|
16 | * ㅤ@Output() click = new EventEmitter();
|
17 | * }
|
18 | *
|
19 | * // component.stories.ts
|
20 | * import { argsToTemplate } from '@storybook/angular';
|
21 | * export const Input1: Story = {
|
22 | * render: (args) => ({
|
23 | * props: args,
|
24 | * // Problem1: <example [input1]="input1" [input2]="input2" (click)="click($event)"></example>
|
25 | * // This will set input2 to undefined and the internal default value will not be used.
|
26 | * // Problem2: <example [input1]="input1" (click)="click($event)"></example>
|
27 | * // The default value of input2 will be used, but it is not overridable by the user via controls.
|
28 | * // 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.
|
29 | * template: `<example ${argsToTemplate(args)}"></example>`,
|
30 | * }),
|
31 | * args: {
|
32 | * // In this Story, we want to set the input1 property, and the internal default property of input2 should be used.
|
33 | * input1: 'Input 1',
|
34 | * click: { action: 'clicked' },
|
35 | * },
|
36 | *};
|
37 | * ```
|
38 | */
|
39 | function argsToTemplate(args, options = {}) {
|
40 | const includeSet = options.include ? new Set(options.include) : null;
|
41 | const excludeSet = options.exclude ? new Set(options.exclude) : null;
|
42 | return Object.entries(args)
|
43 | .filter(([key]) => args[key] !== undefined)
|
44 | .filter(([key]) => {
|
45 | if (includeSet)
|
46 | return includeSet.has(key);
|
47 | if (excludeSet)
|
48 | return !excludeSet.has(key);
|
49 | return true;
|
50 | })
|
51 | .map(([key, value]) => typeof value === 'function' ? `(${key})="${key}($event)"` : `[${key}]="${key}"`)
|
52 | .join(' ');
|
53 | }
|
54 | exports.argsToTemplate = argsToTemplate;
|