UNPKG

6.37 kBJavaScriptView Raw
1"use strict";
2var __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};
8var __metadata = (this && this.__metadata) || function (k, v) {
9 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10};
11var __param = (this && this.__param) || function (paramIndex, decorator) {
12 return function (target, key) { decorator(target, key, paramIndex); }
13};
14Object.defineProperty(exports, "__esModule", { value: true });
15exports.createStorybookWrapperComponent = void 0;
16const core_1 = require("@angular/core");
17const rxjs_1 = require("rxjs");
18const operators_1 = require("rxjs/operators");
19const StorybookProvider_1 = require("./StorybookProvider");
20const NgComponentAnalyzer_1 = require("./utils/NgComponentAnalyzer");
21const getNonInputsOutputsProps = (ngComponentInputsOutputs, props = {}) => {
22 const inputs = ngComponentInputsOutputs.inputs
23 .filter((i) => i.templateName in props)
24 .map((i) => i.templateName);
25 const outputs = ngComponentInputsOutputs.outputs
26 .filter((o) => o.templateName in props)
27 .map((o) => o.templateName);
28 return Object.keys(props).filter((k) => ![...inputs, ...outputs].includes(k));
29};
30/**
31 * Wraps the story template into a component
32 *
33 * @param storyComponent
34 * @param initialProps
35 */
36exports.createStorybookWrapperComponent = (selector, template, storyComponent, styles, initialProps) => {
37 // In ivy, a '' selector is not allowed, therefore we need to just set it to anything if
38 // storyComponent was not provided.
39 const viewChildSelector = storyComponent !== null && storyComponent !== void 0 ? storyComponent : '__storybook-noop';
40 let StorybookWrapperComponent = class StorybookWrapperComponent {
41 // eslint-disable-next-line no-useless-constructor
42 constructor(storyProps$, changeDetectorRef) {
43 this.storyProps$ = storyProps$;
44 this.changeDetectorRef = changeDetectorRef;
45 // Used in case of a component without selector
46 this.storyComponent = storyComponent !== null && storyComponent !== void 0 ? storyComponent : '';
47 }
48 ngOnInit() {
49 // Subscribes to the observable storyProps$ to keep these properties up to date
50 this.storyWrapperPropsSubscription = this.storyProps$.subscribe((storyProps = {}) => {
51 // All props are added as component properties
52 Object.assign(this, storyProps);
53 this.changeDetectorRef.detectChanges();
54 this.changeDetectorRef.markForCheck();
55 });
56 }
57 ngAfterViewInit() {
58 // Bind properties to component, if the story have component
59 if (this.storyComponentElementRef) {
60 const ngComponentInputsOutputs = NgComponentAnalyzer_1.getComponentInputsOutputs(storyComponent);
61 const initialOtherProps = getNonInputsOutputsProps(ngComponentInputsOutputs, initialProps);
62 // Initializes properties that are not Inputs | Outputs
63 // Allows story props to override local component properties
64 initialOtherProps.forEach((p) => {
65 this.storyComponentElementRef[p] = initialProps[p];
66 });
67 // `markForCheck` the component in case this uses changeDetection: OnPush
68 // And then forces the `detectChanges`
69 this.storyComponentViewContainerRef.injector.get(core_1.ChangeDetectorRef).markForCheck();
70 this.changeDetectorRef.detectChanges();
71 // Once target component has been initialized, the storyProps$ observable keeps target component properties than are not Input|Output up to date
72 this.storyComponentPropsSubscription = this.storyProps$
73 .pipe(operators_1.skip(1), operators_1.map((props) => {
74 const propsKeyToKeep = getNonInputsOutputsProps(ngComponentInputsOutputs, props);
75 return propsKeyToKeep.reduce((acc, p) => (Object.assign(Object.assign({}, acc), { [p]: props[p] })), {});
76 }))
77 .subscribe((props) => {
78 // Replace inputs with new ones from props
79 Object.assign(this.storyComponentElementRef, props);
80 // `markForCheck` the component in case this uses changeDetection: OnPush
81 // And then forces the `detectChanges`
82 this.storyComponentViewContainerRef.injector.get(core_1.ChangeDetectorRef).markForCheck();
83 this.changeDetectorRef.detectChanges();
84 });
85 }
86 }
87 ngOnDestroy() {
88 if (this.storyComponentPropsSubscription != null) {
89 this.storyComponentPropsSubscription.unsubscribe();
90 }
91 if (this.storyWrapperPropsSubscription != null) {
92 this.storyWrapperPropsSubscription.unsubscribe();
93 }
94 }
95 };
96 __decorate([
97 core_1.ViewChild(viewChildSelector, { static: true }),
98 __metadata("design:type", core_1.ElementRef)
99 ], StorybookWrapperComponent.prototype, "storyComponentElementRef", void 0);
100 __decorate([
101 core_1.ViewChild(viewChildSelector, { read: core_1.ViewContainerRef, static: true }),
102 __metadata("design:type", core_1.ViewContainerRef)
103 ], StorybookWrapperComponent.prototype, "storyComponentViewContainerRef", void 0);
104 StorybookWrapperComponent = __decorate([
105 core_1.Component({
106 selector,
107 template,
108 styles,
109 }),
110 __param(0, core_1.Inject(StorybookProvider_1.STORY_PROPS)),
111 __metadata("design:paramtypes", [rxjs_1.Subject,
112 core_1.ChangeDetectorRef])
113 ], StorybookWrapperComponent);
114 return StorybookWrapperComponent;
115};