From 6c059eab7d9f73b85f65254db861c6c03c0e173c Mon Sep 17 00:00:00 2001 From: Katerina Skroumpelou Date: Thu, 23 Feb 2023 17:11:41 +0200 Subject: [PATCH] feat(storybook): csf3 stories generator (#15192) --- .../component-story.spec.ts.snap | 24 +- .../component-story/component-story.spec.ts | 33 +- .../__componentFileName__.stories.ts__tmpl__ | 24 +- .../__snapshots__/stories-app.spec.ts.snap | 655 ++++++++++++++++++ .../__snapshots__/stories-lib.spec.ts.snap | 96 +-- .../generators/stories/stories-app.spec.ts | 10 +- .../component-story.spec.ts.snap | 612 ++++++++++++++++ .../component-story/component-story.spec.ts | 206 +----- .../__componentFileName__.stories.__fileExt__ | 13 +- 9 files changed, 1358 insertions(+), 315 deletions(-) create mode 100644 packages/angular/src/generators/stories/__snapshots__/stories-app.spec.ts.snap create mode 100644 packages/react/src/generators/component-story/__snapshots__/component-story.spec.ts.snap diff --git a/packages/angular/src/generators/component-story/__snapshots__/component-story.spec.ts.snap b/packages/angular/src/generators/component-story/__snapshots__/component-story.spec.ts.snap index ed20d80927882..9a14b41748b3a 100644 --- a/packages/angular/src/generators/component-story/__snapshots__/component-story.spec.ts.snap +++ b/packages/angular/src/generators/component-story/__snapshots__/component-story.spec.ts.snap @@ -1,29 +1,23 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`componentStory generator should generate the right props 1`] = ` -"import { moduleMetadata, Story, Meta } from '@storybook/angular'; +"import { Meta } from '@storybook/angular'; import { TestButtonComponent } from './test-button.component'; export default { title: 'TestButtonComponent', - component: TestButtonComponent, - decorators: [ - moduleMetadata({ - imports: [], - }) - ], + component: TestButtonComponent } as Meta; -const Template: Story = (args: TestButtonComponent) => ({ - props: args, -}); - - -export const Primary = Template.bind({}); -Primary.args = { +export const Primary = { + render: (args: TestButtonComponent) => ({ + props: args, + }), + args: { buttonType: 'button', style: 'default', age: 0, isOn: false, -}" + }, +};" `; diff --git a/packages/angular/src/generators/component-story/component-story.spec.ts b/packages/angular/src/generators/component-story/component-story.spec.ts index cd9a00c836b49..796e0ba979fca 100644 --- a/packages/angular/src/generators/component-story/component-story.spec.ts +++ b/packages/angular/src/generators/component-story/component-story.spec.ts @@ -29,22 +29,22 @@ describe('componentStory generator', () => { `libs/${libName}/src/lib/test-button/test-button.component.ts`, `import { Component, Input } from '@angular/core'; -export type ButtonStyle = 'default' | 'primary' | 'accent'; + export type ButtonStyle = 'default' | 'primary' | 'accent'; -@Component({ - selector: 'proj-test-button', - templateUrl: './test-button.component.html', - styleUrls: ['./test-button.component.css'] -}) -export class TestButtonComponent { - @Input('buttonType') type = 'button'; - @Input() style: ButtonStyle = 'default'; - @Input() age?: number; - @Input() isOn = false; - @Input() message: string | undefined; - @Input() anotherProp: any; - @Input() anotherNeverProp: never; -}` + @Component({ + selector: 'proj-test-button', + templateUrl: './test-button.component.html', + styleUrls: ['./test-button.component.css'] + }) + export class TestButtonComponent { + @Input('buttonType') type = 'button'; + @Input() style: ButtonStyle = 'default'; + @Input() age?: number; + @Input() isOn = false; + @Input() message: string | undefined; + @Input() anotherProp: any; + @Input() anotherNeverProp: never; + }` ); }); @@ -84,7 +84,6 @@ export class TestButtonComponent { projectPath: `libs/${libName}`, }); - const storiesFileContent = tree.read(storyFile).toString(); - expect(storiesFileContent).toMatchSnapshot(); + expect(tree.read(storyFile).toString()).toMatchSnapshot(); }); }); diff --git a/packages/angular/src/generators/component-story/files/__componentFileName__.stories.ts__tmpl__ b/packages/angular/src/generators/component-story/files/__componentFileName__.stories.ts__tmpl__ index d9f8c697a2127..338a94bde0e8c 100644 --- a/packages/angular/src/generators/component-story/files/__componentFileName__.stories.ts__tmpl__ +++ b/packages/angular/src/generators/component-story/files/__componentFileName__.stories.ts__tmpl__ @@ -1,22 +1,16 @@ -import { moduleMetadata, Story, Meta } from '@storybook/angular'; +import { Meta } from '@storybook/angular'; import { <%=componentName%> } from './<%=componentFileName%>'; export default { title: '<%=componentName%>', - component: <%=componentName%>, - decorators: [ - moduleMetadata({ - imports: [], - }) - ], + component: <%=componentName%> } as Meta<<%=componentName%>>; -const Template: Story<<%=componentName%>> = (args: <%=componentName%>) => ({ - props: args, -}); - - -export const Primary = Template.bind({}); -Primary.args = {<% for (let prop of props) { %> +export const Primary = { + render: (args: <%=componentName%>) => ({ + props: args, + }), + args: {<% for (let prop of props) { %> <%= prop.name %>: <%- prop.defaultValue %>,<% } %> -} \ No newline at end of file + }, +}; \ No newline at end of file diff --git a/packages/angular/src/generators/stories/__snapshots__/stories-app.spec.ts.snap b/packages/angular/src/generators/stories/__snapshots__/stories-app.spec.ts.snap new file mode 100644 index 0000000000000..ac9b5e25e3799 --- /dev/null +++ b/packages/angular/src/generators/stories/__snapshots__/stories-app.spec.ts.snap @@ -0,0 +1,655 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`angularStories generator: applications should generate stories file for inline scam component 1`] = ` +Object { + "data": Array [ + 105, + 109, + 112, + 111, + 114, + 116, + 32, + 123, + 32, + 77, + 101, + 116, + 97, + 32, + 125, + 32, + 102, + 114, + 111, + 109, + 32, + 39, + 64, + 115, + 116, + 111, + 114, + 121, + 98, + 111, + 111, + 107, + 47, + 97, + 110, + 103, + 117, + 108, + 97, + 114, + 39, + 59, + 10, + 105, + 109, + 112, + 111, + 114, + 116, + 32, + 123, + 32, + 77, + 121, + 83, + 99, + 97, + 109, + 67, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 32, + 125, + 32, + 102, + 114, + 111, + 109, + 32, + 39, + 46, + 47, + 109, + 121, + 45, + 115, + 99, + 97, + 109, + 46, + 99, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 39, + 59, + 10, + 10, + 101, + 120, + 112, + 111, + 114, + 116, + 32, + 100, + 101, + 102, + 97, + 117, + 108, + 116, + 32, + 123, + 10, + 32, + 32, + 116, + 105, + 116, + 108, + 101, + 58, + 32, + 39, + 77, + 121, + 83, + 99, + 97, + 109, + 67, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 39, + 44, + 10, + 32, + 32, + 99, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 58, + 32, + 77, + 121, + 83, + 99, + 97, + 109, + 67, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 10, + 125, + 32, + 97, + 115, + 32, + 77, + 101, + 116, + 97, + 60, + 77, + 121, + 83, + 99, + 97, + 109, + 67, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 62, + 59, + 10, + 10, + 101, + 120, + 112, + 111, + 114, + 116, + 32, + 99, + 111, + 110, + 115, + 116, + 32, + 80, + 114, + 105, + 109, + 97, + 114, + 121, + 32, + 61, + 32, + 123, + 10, + 32, + 32, + 114, + 101, + 110, + 100, + 101, + 114, + 58, + 32, + 40, + 97, + 114, + 103, + 115, + 58, + 32, + 77, + 121, + 83, + 99, + 97, + 109, + 67, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 41, + 32, + 61, + 62, + 32, + 40, + 123, + 10, + 32, + 32, + 32, + 32, + 112, + 114, + 111, + 112, + 115, + 58, + 32, + 97, + 114, + 103, + 115, + 44, + 10, + 32, + 32, + 125, + 41, + 44, + 10, + 32, + 32, + 97, + 114, + 103, + 115, + 58, + 32, + 123, + 10, + 32, + 32, + 125, + 44, + 10, + 125, + 59, + ], + "type": "Buffer", +} +`; + +exports[`angularStories generator: applications should ignore a path that has a nested component, but still generate nested component stories 1`] = ` +Object { + "data": Array [ + 105, + 109, + 112, + 111, + 114, + 116, + 32, + 123, + 32, + 77, + 101, + 116, + 97, + 32, + 125, + 32, + 102, + 114, + 111, + 109, + 32, + 39, + 64, + 115, + 116, + 111, + 114, + 121, + 98, + 111, + 111, + 107, + 47, + 97, + 110, + 103, + 117, + 108, + 97, + 114, + 39, + 59, + 10, + 105, + 109, + 112, + 111, + 114, + 116, + 32, + 123, + 32, + 67, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 66, + 67, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 32, + 125, + 32, + 102, + 114, + 111, + 109, + 32, + 39, + 46, + 47, + 99, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 45, + 98, + 46, + 99, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 39, + 59, + 10, + 10, + 101, + 120, + 112, + 111, + 114, + 116, + 32, + 100, + 101, + 102, + 97, + 117, + 108, + 116, + 32, + 123, + 10, + 32, + 32, + 116, + 105, + 116, + 108, + 101, + 58, + 32, + 39, + 67, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 66, + 67, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 39, + 44, + 10, + 32, + 32, + 99, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 58, + 32, + 67, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 66, + 67, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 10, + 125, + 32, + 97, + 115, + 32, + 77, + 101, + 116, + 97, + 60, + 67, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 66, + 67, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 62, + 59, + 10, + 10, + 101, + 120, + 112, + 111, + 114, + 116, + 32, + 99, + 111, + 110, + 115, + 116, + 32, + 80, + 114, + 105, + 109, + 97, + 114, + 121, + 32, + 61, + 32, + 123, + 10, + 32, + 32, + 114, + 101, + 110, + 100, + 101, + 114, + 58, + 32, + 40, + 97, + 114, + 103, + 115, + 58, + 32, + 67, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 66, + 67, + 111, + 109, + 112, + 111, + 110, + 101, + 110, + 116, + 41, + 32, + 61, + 62, + 32, + 40, + 123, + 10, + 32, + 32, + 32, + 32, + 112, + 114, + 111, + 112, + 115, + 58, + 32, + 97, + 114, + 103, + 115, + 44, + 10, + 32, + 32, + 125, + 41, + 44, + 10, + 32, + 32, + 97, + 114, + 103, + 115, + 58, + 32, + 123, + 10, + 32, + 32, + 125, + 44, + 10, + 125, + 59, + ], + "type": "Buffer", +} +`; diff --git a/packages/angular/src/generators/stories/__snapshots__/stories-lib.spec.ts.snap b/packages/angular/src/generators/stories/__snapshots__/stories-lib.spec.ts.snap index 73cc40cb16b09..b5fb99eb46fd9 100644 --- a/packages/angular/src/generators/stories/__snapshots__/stories-lib.spec.ts.snap +++ b/packages/angular/src/generators/stories/__snapshots__/stories-lib.spec.ts.snap @@ -10,105 +10,81 @@ exports[`angularStories generator: libraries Stories for non-empty Angular libra `; exports[`angularStories generator: libraries Stories for non-empty Angular library should generate stories file for standalone components 1`] = ` -"import { moduleMetadata, Story, Meta } from '@storybook/angular'; +"import { Meta } from '@storybook/angular'; import { StandaloneComponent } from './standalone.component'; export default { title: 'StandaloneComponent', - component: StandaloneComponent, - decorators: [ - moduleMetadata({ - imports: [], - }) - ], + component: StandaloneComponent } as Meta; -const Template: Story = (args: StandaloneComponent) => ({ - props: args, -}); - - -export const Primary = Template.bind({}); -Primary.args = { -}" +export const Primary = { + render: (args: StandaloneComponent) => ({ + props: args, + }), + args: { + }, +};" `; exports[`angularStories generator: libraries Stories for non-empty Angular library should generate stories file for standalone components 2`] = ` -"import { moduleMetadata, Story, Meta } from '@storybook/angular'; +"import { Meta } from '@storybook/angular'; import { SecondaryStandaloneComponent } from './secondary-standalone.component'; export default { title: 'SecondaryStandaloneComponent', - component: SecondaryStandaloneComponent, - decorators: [ - moduleMetadata({ - imports: [], - }) - ], + component: SecondaryStandaloneComponent } as Meta; -const Template: Story = (args: SecondaryStandaloneComponent) => ({ - props: args, -}); - - -export const Primary = Template.bind({}); -Primary.args = { -}" +export const Primary = { + render: (args: SecondaryStandaloneComponent) => ({ + props: args, + }), + args: { + }, +};" `; exports[`angularStories generator: libraries Stories for non-empty Angular library should generate stories.ts files 1`] = ` -"import { moduleMetadata, Story, Meta } from '@storybook/angular'; +"import { Meta } from '@storybook/angular'; import { TestButtonComponent } from './test-button.component'; export default { title: 'TestButtonComponent', - component: TestButtonComponent, - decorators: [ - moduleMetadata({ - imports: [], - }) - ], + component: TestButtonComponent } as Meta; -const Template: Story = (args: TestButtonComponent) => ({ - props: args, -}); - - -export const Primary = Template.bind({}); -Primary.args = { +export const Primary = { + render: (args: TestButtonComponent) => ({ + props: args, + }), + args: { buttonType: 'button', style: 'default', age: 0, isOn: false, -}" + }, +};" `; exports[`angularStories generator: libraries Stories for non-empty Angular library should ignore paths 1`] = ` -"import { moduleMetadata, Story, Meta } from '@storybook/angular'; +"import { Meta } from '@storybook/angular'; import { TestButtonComponent } from './test-button.component'; export default { title: 'TestButtonComponent', - component: TestButtonComponent, - decorators: [ - moduleMetadata({ - imports: [], - }) - ], + component: TestButtonComponent } as Meta; -const Template: Story = (args: TestButtonComponent) => ({ - props: args, -}); - - -export const Primary = Template.bind({}); -Primary.args = { +export const Primary = { + render: (args: TestButtonComponent) => ({ + props: args, + }), + args: { buttonType: 'button', style: 'default', age: 0, isOn: false, -}" + }, +};" `; diff --git a/packages/angular/src/generators/stories/stories-app.spec.ts b/packages/angular/src/generators/stories/stories-app.spec.ts index d8c6afecf0c3c..2be9a6de47bde 100644 --- a/packages/angular/src/generators/stories/stories-app.spec.ts +++ b/packages/angular/src/generators/stories/stories-app.spec.ts @@ -89,10 +89,10 @@ describe('angularStories generator: applications', () => { }); expect( - tree.exists( + tree.read( `apps/${appName}/src/app/component-a/component-b/component-b.component.stories.ts` ) - ).toBeTruthy(); + ).toMatchSnapshot(); expect( tree.exists( `apps/${appName}/src/app/component-a/component-a.component.stories.ts` @@ -110,10 +110,8 @@ describe('angularStories generator: applications', () => { angularStoriesGenerator(tree, { name: appName }); expect( - tree.exists( - `apps/${appName}/src/app/my-scam/my-scam.component.stories.ts` - ) - ).toBeTruthy(); + tree.read(`apps/${appName}/src/app/my-scam/my-scam.component.stories.ts`) + ).toMatchSnapshot(); }); it('should generate cypress spec file', () => { diff --git a/packages/react/src/generators/component-story/__snapshots__/component-story.spec.ts.snap b/packages/react/src/generators/component-story/__snapshots__/component-story.spec.ts.snap new file mode 100644 index 0000000000000..5edd1c4ef6907 --- /dev/null +++ b/packages/react/src/generators/component-story/__snapshots__/component-story.spec.ts.snap @@ -0,0 +1,612 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`react:component-story default setup Other types of component definitions Component files with DEFAULT export React component defined as: PureComponent class & then default export new JSX transform should properly setup the controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with DEFAULT export React component defined as: PureComponent class & then default export should properly setup the controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with DEFAULT export React component defined as: arrow function should properly setup the controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with DEFAULT export React component defined as: arrow function without {..} should properly setup the controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with DEFAULT export React component defined as: component class & then default export new JSX transform should properly setup the controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with DEFAULT export React component defined as: component class & then default export should properly setup the controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with DEFAULT export React component defined as: default export function should properly setup the controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with DEFAULT export React component defined as: direct export of component class new JSX transform should properly setup the controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with DEFAULT export React component defined as: direct export of component class should properly setup the controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with DEFAULT export React component defined as: function and then export should properly setup the controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with NO DEFAULT export React component defined as: no default PureComponent class & then default export new JSX transform should properly setup the controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with NO DEFAULT export React component defined as: no default PureComponent class & then default export should properly setup the controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with NO DEFAULT export React component defined as: no default arrow function should properly setup the controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with NO DEFAULT export React component defined as: no default arrow function without {..} should properly setup the controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with NO DEFAULT export React component defined as: no default component class should properly setup the controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with NO DEFAULT export React component defined as: no default direct export of component class new JSX transform should properly setup the controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with NO DEFAULT export React component defined as: no default direct export of component class should properly setup the controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with NO DEFAULT export React component defined as: no default simple export function should properly setup the controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with NO DEFAULT export should create stories for all components in a file with no default export 1`] = ` +"import type { Meta } from '@storybook/react'; +import { One } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: One, + title: 'One', +}; +export default Story; + + +export const Primary = { + args: { + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with NO DEFAULT export should create stories for all components in a file with no default export 2`] = ` +"import type { Meta } from '@storybook/react'; +import { Two } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Two, + title: 'Two', +}; +export default Story; + + +export const Primary = { + args: { + }, +};" +`; + +exports[`react:component-story default setup Other types of component definitions Component files with NO DEFAULT export should create stories for all components in a file with no default export 3`] = ` +"import type { Meta } from '@storybook/react'; +import { Three } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Three, + title: 'Three', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + }, +};" +`; + +exports[`react:component-story default setup component with props and actions should setup controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', + argTypes: { + someAction: { action : \\"someAction executed!\\" }, +} + +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup component with props should setup controls based on the component props 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + name: '', + displayAge: false, + }, +};" +`; + +exports[`react:component-story default setup component without any props defined should create a story without controls 1`] = ` +"import type { Meta } from '@storybook/react'; +import { Test } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: Test, + title: 'Test', +}; +export default Story; + + +export const Primary = { + args: { + }, +};" +`; + +exports[`react:component-story default setup default component setup should properly set up the story 1`] = ` +"import type { Meta } from '@storybook/react'; +import { TestUiLib } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: TestUiLib, + title: 'TestUiLib', +}; +export default Story; + + +export const Primary = { + args: { + }, +};" +`; + +exports[`react:component-story default setup when using plain JS components should properly set up the story 1`] = ` +" +import Test from './test-ui-libplain'; + + +export default { + component: Test, + title: 'Test', +}; + + + + + +export const Primary = { + args: { + }, +};" +`; + +exports[`react:component-story using eslint should properly set up the story 1`] = ` +"import type { Meta } from '@storybook/react'; +import { TestUiLib } from './test-ui-lib'; + + + + + +const Story: Meta = { + component: TestUiLib, + title: 'TestUiLib', +}; +export default Story; + + +export const Primary = { + args: { + }, +};" +`; diff --git a/packages/react/src/generators/component-story/component-story.spec.ts b/packages/react/src/generators/component-story/component-story.spec.ts index dedc9101c4057..8ef4df7367040 100644 --- a/packages/react/src/generators/component-story/component-story.spec.ts +++ b/packages/react/src/generators/component-story/component-story.spec.ts @@ -3,7 +3,6 @@ import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; import libraryGenerator from '../library/library'; import componentStoryGenerator from './component-story'; import { Linter } from '@nrwl/linter'; -import { formatFile } from '../../utils/format-file'; describe('react:component-story', () => { let appTree: Tree; @@ -50,22 +49,7 @@ describe('react:component-story', () => { }); it('should properly set up the story', () => { - expect(formatFile`${appTree.read(storyFilePath, 'utf-8')}`) - .toContain(formatFile` - import type { ComponentStory, ComponentMeta } from '@storybook/react'; - import { TestUiLib } from './test-ui-lib'; - - const Story: ComponentMeta = { - component: TestUiLib, - title: 'TestUiLib' - }; - export default Story; - - const Template: ComponentStory = (args) => ; - - export const Primary = Template.bind({}); - Primary.args = {}; - `); + expect(appTree.read(storyFilePath, 'utf-8')).toMatchSnapshot(); }); }); @@ -103,20 +87,7 @@ describe('react:component-story', () => { }); it('should properly set up the story', () => { - expect(formatFile`${appTree.read(storyFilePathPlain, 'utf-8')}`) - .toContain(formatFile` - import Test from './test-ui-libplain'; - - export default { - component: Test, - title: 'Test' - }; - - const Template = (args) => ; - - export const Primary = Template.bind({}); - Primary.args = {}; - `); + expect(appTree.read(storyFilePathPlain, 'utf-8')).toMatchSnapshot(); }); }); @@ -147,22 +118,7 @@ describe('react:component-story', () => { }); it('should create a story without controls', () => { - expect(formatFile`${appTree.read(storyFilePath, 'utf-8')}`) - .toContain(formatFile` - import type { ComponentStory, ComponentMeta } from '@storybook/react'; - import { Test } from './test-ui-lib'; - - const Story: ComponentMeta = { - component: Test, - title: 'Test' - }; - export default Story; - - const Template: ComponentStory = (args) => ; - - export const Primary = Template.bind({}); - Primary.args = {}; - `); + expect(appTree.read(storyFilePath, 'utf-8')).toMatchSnapshot(); }); }); @@ -198,25 +154,7 @@ describe('react:component-story', () => { }); it('should setup controls based on the component props', () => { - expect(formatFile`${appTree.read(storyFilePath, 'utf-8')}`) - .toContain(formatFile` - import type { ComponentStory, ComponentMeta } from '@storybook/react'; - import { Test } from './test-ui-lib'; - - const Story: ComponentMeta = { - component: Test, - title: 'Test' - }; - export default Story; - - const Template: ComponentStory = (args) => ; - - export const Primary = Template.bind({}); - Primary.args = { - name: '', - displayAge: false, - }; - `); + expect(appTree.read(storyFilePath, 'utf-8')).toMatchSnapshot(); }); }); @@ -257,28 +195,7 @@ describe('react:component-story', () => { }); it('should setup controls based on the component props', () => { - expect(formatFile`${appTree.read(storyFilePath, 'utf-8')}`) - .toContain(formatFile` - import type { ComponentStory, ComponentMeta } from '@storybook/react'; - import { Test } from './test-ui-lib'; - - const Story: ComponentMeta = { - component: Test, - title: 'Test', - argTypes: { - someAction: { action: 'someAction executed!' }, - } - }; - export default Story; - - const Template: ComponentStory = (args) => ; - - export const Primary = Template.bind({}); - Primary.args = { - name: '', - displayAge: false, - }; - `); + expect(appTree.read(storyFilePath, 'utf-8')).toMatchSnapshot(); }); }); @@ -421,25 +338,7 @@ describe('react:component-story', () => { }); it('should properly setup the controls based on the component props', () => { - expect(formatFile`${appTree.read(storyFilePath, 'utf-8')}`) - .toContain(formatFile` - import type { ComponentStory, ComponentMeta } from '@storybook/react'; - import { Test } from './test-ui-lib'; - - const Story: ComponentMeta = { - component: Test, - title: 'Test' - }; - export default Story; - - const Template: ComponentStory = (args) => ; - - export const Primary = Template.bind({}); - Primary.args = { - name: '', - displayAge: false, - }; - `); + expect(appTree.read(storyFilePath, 'utf-8')).toMatchSnapshot(); }); } ); @@ -554,25 +453,7 @@ describe('react:component-story', () => { }); it('should properly setup the controls based on the component props', () => { - expect(formatFile`${appTree.read(storyFilePath, 'utf-8')}`) - .toContain(formatFile` - import type { ComponentStory, ComponentMeta } from '@storybook/react'; - import { Test } from './test-ui-lib'; - - const Story: ComponentMeta = { - component: Test, - title: 'Test' - }; - export default Story; - - const Template: ComponentStory = (args) => ; - - export const Primary = Template.bind({}); - Primary.args = { - name: '', - displayAge: false, - }; - `); + expect(appTree.read(storyFilePath, 'utf-8')).toMatchSnapshot(); }); } ); @@ -617,59 +498,9 @@ describe('react:component-story', () => { 'libs/test-ui-lib/src/lib/test-ui-lib--Two.stories.tsx'; const storyFilePathThree = 'libs/test-ui-lib/src/lib/test-ui-lib--Three.stories.tsx'; - - expect(formatFile`${appTree.read(storyFilePathOne, 'utf-8')}`) - .toContain(formatFile` - import type { ComponentStory, ComponentMeta } from '@storybook/react'; - import { One } from './test-ui-lib'; - - const Story: ComponentMeta = { - component: One, - title: 'One' - }; - export default Story; - - const Template: ComponentStory = (args) => ; - - export const Primary = Template.bind({}); - Primary.args = {}; - `); - - expect(formatFile`${appTree.read(storyFilePathTwo, 'utf-8')}`) - .toContain(formatFile` - import type { ComponentStory, ComponentMeta } from '@storybook/react'; - import { Two } from './test-ui-lib'; - - const Story: ComponentMeta = { - component: Two, - title: 'Two' - }; - export default Story; - - const Template: ComponentStory = (args) => ; - - export const Primary = Template.bind({}); - Primary.args = {}; - `); - - expect(formatFile`${appTree.read(storyFilePathThree, 'utf-8')}`) - .toContain(formatFile` - import type { ComponentStory, ComponentMeta } from '@storybook/react'; - import { Three } from './test-ui-lib'; - - const Story: ComponentMeta = { - component: Three, - title: 'Three' - }; - export default Story; - - const Template: ComponentStory = (args) => ; - - export const Primary = Template.bind({}); - Primary.args = { - name: '', - }; - `); + expect(appTree.read(storyFilePathOne, 'utf-8')).toMatchSnapshot(); + expect(appTree.read(storyFilePathTwo, 'utf-8')).toMatchSnapshot(); + expect(appTree.read(storyFilePathThree, 'utf-8')).toMatchSnapshot(); }); }); }); @@ -685,22 +516,7 @@ describe('react:component-story', () => { }); it('should properly set up the story', () => { - expect(formatFile`${appTree.read(storyFilePath, 'utf-8')}`) - .toContain(formatFile` - import type { ComponentStory, ComponentMeta } from '@storybook/react'; - import { TestUiLib } from './test-ui-lib'; - - const Story: ComponentMeta = { - component: TestUiLib, - title: 'TestUiLib' - }; - export default Story; - - const Template: ComponentStory = (args) => ; - - export const Primary = Template.bind({}); - Primary.args = {}; - `); + expect(appTree.read(storyFilePath, 'utf-8')).toMatchSnapshot(); }); }); }); diff --git a/packages/react/src/generators/component-story/files/__componentFileName__.stories.__fileExt__ b/packages/react/src/generators/component-story/files/__componentFileName__.stories.__fileExt__ index 1bc3c674add11..12b9ccd9b1f5c 100644 --- a/packages/react/src/generators/component-story/files/__componentFileName__.stories.__fileExt__ +++ b/packages/react/src/generators/component-story/files/__componentFileName__.stories.__fileExt__ @@ -1,4 +1,4 @@ -<% if ( !isPlainJs ) { %>import type { ComponentStory, ComponentMeta } from '@storybook/react';<% } %> +<% if ( !isPlainJs ) { %>import type { Meta } from '@storybook/react';<% } %> import<% if ( !isPlainJs ) { %> { <% } %> <%= componentName %> <% if ( !isPlainJs ) { %> } <% } %> from './<%= componentImportFileName %>'; <% if ( isPlainJs ) { %> @@ -14,7 +14,7 @@ export default { <% if ( !isPlainJs ) { %> -const Story: ComponentMeta> = { +const Story: Meta> = { component: <%= componentName %>, title: '<%= componentName %>',<% if ( argTypes && argTypes.length > 0 ) { %> argTypes: {<% for (let argType of argTypes) { %> @@ -25,9 +25,8 @@ const Story: ComponentMeta> = { export default Story; <% } %> -const Template<% if ( !isPlainJs ) { %>: ComponentStory< typeof <%= componentName %> ><% } %> = (args) => <<%= componentName %> {...args} />; - -export const Primary = Template.bind({}) -Primary.args = {<% for (let prop of props) { %> +export const Primary = { + args: {<% for (let prop of props) { %> <%= prop.name %>: <%- prop.defaultValue %>,<% } %> -} \ No newline at end of file + }, +}; \ No newline at end of file