@storybook/angular 7.0.0-beta.6 → 7.0.0-beta.61

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +66 -0
  2. package/dist/builders/build-storybook/index.d.ts +5 -3
  3. package/dist/builders/build-storybook/index.js +7 -3
  4. package/dist/builders/build-storybook/schema.json +14 -6
  5. package/dist/builders/start-storybook/index.d.ts +5 -3
  6. package/dist/builders/start-storybook/index.js +9 -5
  7. package/dist/builders/start-storybook/schema.json +10 -5
  8. package/dist/builders/utils/run-compodoc.js +11 -27
  9. package/dist/builders/utils/run-compodoc.spec.js +42 -0
  10. package/dist/builders/utils/standalone-options.d.ts +2 -2
  11. package/dist/client/angular-beta/AbstractRenderer.d.ts +3 -3
  12. package/dist/client/angular-beta/AbstractRenderer.js +31 -31
  13. package/dist/client/angular-beta/CanvasRenderer.js +1 -1
  14. package/dist/client/angular-beta/DocsRenderer.js +5 -3
  15. package/dist/client/angular-beta/RendererFactory.js +5 -4
  16. package/dist/client/angular-beta/StorybookModule.d.ts +3 -6
  17. package/dist/client/angular-beta/StorybookModule.js +4 -45
  18. package/dist/client/angular-beta/StorybookModule.test.js +51 -36
  19. package/dist/client/angular-beta/StorybookWrapperComponent.d.ts +3 -2
  20. package/dist/client/angular-beta/StorybookWrapperComponent.js +30 -2
  21. package/dist/client/angular-beta/__testfixtures__/test.module.d.ts +2 -0
  22. package/dist/client/angular-beta/__testfixtures__/test.module.js +20 -0
  23. package/dist/client/angular-beta/utils/NgComponentAnalyzer.js +1 -1
  24. package/dist/client/angular-beta/utils/NgComponentAnalyzer.test.js +43 -5
  25. package/dist/client/angular-beta/utils/NgModulesAnalyzer.d.ts +1 -1
  26. package/dist/client/angular-beta/utils/NgModulesAnalyzer.js +4 -4
  27. package/dist/client/angular-beta/utils/NgModulesAnalyzer.test.js +3 -3
  28. package/dist/client/angular-beta/utils/PropertyExtractor.d.ts +32 -0
  29. package/dist/client/angular-beta/utils/PropertyExtractor.js +136 -0
  30. package/dist/client/angular-beta/utils/PropertyExtractor.test.d.ts +1 -0
  31. package/dist/client/angular-beta/utils/PropertyExtractor.test.js +141 -0
  32. package/dist/client/config.d.ts +1 -1
  33. package/dist/client/config.js +1 -1
  34. package/dist/client/decorateStory.js +1 -1
  35. package/dist/client/docs/compodoc.js +5 -7
  36. package/dist/client/docs/config.js +1 -2
  37. package/dist/client/docs/sourceDecorator.js +2 -1
  38. package/dist/client/globals.d.ts +0 -8
  39. package/dist/client/globals.js +2 -29
  40. package/dist/client/public-api.js +3 -3
  41. package/dist/client/public-types.d.ts +2 -1
  42. package/dist/client/render.d.ts +1 -0
  43. package/dist/client/render.js +1 -5
  44. package/dist/client/types.d.ts +1 -2
  45. package/dist/index.mjs +13 -0
  46. package/dist/preset.mjs +26 -0
  47. package/dist/renderer.d.ts +2 -1
  48. package/dist/renderer.js +4 -2
  49. package/dist/renderer.mjs +5 -0
  50. package/dist/server/framework-preset-angular-cli.d.ts +2 -1
  51. package/dist/server/framework-preset-angular-cli.js +21 -92
  52. package/dist/server/plugins/storybook-normalize-angular-entry-plugin.js +15 -13
  53. package/dist/server/preset-options.d.ts +3 -2
  54. package/dist/types.mjs +1 -0
  55. package/jest.config.js +19 -0
  56. package/package.json +46 -45
  57. package/template/cli/Button.stories.ts +1 -1
  58. package/template/cli/Header.stories.ts +2 -2
  59. package/template/cli/button.component.ts +2 -0
  60. package/template/components/index.js +2 -2
  61. package/template/stories/angular-mdx.stories.mdx +1 -1
  62. package/template/stories/argTypes/doc-button/doc-button.component.ts +1 -2
  63. package/template/stories/basics/component-without-selector/without-selector-ng-component-outlet.stories.ts +1 -1
  64. package/template/stories/basics/component-without-selector/without-selector-ng-factory-resolver.stories.ts +1 -1
  65. package/template/stories/basics/component-without-selector/without-selector.stories.ts +1 -1
  66. package/template/stories/basics/ng-module/import-module-chip.stories.ts +23 -0
  67. package/template/stories/basics/ng-module/import-module.stories.ts +2 -13
  68. package/template/stories/core/decorators/componentWrapperDecorator/decorators.stories.ts +0 -18
  69. package/template/stories/core/moduleMetadata/angular-src/open-close-component/open-close.component.css +13 -0
  70. package/template/stories/core/moduleMetadata/angular-src/open-close-component/open-close.component.html +7 -0
  71. package/template/stories/core/moduleMetadata/angular-src/open-close-component/open-close.component.ts +39 -0
  72. package/template/stories/core/moduleMetadata/with-browser-animations.stories.ts +30 -0
  73. package/template/stories/core/moduleMetadata/with-noop-browser-animations.stories.ts +27 -0
  74. package/template/stories/core/parameters/bootstrap-options.stories.ts +1 -5
  75. package/template/stories/others/app-initializer-use-factory/app-initializer-use-factory.stories.ts +34 -0
  76. package/dist/client/angular/helpers.d.ts +0 -8
  77. package/dist/client/angular/helpers.js +0 -150
  78. package/dist/server/angular-read-workspace.d.ts +0 -13
  79. package/dist/server/angular-read-workspace.js +0 -78
  80. package/dist/server/utils/normalize-asset-patterns.d.ts +0 -7
  81. package/dist/server/utils/normalize-asset-patterns.js +0 -64
  82. package/dist/server/utils/normalize-optimization.d.ts +0 -3
  83. package/dist/server/utils/normalize-optimization.js +0 -21
package/README.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Storybook for Angular
2
2
 
3
+ - [Storybook for Angular](#storybook-for-angular)
4
+ - [Getting Started](#getting-started)
5
+ - [Setup Compodoc](#setup-compodoc)
6
+ - [Support for multi-project workspace](#support-for-multi-project-workspace)
7
+ - [Run Storybook](#run-storybook)
8
+
3
9
  Storybook for Angular is a UI development environment for your Angular components.
4
10
  With it, you can visualize different states of your UI components and develop them interactively.
5
11
 
@@ -15,6 +21,66 @@ cd my-angular-app
15
21
  npx storybook init
16
22
  ```
17
23
 
24
+ ### Setup Compodoc
25
+
26
+ When installing, you will be given the option to set up Compodoc, which is a tool for creating documentation for Angular projects.
27
+
28
+ You can include JSDoc comments above components, directives, and other parts of your Angular code to include documentation for those elements. Compodoc uses these comments to generate documentation for your application. In Storybook, it is useful to add explanatory comments above @Inputs and @Outputs, since these are the main elements that Storybook displays in its user interface. The @Inputs and @Outputs are the elements that you can interact with in Storybook, such as controls.
29
+
30
+ ## Support for multi-project workspace
31
+
32
+ Storybook supports Angular multi-project workspace. You can setup Storybook for each project in the workspace. When running `npx storybook init` you will be asked for which project Storybook should be set up. Essentially, during initialization, the `angular.json` will be edited to add the Storybook configuration for the selected project. The configuration looks approximately like this:
33
+
34
+ ```json
35
+ // angular.json
36
+ {
37
+ ...
38
+ "projects": {
39
+ ...
40
+ "your-project": {
41
+ ...
42
+ "architect": {
43
+ ...
44
+ "storybook": {
45
+ "builder": "@storybook/angular:start-storybook",
46
+ "options": {
47
+ "configDir": ".storybook",
48
+ "browserTarget": "your-project:build",
49
+ "compodoc": false,
50
+ "port": 6006
51
+ }
52
+ },
53
+ "build-storybook": {
54
+ "builder": "@storybook/angular:build-storybook",
55
+ "options": {
56
+ "configDir": ".storybook",
57
+ "browserTarget": "your-project:build",
58
+ "compodoc": false,
59
+ "outputDir": "dist/storybook/your-project"
60
+ }
61
+ }
62
+ }
63
+ }
64
+ }
65
+ }
66
+ ```
67
+
68
+ ## Run Storybook
69
+
70
+ To run Storybook for a particular project, please run:
71
+
72
+ ```sh
73
+ ng run your-project:storybook
74
+ ```
75
+
76
+ To build Storybook, run:
77
+
78
+ ```sh
79
+ ng run your-project:build-storybook
80
+ ```
81
+
82
+ You will find the output in `dist/storybook/your-project`.
83
+
18
84
  For more information visit: [storybook.js.org](https://storybook.js.org)
19
85
 
20
86
  ---
@@ -1,15 +1,17 @@
1
1
  import { BuilderOutput } from '@angular-devkit/architect';
2
2
  import { JsonObject } from '@angular-devkit/core';
3
3
  import { CLIOptions } from '@storybook/types';
4
- import { ExtraEntryPoint, StylePreprocessorOptions } from '@angular-devkit/build-angular';
4
+ import { StylePreprocessorOptions } from '@angular-devkit/build-angular';
5
+ import { StyleElement } from '@angular-devkit/build-angular/src/builders/browser/schema';
5
6
  export type StorybookBuilderOptions = JsonObject & {
6
7
  browserTarget?: string | null;
7
8
  tsConfig?: string;
9
+ docs: boolean;
8
10
  compodoc: boolean;
9
11
  compodocArgs: string[];
10
- styles?: ExtraEntryPoint[];
12
+ styles?: StyleElement[];
11
13
  stylePreprocessorOptions?: StylePreprocessorOptions;
12
- } & Pick<CLIOptions, 'outputDir' | 'configDir' | 'loglevel' | 'quiet' | 'docs' | 'webpackStatsJson'>;
14
+ } & Pick<CLIOptions, 'outputDir' | 'configDir' | 'loglevel' | 'quiet' | 'webpackStatsJson' | 'disableTelemetry'>;
13
15
  export type StorybookBuilderOutput = JsonObject & BuilderOutput & {};
14
16
  declare const _default: import("@angular-devkit/architect/src/internal").Builder<any>;
15
17
  export default _default;
@@ -16,14 +16,15 @@ function commandBuilder(options, context) {
16
16
  : (0, rxjs_1.of)({});
17
17
  return runCompodoc$.pipe((0, operators_1.mapTo)({ tsConfig }));
18
18
  }), (0, operators_1.map)(({ tsConfig }) => {
19
- const { browserTarget, stylePreprocessorOptions, styles, configDir, docs, loglevel, outputDir, quiet, webpackStatsJson, } = options;
19
+ const { browserTarget, stylePreprocessorOptions, styles, configDir, docs, loglevel, outputDir, quiet, webpackStatsJson, disableTelemetry, } = options;
20
20
  const standaloneOptions = {
21
21
  packageJson: (0, read_pkg_up_1.sync)({ cwd: __dirname }).packageJson,
22
22
  configDir,
23
- docs,
23
+ ...(docs ? { docs } : {}),
24
24
  loglevel,
25
25
  outputDir,
26
26
  quiet,
27
+ disableTelemetry,
27
28
  angularBrowserTarget: browserTarget,
28
29
  angularBuilderContext: context,
29
30
  angularBuilderOptions: {
@@ -52,5 +53,8 @@ async function setup(options, context) {
52
53
  };
53
54
  }
54
55
  function runInstance(options) {
55
- return (0, rxjs_1.from)((0, core_server_1.buildStaticStandalone)(options)).pipe((0, operators_1.catchError)((error) => (0, rxjs_1.throwError)((0, build_standalone_errors_handler_1.buildStandaloneErrorHandler)(error))));
56
+ return (0, rxjs_1.from)((0, core_server_1.withTelemetry)('build', {
57
+ cliOptions: options,
58
+ presetOptions: { ...options, corePresets: [], overridePresets: [] },
59
+ }, () => (0, core_server_1.buildStaticStandalone)(options))).pipe((0, operators_1.catchError)((error) => (0, rxjs_1.throwError)((0, build_standalone_errors_handler_1.buildStandaloneErrorHandler)(error))));
56
60
  }
@@ -34,7 +34,7 @@
34
34
  "description": "Suppress verbose build output.",
35
35
  "default": false
36
36
  },
37
- "docsMode": {
37
+ "docs": {
38
38
  "type": "boolean",
39
39
  "description": "Starts Storybook in documentation mode. Learn more about it : https://storybook.js.org/docs/react/writing-docs/build-documentation#preview-storybooks-documentation.",
40
40
  "default": false
@@ -47,13 +47,19 @@
47
47
  "compodocArgs": {
48
48
  "type": "array",
49
49
  "description": "Compodoc options : https://compodoc.app/guides/options.html. Options `-p` with tsconfig path and `-d` with workspace root is always given.",
50
- "default": ["-e", "json"],
50
+ "default": [
51
+ "-e",
52
+ "json"
53
+ ],
51
54
  "items": {
52
55
  "type": "string"
53
56
  }
54
57
  },
55
58
  "webpackStatsJson": {
56
- "type": "boolean",
59
+ "type": [
60
+ "boolean",
61
+ "string"
62
+ ],
57
63
  "description": "Write Webpack Stats JSON to disk",
58
64
  "default": false
59
65
  },
@@ -61,7 +67,7 @@
61
67
  "type": "array",
62
68
  "description": "Global styles to be included in the build.",
63
69
  "items": {
64
- "$ref": "#/definitions/extraEntryPoint"
70
+ "$ref": "#/definitions/styleElement"
65
71
  },
66
72
  "default": ""
67
73
  },
@@ -83,7 +89,7 @@
83
89
  },
84
90
  "additionalProperties": false,
85
91
  "definitions": {
86
- "extraEntryPoint": {
92
+ "styleElement": {
87
93
  "oneOf": [
88
94
  {
89
95
  "type": "object",
@@ -104,7 +110,9 @@
104
110
  }
105
111
  },
106
112
  "additionalProperties": false,
107
- "required": ["input"]
113
+ "required": [
114
+ "input"
115
+ ]
108
116
  },
109
117
  {
110
118
  "type": "string",
@@ -1,15 +1,17 @@
1
1
  import { BuilderOutput } from '@angular-devkit/architect';
2
2
  import { JsonObject } from '@angular-devkit/core';
3
- import { ExtraEntryPoint, StylePreprocessorOptions } from '@angular-devkit/build-angular';
3
+ import { StylePreprocessorOptions } from '@angular-devkit/build-angular';
4
4
  import { CLIOptions } from '@storybook/types';
5
+ import { StyleElement } from '@angular-devkit/build-angular/src/builders/browser/schema';
5
6
  export type StorybookBuilderOptions = JsonObject & {
6
7
  browserTarget?: string | null;
7
8
  tsConfig?: string;
9
+ docs: boolean;
8
10
  compodoc: boolean;
9
11
  compodocArgs: string[];
10
- styles?: ExtraEntryPoint[];
12
+ styles?: StyleElement[];
11
13
  stylePreprocessorOptions?: StylePreprocessorOptions;
12
- } & Pick<CLIOptions, 'port' | 'host' | 'configDir' | 'https' | 'sslCa' | 'sslCert' | 'sslKey' | 'smokeTest' | 'ci' | 'quiet' | 'docs'>;
14
+ } & Pick<CLIOptions, 'port' | 'host' | 'configDir' | 'https' | 'sslCa' | 'sslCert' | 'sslKey' | 'smokeTest' | 'ci' | 'quiet' | 'disableTelemetry'>;
13
15
  export type StorybookBuilderOutput = JsonObject & BuilderOutput & {};
14
16
  declare const _default: import("@angular-devkit/architect/src/internal").Builder<any>;
15
17
  export default _default;
@@ -16,12 +16,12 @@ function commandBuilder(options, context) {
16
16
  : (0, rxjs_1.of)({});
17
17
  return runCompodoc$.pipe((0, operators_1.mapTo)({ tsConfig }));
18
18
  }), (0, operators_1.map)(({ tsConfig }) => {
19
- const { browserTarget, stylePreprocessorOptions, styles, ci, configDir, docs, host, https, port, quiet, smokeTest, sslCa, sslCert, sslKey, } = options;
19
+ const { browserTarget, stylePreprocessorOptions, styles, ci, configDir, docs, host, https, port, quiet, smokeTest, sslCa, sslCert, sslKey, disableTelemetry, } = options;
20
20
  const standaloneOptions = {
21
21
  packageJson: (0, read_pkg_up_1.sync)({ cwd: __dirname }).packageJson,
22
22
  ci,
23
23
  configDir,
24
- docs,
24
+ ...(docs ? { docs } : {}),
25
25
  host,
26
26
  https,
27
27
  port,
@@ -30,6 +30,7 @@ function commandBuilder(options, context) {
30
30
  sslCa,
31
31
  sslCert,
32
32
  sslKey,
33
+ disableTelemetry,
33
34
  angularBrowserTarget: browserTarget,
34
35
  angularBuilderContext: context,
35
36
  angularBuilderOptions: {
@@ -39,8 +40,8 @@ function commandBuilder(options, context) {
39
40
  tsConfig,
40
41
  };
41
42
  return standaloneOptions;
42
- }), (0, operators_1.switchMap)((standaloneOptions) => runInstance(standaloneOptions)), (0, operators_1.map)(() => {
43
- return { success: true };
43
+ }), (0, operators_1.switchMap)((standaloneOptions) => runInstance(standaloneOptions)), (0, operators_1.map)((port) => {
44
+ return { success: true, info: { port } };
44
45
  }));
45
46
  }
46
47
  async function setup(options, context) {
@@ -59,6 +60,9 @@ async function setup(options, context) {
59
60
  function runInstance(options) {
60
61
  return new rxjs_1.Observable((observer) => {
61
62
  // This Observable intentionally never complete, leaving the process running ;)
62
- (0, core_server_1.buildDevStandalone)(options).then(() => observer.next(), (error) => observer.error((0, build_standalone_errors_handler_1.buildStandaloneErrorHandler)(error)));
63
+ (0, core_server_1.withTelemetry)('dev', {
64
+ cliOptions: options,
65
+ presetOptions: { ...options, corePresets: [], overridePresets: [] },
66
+ }, () => (0, core_server_1.buildDevStandalone)(options).then(({ port }) => observer.next(port), (error) => observer.error((0, build_standalone_errors_handler_1.buildStandaloneErrorHandler)(error))));
63
67
  });
64
68
  }
@@ -61,7 +61,7 @@
61
61
  "description": "Suppress verbose build output.",
62
62
  "default": false
63
63
  },
64
- "docsMode": {
64
+ "docs": {
65
65
  "type": "boolean",
66
66
  "description": "Starts Storybook in documentation mode. Learn more about it : https://storybook.js.org/docs/react/writing-docs/build-documentation#preview-storybooks-documentation.",
67
67
  "default": false
@@ -74,7 +74,10 @@
74
74
  "compodocArgs": {
75
75
  "type": "array",
76
76
  "description": "Compodoc options : https://compodoc.app/guides/options.html. Options `-p` with tsconfig path and `-d` with workspace root is always given.",
77
- "default": ["-e", "json"],
77
+ "default": [
78
+ "-e",
79
+ "json"
80
+ ],
78
81
  "items": {
79
82
  "type": "string"
80
83
  }
@@ -83,7 +86,7 @@
83
86
  "type": "array",
84
87
  "description": "Global styles to be included in the build.",
85
88
  "items": {
86
- "$ref": "#/definitions/extraEntryPoint"
89
+ "$ref": "#/definitions/styleElement"
87
90
  },
88
91
  "default": ""
89
92
  },
@@ -105,7 +108,7 @@
105
108
  },
106
109
  "additionalProperties": false,
107
110
  "definitions": {
108
- "extraEntryPoint": {
111
+ "styleElement": {
109
112
  "oneOf": [
110
113
  {
111
114
  "type": "object",
@@ -126,7 +129,9 @@
126
129
  }
127
130
  },
128
131
  "additionalProperties": false,
129
- "required": ["input"]
132
+ "required": [
133
+ "input"
134
+ ]
130
135
  },
131
136
  {
132
137
  "type": "string",
@@ -24,10 +24,11 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.runCompodoc = void 0;
27
- const child_process_1 = require("child_process");
28
27
  const rxjs_1 = require("rxjs");
29
28
  const path = __importStar(require("path"));
29
+ const cli_1 = require("@storybook/cli");
30
30
  const hasTsConfigArg = (args) => args.indexOf('-p') !== -1;
31
+ const hasOutputArg = (args) => args.indexOf('-d') !== -1 || args.indexOf('--output') !== -1;
31
32
  // path.relative is necessary to workaround a compodoc issue with
32
33
  // absolute paths on windows machines
33
34
  const toRelativePath = (pathToTsConfig) => {
@@ -37,37 +38,20 @@ const runCompodoc = ({ compodocArgs, tsconfig }, context) => {
37
38
  return new rxjs_1.Observable((observer) => {
38
39
  const tsConfigPath = toRelativePath(tsconfig);
39
40
  const finalCompodocArgs = [
40
- 'compodoc',
41
- // Default options
42
41
  ...(hasTsConfigArg(compodocArgs) ? [] : ['-p', tsConfigPath]),
43
- '-d',
44
- `${context.workspaceRoot}`,
42
+ ...(hasOutputArg(compodocArgs) ? [] : ['-d', `${context.workspaceRoot || '.'}`]),
45
43
  ...compodocArgs,
46
44
  ];
45
+ const packageManager = cli_1.JsPackageManagerFactory.getPackageManager();
47
46
  try {
48
- context.logger.info(finalCompodocArgs.join(' '));
49
- const child = (0, child_process_1.spawn)('npx', finalCompodocArgs, {
50
- cwd: context.workspaceRoot,
51
- shell: true,
52
- });
53
- child.stdout.on('data', (data) => {
54
- context.logger.info(data.toString());
55
- });
56
- child.stderr.on('data', (data) => {
57
- context.logger.error(data.toString());
58
- });
59
- child.on('close', (code) => {
60
- if (code === 0) {
61
- observer.next();
62
- observer.complete();
63
- }
64
- else {
65
- observer.error();
66
- }
67
- });
47
+ const stdout = packageManager.runPackageCommand('compodoc', finalCompodocArgs, context.workspaceRoot);
48
+ context.logger.info(stdout);
49
+ observer.next();
50
+ observer.complete();
68
51
  }
69
- catch (error) {
70
- observer.error(error);
52
+ catch (e) {
53
+ context.logger.error(e);
54
+ observer.error();
71
55
  }
72
56
  });
73
57
  };
@@ -56,4 +56,46 @@ describe('runCompodoc', () => {
56
56
  shell: true,
57
57
  });
58
58
  });
59
+ it('should run compodoc with default output folder.', async () => {
60
+ runCompodoc({
61
+ compodocArgs: [],
62
+ tsconfig: 'path/to/tsconfig.json',
63
+ }, {
64
+ workspaceRoot: 'path/to/project',
65
+ logger: builderContextLoggerMock,
66
+ })
67
+ .pipe((0, operators_1.take)(1))
68
+ .subscribe();
69
+ expect(cpSpawnMock.spawn).toHaveBeenCalledWith('npx', ['compodoc', '-p', 'path/to/tsconfig.json', '-d', 'path/to/project'], {
70
+ cwd: 'path/to/project',
71
+ });
72
+ });
73
+ it('should run with custom output folder specified with --output compodocArgs', async () => {
74
+ runCompodoc({
75
+ compodocArgs: ['--output', 'path/to/customFolder'],
76
+ tsconfig: 'path/to/tsconfig.json',
77
+ }, {
78
+ workspaceRoot: 'path/to/project',
79
+ logger: builderContextLoggerMock,
80
+ })
81
+ .pipe((0, operators_1.take)(1))
82
+ .subscribe();
83
+ expect(cpSpawnMock.spawn).toHaveBeenCalledWith('npx', ['compodoc', '-p', 'path/to/tsconfig.json', '--output', 'path/to/customFolder'], {
84
+ cwd: 'path/to/project',
85
+ });
86
+ });
87
+ it('should run with custom output folder specified with -d compodocArgs', async () => {
88
+ runCompodoc({
89
+ compodocArgs: ['-d', 'path/to/customFolder'],
90
+ tsconfig: 'path/to/tsconfig.json',
91
+ }, {
92
+ workspaceRoot: 'path/to/project',
93
+ logger: builderContextLoggerMock,
94
+ })
95
+ .pipe((0, operators_1.take)(1))
96
+ .subscribe();
97
+ expect(cpSpawnMock.spawn).toHaveBeenCalledWith('npx', ['compodoc', '-p', 'path/to/tsconfig.json', '-d', 'path/to/customFolder'], {
98
+ cwd: 'path/to/project',
99
+ });
100
+ });
59
101
  });
@@ -1,6 +1,6 @@
1
1
  import { BuilderContext } from '@angular-devkit/architect';
2
2
  import { LoadOptions, CLIOptions, BuilderOptions } from '@storybook/types';
3
- export type StandaloneOptions = Partial<CLIOptions & LoadOptions & BuilderOptions & {
3
+ export type StandaloneOptions = CLIOptions & LoadOptions & BuilderOptions & {
4
4
  mode?: 'static' | 'dev';
5
5
  angularBrowserTarget?: string | null;
6
6
  angularBuilderOptions?: Record<string, any> & {
@@ -9,4 +9,4 @@ export type StandaloneOptions = Partial<CLIOptions & LoadOptions & BuilderOption
9
9
  };
10
10
  angularBuilderContext?: BuilderContext | null;
11
11
  tsConfig?: string;
12
- }>;
12
+ };
@@ -1,5 +1,5 @@
1
1
  import { Subject } from 'rxjs';
2
- import { ICollection, StoryFnAngularReturnType, Parameters } from '../types';
2
+ import { ICollection, Parameters, StoryFnAngularReturnType } from '../types';
3
3
  type StoryRenderInfo = {
4
4
  storyFnAngular: StoryFnAngularReturnType;
5
5
  moduleMetadataSnapshot: string;
@@ -9,7 +9,7 @@ export declare abstract class AbstractRenderer {
9
9
  /**
10
10
  * Wait and destroy the platform
11
11
  */
12
- static resetPlatformBrowserDynamic(): Promise<void>;
12
+ static resetApplications(): void;
13
13
  /**
14
14
  * Reset compiled components because we often want to compile the same component with
15
15
  * more than one NgModule.
@@ -49,7 +49,7 @@ export declare abstract class AbstractRenderer {
49
49
  * @protected
50
50
  * @memberof AbstractRenderer
51
51
  */
52
- protected generateTargetSelectorFromStoryId(): string;
52
+ protected generateTargetSelectorFromStoryId(id: string): string;
53
53
  protected initAngularRootElement(targetDOMNode: HTMLElement, targetSelector: string): void;
54
54
  private fullRendererRequired;
55
55
  }
@@ -26,36 +26,24 @@ var _a;
26
26
  Object.defineProperty(exports, "__esModule", { value: true });
27
27
  exports.AbstractRenderer = void 0;
28
28
  const core_1 = require("@angular/core");
29
- const platform_browser_dynamic_1 = require("@angular/platform-browser-dynamic");
29
+ const platform_browser_1 = require("@angular/platform-browser");
30
30
  const rxjs_1 = require("rxjs");
31
31
  const telejson_1 = require("telejson");
32
32
  const StorybookModule_1 = require("./StorybookModule");
33
- // platform must be init only if render is called at least once
34
- let platformRef;
35
- function getPlatform(newPlatform) {
36
- if (!platformRef || newPlatform) {
37
- platformRef = (0, platform_browser_dynamic_1.platformBrowserDynamic)();
38
- }
39
- return platformRef;
40
- }
33
+ const StorybookProvider_1 = require("./StorybookProvider");
34
+ const StorybookWrapperComponent_1 = require("./StorybookWrapperComponent");
35
+ const PropertyExtractor_1 = require("./utils/PropertyExtractor");
36
+ const applicationRefs = new Set();
41
37
  class AbstractRenderer {
42
38
  /**
43
39
  * Wait and destroy the platform
44
40
  */
45
- static resetPlatformBrowserDynamic() {
46
- return new Promise((resolve) => {
47
- if (platformRef && !platformRef.destroyed) {
48
- platformRef.onDestroy(async () => {
49
- resolve();
50
- });
51
- // Destroys the current Angular platform and all Angular applications on the page.
52
- // So call each angular ngOnDestroy and avoid memory leaks
53
- platformRef.destroy();
54
- return;
41
+ static resetApplications() {
42
+ StorybookWrapperComponent_1.componentNgModules.clear();
43
+ applicationRefs.forEach((appRef) => {
44
+ if (!appRef.destroyed) {
45
+ appRef.destroy();
55
46
  }
56
- resolve();
57
- }).then(() => {
58
- getPlatform(true);
59
47
  });
60
48
  }
61
49
  constructor(storyId) {
@@ -82,12 +70,13 @@ class AbstractRenderer {
82
70
  * @param parameters {Parameters}
83
71
  */
84
72
  async render({ storyFnAngular, forced, parameters, component, targetDOMNode, }) {
85
- const targetSelector = `${this.generateTargetSelectorFromStoryId()}`;
73
+ const targetSelector = this.generateTargetSelectorFromStoryId(targetDOMNode.id);
86
74
  const newStoryProps$ = new rxjs_1.BehaviorSubject(storyFnAngular.props);
87
- const moduleMetadata = (0, StorybookModule_1.getStorybookModuleMetadata)({ storyFnAngular, component, targetSelector }, newStoryProps$);
88
75
  if (!this.fullRendererRequired({
89
76
  storyFnAngular,
90
- moduleMetadata,
77
+ moduleMetadata: {
78
+ ...storyFnAngular.moduleMetadata,
79
+ },
91
80
  forced,
92
81
  })) {
93
82
  this.storyProps$.next(storyFnAngular.props);
@@ -100,7 +89,20 @@ class AbstractRenderer {
100
89
  }
101
90
  this.storyProps$ = newStoryProps$;
102
91
  this.initAngularRootElement(targetDOMNode, targetSelector);
103
- await getPlatform().bootstrapModule((0, StorybookModule_1.createStorybookModule)(moduleMetadata), parameters.bootstrapModuleOptions ?? undefined);
92
+ const analyzedMetadata = new PropertyExtractor_1.PropertyExtractor(storyFnAngular.moduleMetadata, component);
93
+ const providers = [
94
+ // Providers for BrowserAnimations & NoopAnimationsModule
95
+ analyzedMetadata.singletons,
96
+ (0, core_1.importProvidersFrom)(...analyzedMetadata.imports.filter((imported) => {
97
+ const { isStandalone } = PropertyExtractor_1.PropertyExtractor.analyzeDecorators(imported);
98
+ return !isStandalone;
99
+ })),
100
+ analyzedMetadata.providers,
101
+ (0, StorybookProvider_1.storyPropsProvider)(newStoryProps$),
102
+ ].filter(Boolean);
103
+ const application = (0, StorybookModule_1.getApplication)({ storyFnAngular, component, targetSelector });
104
+ const applicationRef = await (0, platform_browser_1.bootstrapApplication)(application, { providers });
105
+ applicationRefs.add(applicationRef);
104
106
  await this.afterFullRender();
105
107
  }
106
108
  /**
@@ -115,12 +117,10 @@ class AbstractRenderer {
115
117
  * @protected
116
118
  * @memberof AbstractRenderer
117
119
  */
118
- generateTargetSelectorFromStoryId() {
120
+ generateTargetSelectorFromStoryId(id) {
119
121
  const invalidHtmlTag = /[^A-Za-z0-9-]/g;
120
- const storyIdIsInvalidHtmlTagName = invalidHtmlTag.test(this.storyId);
121
- return storyIdIsInvalidHtmlTagName
122
- ? `sb-${this.storyId.replace(invalidHtmlTag, '')}-component`
123
- : this.storyId;
122
+ const storyIdIsInvalidHtmlTagName = invalidHtmlTag.test(id);
123
+ return storyIdIsInvalidHtmlTagName ? `sb-${id.replace(invalidHtmlTag, '')}-component` : id;
124
124
  }
125
125
  initAngularRootElement(targetDOMNode, targetSelector) {
126
126
  // Adds DOM element that angular will use as bootstrap component
@@ -7,7 +7,7 @@ class CanvasRenderer extends AbstractRenderer_1.AbstractRenderer {
7
7
  await super.render(options);
8
8
  }
9
9
  async beforeFullRender() {
10
- await CanvasRenderer.resetPlatformBrowserDynamic();
10
+ CanvasRenderer.resetApplications();
11
11
  }
12
12
  async afterFullRender() {
13
13
  await AbstractRenderer_1.AbstractRenderer.resetCompiledComponents();
@@ -18,7 +18,7 @@ class DocsRenderer extends AbstractRenderer_1.AbstractRenderer {
18
18
  *
19
19
  */
20
20
  channel.once(core_events_1.STORY_CHANGED, async () => {
21
- await DocsRenderer.resetPlatformBrowserDynamic();
21
+ await DocsRenderer.resetApplications();
22
22
  });
23
23
  /**
24
24
  * Destroy and recreate the PlatformBrowserDynamic of angular
@@ -26,11 +26,13 @@ class DocsRenderer extends AbstractRenderer_1.AbstractRenderer {
26
26
  * for previous component
27
27
  */
28
28
  channel.once(core_events_1.DOCS_RENDERED, async () => {
29
- await DocsRenderer.resetPlatformBrowserDynamic();
29
+ await DocsRenderer.resetApplications();
30
30
  });
31
31
  await super.render({ ...options, forced: false });
32
32
  }
33
- async beforeFullRender() { }
33
+ async beforeFullRender() {
34
+ DocsRenderer.resetApplications();
35
+ }
34
36
  async afterFullRender() {
35
37
  await AbstractRenderer_1.AbstractRenderer.resetCompiledComponents();
36
38
  }
@@ -9,6 +9,7 @@ class RendererFactory {
9
9
  this.rendererMap = new Map();
10
10
  }
11
11
  async getRendererInstance(storyId, targetDOMNode) {
12
+ const targetId = targetDOMNode.id;
12
13
  // do nothing if the target node is null
13
14
  // fix a problem when the docs asks 2 times the same component at the same time
14
15
  // the 1st targetDOMNode of the 1st requested rendering becomes null 🤷‍♂️
@@ -18,15 +19,15 @@ class RendererFactory {
18
19
  const renderType = (0, exports.getRenderType)(targetDOMNode);
19
20
  // keep only instances of the same type
20
21
  if (this.lastRenderType && this.lastRenderType !== renderType) {
21
- await AbstractRenderer_1.AbstractRenderer.resetPlatformBrowserDynamic();
22
+ await AbstractRenderer_1.AbstractRenderer.resetApplications();
22
23
  clearRootHTMLElement(renderType);
23
24
  this.rendererMap.clear();
24
25
  }
25
- if (!this.rendererMap.has(storyId)) {
26
- this.rendererMap.set(storyId, this.buildRenderer(storyId, renderType));
26
+ if (!this.rendererMap.has(targetId)) {
27
+ this.rendererMap.set(targetId, this.buildRenderer(storyId, renderType));
27
28
  }
28
29
  this.lastRenderType = renderType;
29
- return this.rendererMap.get(storyId);
30
+ return this.rendererMap.get(targetId);
30
31
  }
31
32
  buildRenderer(storyId, renderType) {
32
33
  if (renderType === 'docs') {
@@ -1,9 +1,6 @@
1
- import { Type, NgModule } from '@angular/core';
2
- import { Subject } from 'rxjs';
3
- import { ICollection, StoryFnAngularReturnType } from '../types';
4
- export declare const getStorybookModuleMetadata: ({ storyFnAngular, component, targetSelector, }: {
1
+ import { StoryFnAngularReturnType } from '../types';
2
+ export declare const getApplication: ({ storyFnAngular, component, targetSelector, }: {
5
3
  storyFnAngular: StoryFnAngularReturnType;
6
4
  component?: any;
7
5
  targetSelector: string;
8
- }, storyProps$: Subject<ICollection>) => NgModule;
9
- export declare const createStorybookModule: (ngModule: NgModule) => Type<unknown>;
6
+ }) => import("@angular/core").Type<any>;