@storybook/angular 7.0.0-beta.9 → 7.0.0-rc.0
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.
- package/README.md +214 -0
- package/dist/builders/build-storybook/index.d.ts +5 -3
- package/dist/builders/build-storybook/index.js +9 -4
- package/dist/builders/build-storybook/schema.json +14 -6
- package/dist/builders/start-storybook/index.d.ts +5 -3
- package/dist/builders/start-storybook/index.js +15 -6
- package/dist/builders/start-storybook/schema.json +10 -5
- package/dist/builders/utils/error-handler.d.ts +2 -0
- package/dist/builders/utils/{build-standalone-errors-handler.js → error-handler.js} +6 -3
- package/dist/builders/utils/run-compodoc.js +11 -27
- package/dist/builders/utils/run-compodoc.spec.js +42 -0
- package/dist/builders/utils/standalone-options.d.ts +2 -2
- package/dist/client/angular-beta/AbstractRenderer.d.ts +3 -3
- package/dist/client/angular-beta/AbstractRenderer.js +31 -31
- package/dist/client/angular-beta/CanvasRenderer.js +1 -1
- package/dist/client/angular-beta/DocsRenderer.js +5 -3
- package/dist/client/angular-beta/RendererFactory.js +5 -4
- package/dist/client/angular-beta/StorybookModule.d.ts +3 -6
- package/dist/client/angular-beta/StorybookModule.js +4 -45
- package/dist/client/angular-beta/StorybookModule.test.js +51 -36
- package/dist/client/angular-beta/StorybookWrapperComponent.d.ts +3 -2
- package/dist/client/angular-beta/StorybookWrapperComponent.js +30 -2
- package/dist/client/angular-beta/__testfixtures__/test.module.d.ts +2 -0
- package/dist/client/angular-beta/__testfixtures__/test.module.js +20 -0
- package/dist/client/angular-beta/utils/NgComponentAnalyzer.js +1 -1
- package/dist/client/angular-beta/utils/NgComponentAnalyzer.test.js +43 -5
- package/dist/client/angular-beta/utils/NgModulesAnalyzer.d.ts +1 -1
- package/dist/client/angular-beta/utils/NgModulesAnalyzer.js +4 -4
- package/dist/client/angular-beta/utils/NgModulesAnalyzer.test.js +3 -3
- package/dist/client/angular-beta/utils/PropertyExtractor.d.ts +32 -0
- package/dist/client/angular-beta/utils/PropertyExtractor.js +136 -0
- package/dist/client/angular-beta/utils/PropertyExtractor.test.d.ts +1 -0
- package/dist/client/angular-beta/utils/PropertyExtractor.test.js +141 -0
- package/dist/client/config.d.ts +1 -1
- package/dist/client/config.js +1 -1
- package/dist/client/decorateStory.js +1 -1
- package/dist/client/docs/compodoc.js +5 -7
- package/dist/client/docs/config.js +1 -2
- package/dist/client/docs/sourceDecorator.js +2 -1
- package/dist/client/globals.d.ts +0 -8
- package/dist/client/globals.js +2 -29
- package/dist/client/public-api.js +3 -3
- package/dist/client/public-types.d.ts +2 -1
- package/dist/client/render.d.ts +1 -0
- package/dist/client/render.js +1 -5
- package/dist/client/types.d.ts +1 -2
- package/dist/index.mjs +13 -0
- package/dist/preset.js +3 -5
- package/dist/preset.mjs +27 -0
- package/dist/renderer.d.ts +2 -1
- package/dist/renderer.js +4 -2
- package/dist/renderer.mjs +5 -0
- package/dist/server/framework-preset-angular-cli.d.ts +2 -1
- package/dist/server/framework-preset-angular-cli.js +21 -92
- package/dist/server/preset-options.d.ts +3 -2
- package/dist/types.mjs +1 -0
- package/jest.config.js +19 -0
- package/package.json +46 -45
- package/template/cli/Button.stories.ts +1 -1
- package/template/cli/Header.stories.ts +2 -2
- package/template/cli/button.component.ts +2 -0
- package/template/components/index.js +2 -2
- package/template/stories/angular-mdx.stories.mdx +1 -1
- package/template/stories/argTypes/doc-button/doc-button.component.ts +1 -2
- package/template/stories/basics/component-without-selector/without-selector-ng-component-outlet.stories.ts +1 -1
- package/template/stories/basics/component-without-selector/without-selector-ng-factory-resolver.stories.ts +1 -1
- package/template/stories/basics/component-without-selector/without-selector.stories.ts +1 -1
- package/template/stories/basics/ng-module/import-module-chip.stories.ts +23 -0
- package/template/stories/basics/ng-module/import-module.stories.ts +2 -13
- package/template/stories/core/decorators/componentWrapperDecorator/decorators.stories.ts +0 -18
- package/template/stories/core/moduleMetadata/angular-src/open-close-component/open-close.component.css +13 -0
- package/template/stories/core/moduleMetadata/angular-src/open-close-component/open-close.component.html +7 -0
- package/template/stories/core/moduleMetadata/angular-src/open-close-component/open-close.component.ts +39 -0
- package/template/stories/core/moduleMetadata/with-browser-animations.stories.ts +30 -0
- package/template/stories/core/moduleMetadata/with-noop-browser-animations.stories.ts +27 -0
- package/template/stories/core/parameters/bootstrap-options.stories.ts +1 -5
- package/template/stories/others/app-initializer-use-factory/app-initializer-use-factory.stories.ts +34 -0
- package/dist/builders/utils/build-standalone-errors-handler.d.ts +0 -1
- package/dist/client/angular/helpers.d.ts +0 -8
- package/dist/client/angular/helpers.js +0 -150
- package/dist/server/angular-read-workspace.d.ts +0 -13
- package/dist/server/angular-read-workspace.js +0 -78
- package/dist/server/utils/normalize-asset-patterns.d.ts +0 -7
- package/dist/server/utils/normalize-asset-patterns.js +0 -64
- package/dist/server/utils/normalize-optimization.d.ts +0 -3
- package/dist/server/utils/normalize-optimization.js +0 -21
|
@@ -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
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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 =
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
22
|
+
await AbstractRenderer_1.AbstractRenderer.resetApplications();
|
|
22
23
|
clearRootHTMLElement(renderType);
|
|
23
24
|
this.rendererMap.clear();
|
|
24
25
|
}
|
|
25
|
-
if (!this.rendererMap.has(
|
|
26
|
-
this.rendererMap.set(
|
|
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(
|
|
30
|
+
return this.rendererMap.get(targetId);
|
|
30
31
|
}
|
|
31
32
|
buildRenderer(storyId, renderType) {
|
|
32
33
|
if (renderType === 'docs') {
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
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
|
-
}
|
|
9
|
-
export declare const createStorybookModule: (ngModule: NgModule) => Type<unknown>;
|
|
6
|
+
}) => import("@angular/core").Type<any>;
|
|
@@ -1,20 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.
|
|
10
|
-
const core_1 = require("@angular/core");
|
|
11
|
-
const platform_browser_1 = require("@angular/platform-browser");
|
|
12
|
-
const StorybookProvider_1 = require("./StorybookProvider");
|
|
13
|
-
const NgModulesAnalyzer_1 = require("./utils/NgModulesAnalyzer");
|
|
14
|
-
const NgComponentAnalyzer_1 = require("./utils/NgComponentAnalyzer");
|
|
3
|
+
exports.getApplication = void 0;
|
|
15
4
|
const StorybookWrapperComponent_1 = require("./StorybookWrapperComponent");
|
|
16
5
|
const ComputesTemplateFromComponent_1 = require("./ComputesTemplateFromComponent");
|
|
17
|
-
const
|
|
6
|
+
const getApplication = ({ storyFnAngular, component, targetSelector, }) => {
|
|
18
7
|
const { props, styles, moduleMetadata = {} } = storyFnAngular;
|
|
19
8
|
let { template } = storyFnAngular;
|
|
20
9
|
const hasTemplate = !hasNoTemplate(template);
|
|
@@ -24,39 +13,9 @@ const getStorybookModuleMetadata = ({ storyFnAngular, component, targetSelector,
|
|
|
24
13
|
/**
|
|
25
14
|
* Create a component that wraps generated template and gives it props
|
|
26
15
|
*/
|
|
27
|
-
|
|
28
|
-
const isStandalone = (0, NgComponentAnalyzer_1.isStandaloneComponent)(component);
|
|
29
|
-
// Look recursively (deep) if the component is not already declared by an import module
|
|
30
|
-
const requiresComponentDeclaration = (0, NgComponentAnalyzer_1.isDeclarable)(component) &&
|
|
31
|
-
!(0, NgModulesAnalyzer_1.isComponentAlreadyDeclaredInModules)(component, moduleMetadata.declarations, moduleMetadata.imports) &&
|
|
32
|
-
!isStandalone;
|
|
33
|
-
return {
|
|
34
|
-
declarations: [
|
|
35
|
-
...(requiresComponentDeclaration ? [component] : []),
|
|
36
|
-
ComponentToInject,
|
|
37
|
-
...(moduleMetadata.declarations ?? []),
|
|
38
|
-
],
|
|
39
|
-
imports: [
|
|
40
|
-
platform_browser_1.BrowserModule,
|
|
41
|
-
...(isStandalone ? [component] : []),
|
|
42
|
-
...(moduleMetadata.imports ?? []),
|
|
43
|
-
],
|
|
44
|
-
providers: [(0, StorybookProvider_1.storyPropsProvider)(storyProps$), ...(moduleMetadata.providers ?? [])],
|
|
45
|
-
entryComponents: [...(moduleMetadata.entryComponents ?? [])],
|
|
46
|
-
schemas: [...(moduleMetadata.schemas ?? [])],
|
|
47
|
-
bootstrap: [ComponentToInject],
|
|
48
|
-
};
|
|
49
|
-
};
|
|
50
|
-
exports.getStorybookModuleMetadata = getStorybookModuleMetadata;
|
|
51
|
-
const createStorybookModule = (ngModule) => {
|
|
52
|
-
let StorybookModule = class StorybookModule {
|
|
53
|
-
};
|
|
54
|
-
StorybookModule = __decorate([
|
|
55
|
-
(0, core_1.NgModule)(ngModule)
|
|
56
|
-
], StorybookModule);
|
|
57
|
-
return StorybookModule;
|
|
16
|
+
return (0, StorybookWrapperComponent_1.createStorybookWrapperComponent)(targetSelector, template, component, styles, moduleMetadata, props);
|
|
58
17
|
};
|
|
59
|
-
exports.
|
|
18
|
+
exports.getApplication = getApplication;
|
|
60
19
|
function hasNoTemplate(template) {
|
|
61
20
|
return template === null || template === undefined;
|
|
62
21
|
}
|
|
@@ -11,9 +11,9 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const core_1 = require("@angular/core");
|
|
13
13
|
const testing_1 = require("@angular/core/testing");
|
|
14
|
-
const platform_browser_1 = require("@angular/platform-browser");
|
|
15
14
|
const rxjs_1 = require("rxjs");
|
|
16
15
|
const StorybookModule_1 = require("./StorybookModule");
|
|
16
|
+
const StorybookProvider_1 = require("./StorybookProvider");
|
|
17
17
|
describe('StorybookModule', () => {
|
|
18
18
|
describe('getStorybookModuleMetadata', () => {
|
|
19
19
|
describe('with simple component', () => {
|
|
@@ -70,12 +70,15 @@ describe('StorybookModule', () => {
|
|
|
70
70
|
localProperty: 'localProperty',
|
|
71
71
|
localFunction: () => 'localFunction',
|
|
72
72
|
};
|
|
73
|
-
const
|
|
73
|
+
const application = (0, StorybookModule_1.getApplication)({
|
|
74
74
|
storyFnAngular: { props },
|
|
75
75
|
component: FooComponent,
|
|
76
76
|
targetSelector: 'my-selector',
|
|
77
|
-
}
|
|
78
|
-
const { fixture } = await configureTestingModule(
|
|
77
|
+
});
|
|
78
|
+
const { fixture } = await configureTestingModule({
|
|
79
|
+
imports: [application],
|
|
80
|
+
providers: [(0, StorybookProvider_1.storyPropsProvider)(new rxjs_1.BehaviorSubject(props))],
|
|
81
|
+
});
|
|
79
82
|
fixture.detectChanges();
|
|
80
83
|
expect(fixture.nativeElement.querySelector('p#input').innerHTML).toEqual(props.input);
|
|
81
84
|
expect(fixture.nativeElement.querySelector('p#inputBindingPropertyName').innerHTML).toEqual(props.inputBindingPropertyName);
|
|
@@ -93,12 +96,15 @@ describe('StorybookModule', () => {
|
|
|
93
96
|
expectedOutputBindingValue = value;
|
|
94
97
|
},
|
|
95
98
|
};
|
|
96
|
-
const
|
|
99
|
+
const application = (0, StorybookModule_1.getApplication)({
|
|
97
100
|
storyFnAngular: { props },
|
|
98
101
|
component: FooComponent,
|
|
99
102
|
targetSelector: 'my-selector',
|
|
100
|
-
}
|
|
101
|
-
const { fixture } = await configureTestingModule(
|
|
103
|
+
});
|
|
104
|
+
const { fixture } = await configureTestingModule({
|
|
105
|
+
imports: [application],
|
|
106
|
+
providers: [(0, StorybookProvider_1.storyPropsProvider)(new rxjs_1.BehaviorSubject(props))],
|
|
107
|
+
});
|
|
102
108
|
fixture.detectChanges();
|
|
103
109
|
fixture.nativeElement.querySelector('p#output').click();
|
|
104
110
|
fixture.nativeElement.querySelector('p#outputBindingPropertyName').click();
|
|
@@ -111,12 +117,15 @@ describe('StorybookModule', () => {
|
|
|
111
117
|
inputBindingPropertyName: '',
|
|
112
118
|
};
|
|
113
119
|
const storyProps$ = new rxjs_1.BehaviorSubject(initialProps);
|
|
114
|
-
const
|
|
120
|
+
const application = (0, StorybookModule_1.getApplication)({
|
|
115
121
|
storyFnAngular: { props: initialProps },
|
|
116
122
|
component: FooComponent,
|
|
117
123
|
targetSelector: 'my-selector',
|
|
118
|
-
}
|
|
119
|
-
const { fixture } = await configureTestingModule(
|
|
124
|
+
});
|
|
125
|
+
const { fixture } = await configureTestingModule({
|
|
126
|
+
imports: [application],
|
|
127
|
+
providers: [(0, StorybookProvider_1.storyPropsProvider)(storyProps$)],
|
|
128
|
+
});
|
|
120
129
|
fixture.detectChanges();
|
|
121
130
|
expect(fixture.nativeElement.querySelector('p#input').innerHTML).toEqual(initialProps.input);
|
|
122
131
|
expect(fixture.nativeElement.querySelector('p#inputBindingPropertyName').innerHTML).toEqual('');
|
|
@@ -146,12 +155,15 @@ describe('StorybookModule', () => {
|
|
|
146
155
|
},
|
|
147
156
|
};
|
|
148
157
|
const storyProps$ = new rxjs_1.BehaviorSubject(initialProps);
|
|
149
|
-
const
|
|
158
|
+
const application = (0, StorybookModule_1.getApplication)({
|
|
150
159
|
storyFnAngular: { props: initialProps },
|
|
151
160
|
component: FooComponent,
|
|
152
161
|
targetSelector: 'my-selector',
|
|
153
|
-
}
|
|
154
|
-
const { fixture } = await configureTestingModule(
|
|
162
|
+
});
|
|
163
|
+
const { fixture } = await configureTestingModule({
|
|
164
|
+
imports: [application],
|
|
165
|
+
providers: [(0, StorybookProvider_1.storyPropsProvider)(storyProps$)],
|
|
166
|
+
});
|
|
155
167
|
fixture.detectChanges();
|
|
156
168
|
const newProps = {
|
|
157
169
|
input: 'new input',
|
|
@@ -176,15 +188,18 @@ describe('StorybookModule', () => {
|
|
|
176
188
|
input: 'input',
|
|
177
189
|
};
|
|
178
190
|
const storyProps$ = new rxjs_1.BehaviorSubject(initialProps);
|
|
179
|
-
const
|
|
191
|
+
const application = (0, StorybookModule_1.getApplication)({
|
|
180
192
|
storyFnAngular: {
|
|
181
193
|
props: initialProps,
|
|
182
194
|
template: '<p [style.color]="color"><foo [input]="input"></foo></p>',
|
|
183
195
|
},
|
|
184
196
|
component: FooComponent,
|
|
185
197
|
targetSelector: 'my-selector',
|
|
186
|
-
}
|
|
187
|
-
const { fixture } = await configureTestingModule(
|
|
198
|
+
});
|
|
199
|
+
const { fixture } = await configureTestingModule({
|
|
200
|
+
imports: [application],
|
|
201
|
+
providers: [(0, StorybookProvider_1.storyPropsProvider)(storyProps$)],
|
|
202
|
+
});
|
|
188
203
|
fixture.detectChanges();
|
|
189
204
|
expect(fixture.nativeElement.querySelector('p').style.color).toEqual('red');
|
|
190
205
|
expect(fixture.nativeElement.querySelector('p#input').innerHTML).toEqual(initialProps.input);
|
|
@@ -202,12 +217,15 @@ describe('StorybookModule', () => {
|
|
|
202
217
|
setter: 'init',
|
|
203
218
|
};
|
|
204
219
|
const storyProps$ = new rxjs_1.BehaviorSubject(initialProps);
|
|
205
|
-
const
|
|
220
|
+
const application = (0, StorybookModule_1.getApplication)({
|
|
206
221
|
storyFnAngular: { props: initialProps },
|
|
207
222
|
component: FooComponent,
|
|
208
223
|
targetSelector: 'my-selector',
|
|
209
|
-
}
|
|
210
|
-
const { fixture } = await configureTestingModule(
|
|
224
|
+
});
|
|
225
|
+
const { fixture } = await configureTestingModule({
|
|
226
|
+
imports: [application],
|
|
227
|
+
providers: [(0, StorybookProvider_1.storyPropsProvider)(storyProps$)],
|
|
228
|
+
});
|
|
211
229
|
fixture.detectChanges();
|
|
212
230
|
expect(fixture.nativeElement.querySelector('p#setterCallNb').innerHTML).toEqual('1');
|
|
213
231
|
const newProps = {
|
|
@@ -228,15 +246,18 @@ describe('StorybookModule', () => {
|
|
|
228
246
|
], WithoutSelectorComponent);
|
|
229
247
|
it('should display the component', async () => {
|
|
230
248
|
const props = {};
|
|
231
|
-
const
|
|
249
|
+
const application = (0, StorybookModule_1.getApplication)({
|
|
232
250
|
storyFnAngular: {
|
|
233
251
|
props,
|
|
234
252
|
moduleMetadata: { entryComponents: [WithoutSelectorComponent] },
|
|
235
253
|
},
|
|
236
254
|
component: WithoutSelectorComponent,
|
|
237
255
|
targetSelector: 'my-selector',
|
|
238
|
-
}
|
|
239
|
-
const { fixture } = await configureTestingModule(
|
|
256
|
+
});
|
|
257
|
+
const { fixture } = await configureTestingModule({
|
|
258
|
+
imports: [application],
|
|
259
|
+
providers: [(0, StorybookProvider_1.storyPropsProvider)(new rxjs_1.BehaviorSubject(props))],
|
|
260
|
+
});
|
|
240
261
|
fixture.detectChanges();
|
|
241
262
|
expect(fixture.nativeElement.innerHTML).toContain('The content');
|
|
242
263
|
});
|
|
@@ -250,28 +271,22 @@ describe('StorybookModule', () => {
|
|
|
250
271
|
template: `Should not be displayed`,
|
|
251
272
|
})
|
|
252
273
|
], FooComponent);
|
|
253
|
-
const
|
|
274
|
+
const application = (0, StorybookModule_1.getApplication)({
|
|
254
275
|
storyFnAngular: { template: '' },
|
|
255
276
|
component: FooComponent,
|
|
256
277
|
targetSelector: 'my-selector',
|
|
257
|
-
}
|
|
258
|
-
const { fixture } = await configureTestingModule(
|
|
278
|
+
});
|
|
279
|
+
const { fixture } = await configureTestingModule({
|
|
280
|
+
imports: [application],
|
|
281
|
+
providers: [(0, StorybookProvider_1.storyPropsProvider)(new rxjs_1.BehaviorSubject({}))],
|
|
282
|
+
});
|
|
259
283
|
fixture.detectChanges();
|
|
260
284
|
expect(fixture.nativeElement.innerHTML).toEqual('');
|
|
261
285
|
});
|
|
262
286
|
});
|
|
263
287
|
async function configureTestingModule(ngModule) {
|
|
264
|
-
await testing_1.TestBed.configureTestingModule(
|
|
265
|
-
|
|
266
|
-
providers: ngModule.providers,
|
|
267
|
-
})
|
|
268
|
-
.overrideModule(platform_browser_1.BrowserModule, {
|
|
269
|
-
set: {
|
|
270
|
-
entryComponents: [...ngModule.entryComponents],
|
|
271
|
-
},
|
|
272
|
-
})
|
|
273
|
-
.compileComponents();
|
|
274
|
-
const fixture = testing_1.TestBed.createComponent(ngModule.bootstrap[0]);
|
|
288
|
+
await testing_1.TestBed.configureTestingModule(ngModule).compileComponents();
|
|
289
|
+
const fixture = testing_1.TestBed.createComponent(ngModule.imports[0]);
|
|
275
290
|
return {
|
|
276
291
|
fixture,
|
|
277
292
|
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Type } from '@angular/core';
|
|
2
|
-
import { ICollection } from '../types';
|
|
2
|
+
import { ICollection, NgModuleMetadata } from '../types';
|
|
3
|
+
export declare const componentNgModules: Map<any, Type<any>>;
|
|
3
4
|
/**
|
|
4
5
|
* Wraps the story template into a component
|
|
5
6
|
*
|
|
6
7
|
* @param storyComponent
|
|
7
8
|
* @param initialProps
|
|
8
9
|
*/
|
|
9
|
-
export declare const createStorybookWrapperComponent: (selector: string, template: string, storyComponent: Type<unknown> | undefined, styles: string[], initialProps?: ICollection) => Type<any>;
|
|
10
|
+
export declare const createStorybookWrapperComponent: (selector: string, template: string, storyComponent: Type<unknown> | undefined, styles: string[], moduleMetadata: NgModuleMetadata, initialProps?: ICollection) => Type<any>;
|
|
@@ -12,12 +12,13 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
12
12
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.createStorybookWrapperComponent = void 0;
|
|
15
|
+
exports.createStorybookWrapperComponent = exports.componentNgModules = void 0;
|
|
16
16
|
const core_1 = require("@angular/core");
|
|
17
17
|
const rxjs_1 = require("rxjs");
|
|
18
18
|
const operators_1 = require("rxjs/operators");
|
|
19
19
|
const StorybookProvider_1 = require("./StorybookProvider");
|
|
20
20
|
const NgComponentAnalyzer_1 = require("./utils/NgComponentAnalyzer");
|
|
21
|
+
const PropertyExtractor_1 = require("./utils/PropertyExtractor");
|
|
21
22
|
const getNonInputsOutputsProps = (ngComponentInputsOutputs, props = {}) => {
|
|
22
23
|
const inputs = ngComponentInputsOutputs.inputs
|
|
23
24
|
.filter((i) => i.templateName in props)
|
|
@@ -27,16 +28,38 @@ const getNonInputsOutputsProps = (ngComponentInputsOutputs, props = {}) => {
|
|
|
27
28
|
.map((o) => o.templateName);
|
|
28
29
|
return Object.keys(props).filter((k) => ![...inputs, ...outputs].includes(k));
|
|
29
30
|
};
|
|
31
|
+
// component modules cache
|
|
32
|
+
exports.componentNgModules = new Map();
|
|
30
33
|
/**
|
|
31
34
|
* Wraps the story template into a component
|
|
32
35
|
*
|
|
33
36
|
* @param storyComponent
|
|
34
37
|
* @param initialProps
|
|
35
38
|
*/
|
|
36
|
-
const createStorybookWrapperComponent = (selector, template, storyComponent, styles, initialProps) => {
|
|
39
|
+
const createStorybookWrapperComponent = (selector, template, storyComponent, styles, moduleMetadata, initialProps) => {
|
|
37
40
|
// In ivy, a '' selector is not allowed, therefore we need to just set it to anything if
|
|
38
41
|
// storyComponent was not provided.
|
|
39
42
|
const viewChildSelector = storyComponent ?? '__storybook-noop';
|
|
43
|
+
const analyzedMetadata = new PropertyExtractor_1.PropertyExtractor(moduleMetadata, storyComponent);
|
|
44
|
+
const { imports, declarations, providers } = analyzedMetadata;
|
|
45
|
+
// Only create a new module if it doesn't already exist
|
|
46
|
+
// This is to prevent the module from being recreated on every story change
|
|
47
|
+
// Declarations & Imports are only added once
|
|
48
|
+
// Providers are added on every story change to allow for story-specific providers
|
|
49
|
+
let ngModule = exports.componentNgModules.get(storyComponent);
|
|
50
|
+
if (!ngModule) {
|
|
51
|
+
let StorybookComponentModule = class StorybookComponentModule {
|
|
52
|
+
};
|
|
53
|
+
StorybookComponentModule = __decorate([
|
|
54
|
+
(0, core_1.NgModule)({
|
|
55
|
+
declarations,
|
|
56
|
+
imports,
|
|
57
|
+
exports: [...declarations, ...imports],
|
|
58
|
+
})
|
|
59
|
+
], StorybookComponentModule);
|
|
60
|
+
exports.componentNgModules.set(storyComponent, StorybookComponentModule);
|
|
61
|
+
ngModule = exports.componentNgModules.get(storyComponent);
|
|
62
|
+
}
|
|
40
63
|
let StorybookWrapperComponent = class StorybookWrapperComponent {
|
|
41
64
|
constructor(storyProps$, changeDetectorRef) {
|
|
42
65
|
this.storyProps$ = storyProps$;
|
|
@@ -104,9 +127,14 @@ const createStorybookWrapperComponent = (selector, template, storyComponent, sty
|
|
|
104
127
|
(0, core_1.Component)({
|
|
105
128
|
selector,
|
|
106
129
|
template,
|
|
130
|
+
standalone: true,
|
|
131
|
+
imports: [ngModule],
|
|
132
|
+
providers,
|
|
107
133
|
styles,
|
|
134
|
+
schemas: moduleMetadata.schemas,
|
|
108
135
|
}),
|
|
109
136
|
__param(0, (0, core_1.Inject)(StorybookProvider_1.STORY_PROPS)),
|
|
137
|
+
__param(1, (0, core_1.Inject)(core_1.ChangeDetectorRef)),
|
|
110
138
|
__metadata("design:paramtypes", [rxjs_1.Subject,
|
|
111
139
|
core_1.ChangeDetectorRef])
|
|
112
140
|
], StorybookWrapperComponent);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.WithOfficialModule = void 0;
|
|
10
|
+
const common_1 = require("@angular/common");
|
|
11
|
+
const http_1 = require("@angular/common/http");
|
|
12
|
+
const core_1 = require("@angular/core");
|
|
13
|
+
let WithOfficialModule = class WithOfficialModule {
|
|
14
|
+
};
|
|
15
|
+
WithOfficialModule = __decorate([
|
|
16
|
+
(0, core_1.NgModule)({
|
|
17
|
+
imports: [common_1.CommonModule, http_1.HttpClientModule],
|
|
18
|
+
})
|
|
19
|
+
], WithOfficialModule);
|
|
20
|
+
exports.WithOfficialModule = WithOfficialModule;
|
|
@@ -76,7 +76,7 @@ const isStandaloneComponent = (component) => {
|
|
|
76
76
|
const decorators = reflectionCapabilities.annotations(component);
|
|
77
77
|
// TODO: `standalone` is only available in Angular v14. Remove cast to `any` once
|
|
78
78
|
// Angular deps are updated to v14.x.x.
|
|
79
|
-
return (decorators || []).some((d) => d instanceof core_1.Component && d.standalone);
|
|
79
|
+
return (decorators || []).some((d) => (d instanceof core_1.Component || d instanceof core_1.Directive || d instanceof core_1.Pipe) && d.standalone);
|
|
80
80
|
};
|
|
81
81
|
exports.isStandaloneComponent = isStandaloneComponent;
|
|
82
82
|
/**
|
|
@@ -252,8 +252,6 @@ describe('isComponent', () => {
|
|
|
252
252
|
});
|
|
253
253
|
describe('isStandaloneComponent', () => {
|
|
254
254
|
it('should return true with a Component with "standalone: true"', () => {
|
|
255
|
-
// TODO: `standalone` is only available in Angular v14. Remove cast to `any` once
|
|
256
|
-
// Angular deps are updated to v14.x.x.
|
|
257
255
|
let FooComponent = class FooComponent {
|
|
258
256
|
};
|
|
259
257
|
FooComponent = __decorate([
|
|
@@ -262,8 +260,6 @@ describe('isStandaloneComponent', () => {
|
|
|
262
260
|
expect((0, NgComponentAnalyzer_1.isStandaloneComponent)(FooComponent)).toEqual(true);
|
|
263
261
|
});
|
|
264
262
|
it('should return false with a Component with "standalone: false"', () => {
|
|
265
|
-
// TODO: `standalone` is only available in Angular v14. Remove cast to `any` once
|
|
266
|
-
// Angular deps are updated to v14.x.x.
|
|
267
263
|
let FooComponent = class FooComponent {
|
|
268
264
|
};
|
|
269
265
|
FooComponent = __decorate([
|
|
@@ -284,7 +280,23 @@ describe('isStandaloneComponent', () => {
|
|
|
284
280
|
}
|
|
285
281
|
expect((0, NgComponentAnalyzer_1.isStandaloneComponent)(FooPipe)).toEqual(false);
|
|
286
282
|
});
|
|
287
|
-
it('should return
|
|
283
|
+
it('should return true with a Directive with "standalone: true"', () => {
|
|
284
|
+
let FooDirective = class FooDirective {
|
|
285
|
+
};
|
|
286
|
+
FooDirective = __decorate([
|
|
287
|
+
(0, core_1.Directive)({ standalone: true })
|
|
288
|
+
], FooDirective);
|
|
289
|
+
expect((0, NgComponentAnalyzer_1.isStandaloneComponent)(FooDirective)).toEqual(true);
|
|
290
|
+
});
|
|
291
|
+
it('should return false with a Directive with "standalone: false"', () => {
|
|
292
|
+
let FooDirective = class FooDirective {
|
|
293
|
+
};
|
|
294
|
+
FooDirective = __decorate([
|
|
295
|
+
(0, core_1.Directive)({ standalone: false })
|
|
296
|
+
], FooDirective);
|
|
297
|
+
expect((0, NgComponentAnalyzer_1.isStandaloneComponent)(FooDirective)).toEqual(false);
|
|
298
|
+
});
|
|
299
|
+
it('should return false with Directive without the "standalone" property', () => {
|
|
288
300
|
let FooDirective = class FooDirective {
|
|
289
301
|
};
|
|
290
302
|
FooDirective = __decorate([
|
|
@@ -292,6 +304,32 @@ describe('isStandaloneComponent', () => {
|
|
|
292
304
|
], FooDirective);
|
|
293
305
|
expect((0, NgComponentAnalyzer_1.isStandaloneComponent)(FooDirective)).toEqual(false);
|
|
294
306
|
});
|
|
307
|
+
it('should return true with a Pipe with "standalone: true"', () => {
|
|
308
|
+
let FooPipe = class FooPipe {
|
|
309
|
+
};
|
|
310
|
+
FooPipe = __decorate([
|
|
311
|
+
(0, core_1.Pipe)({ name: 'FooPipe', standalone: true })
|
|
312
|
+
], FooPipe);
|
|
313
|
+
expect((0, NgComponentAnalyzer_1.isStandaloneComponent)(FooPipe)).toEqual(true);
|
|
314
|
+
});
|
|
315
|
+
it('should return false with a Pipe with "standalone: false"', () => {
|
|
316
|
+
let FooPipe = class FooPipe {
|
|
317
|
+
};
|
|
318
|
+
FooPipe = __decorate([
|
|
319
|
+
(0, core_1.Pipe)({ name: 'FooPipe', standalone: false })
|
|
320
|
+
], FooPipe);
|
|
321
|
+
expect((0, NgComponentAnalyzer_1.isStandaloneComponent)(FooPipe)).toEqual(false);
|
|
322
|
+
});
|
|
323
|
+
it('should return false with Pipe without the "standalone" property', () => {
|
|
324
|
+
let FooPipe = class FooPipe {
|
|
325
|
+
};
|
|
326
|
+
FooPipe = __decorate([
|
|
327
|
+
(0, core_1.Pipe)({
|
|
328
|
+
name: 'fooPipe',
|
|
329
|
+
})
|
|
330
|
+
], FooPipe);
|
|
331
|
+
expect((0, NgComponentAnalyzer_1.isStandaloneComponent)(FooPipe)).toEqual(false);
|
|
332
|
+
});
|
|
295
333
|
});
|
|
296
334
|
describe('getComponentDecoratorMetadata', () => {
|
|
297
335
|
it('should return Component with a Component', () => {
|
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Checks recursively if the component has already been declared in all import Module
|
|
5
5
|
*/
|
|
6
|
-
export declare const
|
|
6
|
+
export declare const isComponentAlreadyDeclared: (componentToFind: any, moduleDeclarations: any[], moduleImports: any[]) => boolean;
|