@storybook/angular 10.1.0-alpha.8 → 10.1.0-beta.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.
@@ -0,0 +1,711 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __export = (target, all) => {
4
+ for (var name in all)
5
+ __defProp(target, name, { get: all[name], enumerable: !0 });
6
+ };
7
+ var __decorateClass = (decorators, target, key, kind) => {
8
+ for (var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target, i = decorators.length - 1, decorator; i >= 0; i--)
9
+ (decorator = decorators[i]) && (result = (kind ? decorator(target, key, result) : decorator(result)) || result);
10
+ return kind && result && __defProp(target, key, result), result;
11
+ }, __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
12
+
13
+ // src/client/render.ts
14
+ var render_exports = {};
15
+ __export(render_exports, {
16
+ render: () => render,
17
+ renderToCanvas: () => renderToCanvas,
18
+ rendererFactory: () => rendererFactory
19
+ });
20
+ import "@angular/compiler";
21
+
22
+ // src/client/angular-beta/AbstractRenderer.ts
23
+ import { bootstrapApplication } from "@angular/platform-browser";
24
+ import { BehaviorSubject } from "rxjs";
25
+ import { stringify } from "telejson";
26
+
27
+ // src/client/angular-beta/utils/NgComponentAnalyzer.ts
28
+ import {
29
+ Component,
30
+ Directive,
31
+ Input,
32
+ Output,
33
+ Pipe,
34
+ \u0275ReflectionCapabilities as ReflectionCapabilities
35
+ } from "@angular/core";
36
+ var reflectionCapabilities = new ReflectionCapabilities(), getComponentInputsOutputs = (component) => {
37
+ let componentMetadata = getComponentDecoratorMetadata(component), componentPropsMetadata = getComponentPropsDecoratorMetadata(component), initialValue = {
38
+ inputs: [],
39
+ outputs: []
40
+ };
41
+ return componentMetadata && componentMetadata.inputs && initialValue.inputs.push(
42
+ ...componentMetadata.inputs.map((i) => ({
43
+ propName: typeof i == "string" ? i : i.name,
44
+ templateName: typeof i == "string" ? i : i.alias
45
+ }))
46
+ ), componentMetadata && componentMetadata.outputs && initialValue.outputs.push(
47
+ ...componentMetadata.outputs.map((i) => ({ propName: i, templateName: i }))
48
+ ), componentPropsMetadata ? Object.entries(componentPropsMetadata).reduce((previousValue, [propertyName, values]) => {
49
+ let value = values.find((v) => v instanceof Input || v instanceof Output);
50
+ if (value instanceof Input) {
51
+ let inputToAdd = {
52
+ propName: propertyName,
53
+ templateName: value.bindingPropertyName ?? value.alias ?? propertyName
54
+ }, previousInputsFiltered = previousValue.inputs.filter(
55
+ (i) => i.templateName !== propertyName
56
+ );
57
+ return {
58
+ ...previousValue,
59
+ inputs: [...previousInputsFiltered, inputToAdd]
60
+ };
61
+ }
62
+ if (value instanceof Output) {
63
+ let outputToAdd = {
64
+ propName: propertyName,
65
+ templateName: value.bindingPropertyName ?? value.alias ?? propertyName
66
+ }, previousOutputsFiltered = previousValue.outputs.filter(
67
+ (i) => i.templateName !== propertyName
68
+ );
69
+ return {
70
+ ...previousValue,
71
+ outputs: [...previousOutputsFiltered, outputToAdd]
72
+ };
73
+ }
74
+ return previousValue;
75
+ }, initialValue) : initialValue;
76
+ };
77
+ var isComponent = (component) => component ? (reflectionCapabilities.annotations(component) || []).some((d) => d instanceof Component) : !1;
78
+ var getComponentPropsDecoratorMetadata = (component) => reflectionCapabilities.propMetadata(component), getComponentDecoratorMetadata = (component) => reflectionCapabilities.annotations(component).reverse().find((d) => d instanceof Component);
79
+
80
+ // src/client/angular-beta/ComputesTemplateFromComponent.ts
81
+ var isValidIdentifier = (name) => /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name), formatPropInTemplate = (propertyName) => isValidIdentifier(propertyName) ? propertyName : `this['${propertyName}']`, separateInputsOutputsAttributes = (ngComponentInputsOutputs, props = {}) => {
82
+ let inputs = ngComponentInputsOutputs.inputs.filter((i) => i.templateName in props).map((i) => i.templateName), outputs = ngComponentInputsOutputs.outputs.filter((o) => o.templateName in props).map((o) => o.templateName);
83
+ return {
84
+ inputs,
85
+ outputs,
86
+ otherProps: Object.keys(props).filter((k) => ![...inputs, ...outputs].includes(k))
87
+ };
88
+ }, computesTemplateFromComponent = (component, initialProps, innerTemplate = "") => {
89
+ let ngComponentMetadata = getComponentDecoratorMetadata(component), ngComponentInputsOutputs = getComponentInputsOutputs(component);
90
+ if (!ngComponentMetadata.selector)
91
+ return '<ng-container *ngComponentOutlet="storyComponent"></ng-container>';
92
+ let { inputs: initialInputs, outputs: initialOutputs } = separateInputsOutputsAttributes(
93
+ ngComponentInputsOutputs,
94
+ initialProps
95
+ ), templateInputs = initialInputs.length > 0 ? ` ${initialInputs.map((i) => `[${i}]="${formatPropInTemplate(i)}"`).join(" ")}` : "", templateOutputs = initialOutputs.length > 0 ? ` ${initialOutputs.map((i) => `(${i})="${formatPropInTemplate(i)}($event)"`).join(" ")}` : "";
96
+ return buildTemplate(
97
+ ngComponentMetadata.selector,
98
+ innerTemplate,
99
+ templateInputs,
100
+ templateOutputs
101
+ );
102
+ };
103
+ function stringifyCircular(obj) {
104
+ let seen = /* @__PURE__ */ new Set();
105
+ return JSON.stringify(obj, (key, value) => {
106
+ if (typeof value == "object" && value !== null) {
107
+ if (seen.has(value))
108
+ return "[Circular]";
109
+ seen.add(value);
110
+ }
111
+ return value;
112
+ });
113
+ }
114
+ var createAngularInputProperty = ({
115
+ propertyName,
116
+ value,
117
+ argType
118
+ }) => {
119
+ let templateValue;
120
+ switch (typeof value) {
121
+ case "string":
122
+ templateValue = `'${value}'`;
123
+ break;
124
+ case "object":
125
+ templateValue = stringifyCircular(value).replace(/'/g, "\u2019").replace(/\\"/g, "\u201D").replace(/"([^-"]+)":/g, "$1: ").replace(/"/g, "'").replace(/\u2019/g, "\\'").replace(/\u201D/g, "\\'").split(",").join(", ");
126
+ break;
127
+ default:
128
+ templateValue = value;
129
+ }
130
+ return `[${propertyName}]="${templateValue}"`;
131
+ }, computesTemplateSourceFromComponent = (component, initialProps, argTypes) => {
132
+ let ngComponentMetadata = getComponentDecoratorMetadata(component);
133
+ if (!ngComponentMetadata)
134
+ return null;
135
+ if (!ngComponentMetadata.selector)
136
+ return `<ng-container *ngComponentOutlet="${component.name}"></ng-container>`;
137
+ let ngComponentInputsOutputs = getComponentInputsOutputs(component), { inputs: initialInputs, outputs: initialOutputs } = separateInputsOutputsAttributes(
138
+ ngComponentInputsOutputs,
139
+ initialProps
140
+ ), templateInputs = initialInputs.length > 0 ? ` ${initialInputs.map(
141
+ (propertyName) => createAngularInputProperty({
142
+ propertyName,
143
+ value: initialProps[propertyName],
144
+ argType: argTypes?.[propertyName]
145
+ })
146
+ ).join(" ")}` : "", templateOutputs = initialOutputs.length > 0 ? ` ${initialOutputs.map((i) => `(${i})="${formatPropInTemplate(i)}($event)"`).join(" ")}` : "";
147
+ return buildTemplate(ngComponentMetadata.selector, "", templateInputs, templateOutputs);
148
+ }, buildTemplate = (selector, innerTemplate, inputs, outputs) => {
149
+ let voidElements = [
150
+ "area",
151
+ "base",
152
+ "br",
153
+ "col",
154
+ "command",
155
+ "embed",
156
+ "hr",
157
+ "img",
158
+ "input",
159
+ "keygen",
160
+ "link",
161
+ "meta",
162
+ "param",
163
+ "source",
164
+ "track",
165
+ "wbr"
166
+ ], firstSelector = selector.split(",")[0];
167
+ return [
168
+ [/(^.*?)(?=[,])/, "$1"],
169
+ [/(^\..+)/, "div$1"],
170
+ [/(^\[.+?])/, "div$1"],
171
+ [/([\w[\]]+)(\s*,[\w\s-[\],]+)+/, "$1"],
172
+ [/#([\w-]+)/, ' id="$1"'],
173
+ [/((\.[\w-]+)+)/, (_, c) => ` class="${c.split`.`.join` `.trim()}"`],
174
+ [/(\[.+?])/g, (_, a) => ` ${a.slice(1, -1)}`],
175
+ [
176
+ /([\S]+)(.*)/,
177
+ (template, elementSelector) => voidElements.some((element) => elementSelector === element) ? template.replace(/([\S]+)(.*)/, `<$1$2${inputs}${outputs} />`) : template.replace(/([\S]+)(.*)/, `<$1$2${inputs}${outputs}>${innerTemplate}</$1>`)
178
+ ]
179
+ ].reduce(
180
+ (prevSelector, [searchValue, replacer]) => prevSelector.replace(searchValue, replacer),
181
+ firstSelector
182
+ );
183
+ };
184
+
185
+ // src/client/angular-beta/StorybookWrapperComponent.ts
186
+ import {
187
+ ChangeDetectorRef,
188
+ Component as Component3,
189
+ Inject,
190
+ NgModule as NgModule2,
191
+ ViewChild,
192
+ ViewContainerRef
193
+ } from "@angular/core";
194
+ import { map, skip } from "rxjs/operators";
195
+
196
+ // src/client/angular-beta/StorybookProvider.ts
197
+ import { InjectionToken, NgZone } from "@angular/core";
198
+ import { Observable } from "rxjs";
199
+ var STORY_PROPS = new InjectionToken("STORY_PROPS"), storyPropsProvider = (storyProps$) => ({
200
+ provide: STORY_PROPS,
201
+ useFactory: storyDataFactory(storyProps$.asObservable()),
202
+ deps: [NgZone]
203
+ });
204
+ function storyDataFactory(data) {
205
+ return (ngZone) => new Observable((subscriber) => {
206
+ let sub = data.subscribe(
207
+ (v) => {
208
+ ngZone.run(() => subscriber.next(v));
209
+ },
210
+ (err) => {
211
+ ngZone.run(() => subscriber.error(err));
212
+ },
213
+ () => {
214
+ ngZone.run(() => subscriber.complete());
215
+ }
216
+ );
217
+ return () => {
218
+ sub.unsubscribe();
219
+ };
220
+ });
221
+ }
222
+
223
+ // src/client/angular-beta/utils/PropertyExtractor.ts
224
+ import { CommonModule } from "@angular/common";
225
+ import {
226
+ Component as Component2,
227
+ Directive as Directive2,
228
+ Injectable,
229
+ InjectionToken as InjectionToken2,
230
+ Input as Input2,
231
+ Output as Output2,
232
+ Pipe as Pipe2,
233
+ \u0275ReflectionCapabilities as ReflectionCapabilities3,
234
+ VERSION
235
+ } from "@angular/core";
236
+ import { BrowserModule } from "@angular/platform-browser";
237
+ import { dedent } from "ts-dedent";
238
+
239
+ // src/client/angular-beta/utils/NgModulesAnalyzer.ts
240
+ import { NgModule, \u0275ReflectionCapabilities as ReflectionCapabilities2 } from "@angular/core";
241
+ var reflectionCapabilities2 = new ReflectionCapabilities2(), isComponentAlreadyDeclared = (componentToFind, moduleDeclarations, moduleImports) => moduleDeclarations && moduleDeclarations.flat().some((declaration) => declaration === componentToFind) ? !0 : moduleImports ? moduleImports.flat().some((importItem) => {
242
+ let extractedNgModuleMetadata = extractNgModuleMetadata(importItem);
243
+ return extractedNgModuleMetadata ? isComponentAlreadyDeclared(
244
+ componentToFind,
245
+ extractedNgModuleMetadata.declarations,
246
+ extractedNgModuleMetadata.imports
247
+ ) : !1;
248
+ }) : !1, extractNgModuleMetadata = (importItem) => {
249
+ let target = importItem && importItem.ngModule ? importItem.ngModule : importItem, decorators = reflectionCapabilities2.annotations(target);
250
+ if (!decorators || decorators.length === 0)
251
+ return null;
252
+ let ngModuleDecorator = decorators.find(
253
+ (decorator) => decorator instanceof NgModule
254
+ );
255
+ return ngModuleDecorator || null;
256
+ };
257
+
258
+ // src/client/angular-beta/utils/PropertyExtractor.ts
259
+ var reflectionCapabilities3 = new ReflectionCapabilities3(), REMOVED_MODULES = new InjectionToken2("REMOVED_MODULES"), uniqueArray = (arr) => arr.flat(Number.MAX_VALUE).filter(Boolean).filter((value, index, self) => self.indexOf(value) === index), _PropertyExtractor = class _PropertyExtractor {
260
+ constructor(metadata, component) {
261
+ this.metadata = metadata;
262
+ this.component = component;
263
+ this.declarations = [];
264
+ /**
265
+ * Analyze NgModule Metadata
266
+ *
267
+ * - Removes Restricted Imports
268
+ * - Extracts providers from ModuleWithProviders
269
+ * - Returns a new NgModuleMetadata object
270
+ */
271
+ this.analyzeMetadata = async (metadata) => {
272
+ let declarations = [...metadata?.declarations || []], providers = [...metadata?.providers || []], applicationProviders = [], imports = await Promise.all(
273
+ [...metadata?.imports || []].map(async (imported) => {
274
+ let [isRestricted, restrictedProviders] = await _PropertyExtractor.analyzeRestricted(imported);
275
+ return isRestricted ? (applicationProviders.unshift(restrictedProviders || []), null) : imported;
276
+ })
277
+ ).then((results) => results.filter(Boolean));
278
+ return { ...metadata, imports, providers, applicationProviders, declarations };
279
+ };
280
+ }
281
+ // With the new way of mounting standalone components to the DOM via bootstrapApplication API,
282
+ // we should now pass ModuleWithProviders to the providers array of the bootstrapApplication function.
283
+ static warnImportsModuleWithProviders(propertyExtractor) {
284
+ propertyExtractor.imports.some(
285
+ (importedModule) => "ngModule" in importedModule
286
+ ) && console.warn(
287
+ dedent(
288
+ `
289
+ Storybook Warning:
290
+ moduleMetadata property 'imports' contains one or more ModuleWithProviders, likely the result of a 'Module.forRoot()'-style call.
291
+ In Storybook 7.0 we use Angular's new 'bootstrapApplication' API to mount the component to the DOM, which accepts a list of providers to set up application-wide providers.
292
+ Use the 'applicationConfig' decorator from '@storybook/angular' to pass your ModuleWithProviders to the 'providers' property in combination with the importProvidersFrom helper function from '@angular/core' to extract all the necessary providers.
293
+ Visit https://angular.io/guide/standalone-components#configuring-dependency-injection for more information
294
+ `
295
+ )
296
+ );
297
+ }
298
+ async init() {
299
+ let analyzed = await this.analyzeMetadata(this.metadata);
300
+ if (this.imports = uniqueArray([CommonModule, analyzed.imports]), this.providers = uniqueArray(analyzed.providers), this.applicationProviders = uniqueArray(analyzed.applicationProviders), this.declarations = uniqueArray(analyzed.declarations), this.component) {
301
+ let { isDeclarable, isStandalone } = _PropertyExtractor.analyzeDecorators(this.component), isDeclared = isComponentAlreadyDeclared(
302
+ this.component,
303
+ analyzed.declarations,
304
+ this.imports
305
+ );
306
+ isStandalone ? this.imports.push(this.component) : isDeclarable && !isDeclared && this.declarations.push(this.component);
307
+ }
308
+ }
309
+ };
310
+ _PropertyExtractor.analyzeRestricted = async (ngModule) => {
311
+ if (ngModule === BrowserModule)
312
+ return console.warn(
313
+ dedent`
314
+ Storybook Warning:
315
+ You have imported the "BrowserModule", which is not necessary anymore.
316
+ In Storybook v7.0 we are using Angular's new bootstrapApplication API to mount an Angular application to the DOM.
317
+ Note that the BrowserModule providers are automatically included when starting an application with bootstrapApplication()
318
+ Please remove the "BrowserModule" from the list of imports in your moduleMetadata definition to remove this warning.
319
+ `
320
+ ), [!0];
321
+ try {
322
+ let animations = await import("@angular/platform-browser/animations");
323
+ if (ngModule === animations.BrowserAnimationsModule)
324
+ return console.warn(
325
+ dedent`
326
+ Storybook Warning:
327
+ You have added the "BrowserAnimationsModule" to the list of "imports" in your moduleMetadata definition of your Story.
328
+ In Storybook 7.0 we use Angular's new 'bootstrapApplication' API to mount the component to the DOM, which accepts a list of providers to set up application-wide providers.
329
+ Use the 'applicationConfig' decorator from '@storybook/angular' and add the "provideAnimations" function to the list of "providers".
330
+ If your Angular version does not support "provide-like" functions, use the helper function importProvidersFrom instead to set up animations. For this case, please add "importProvidersFrom(BrowserAnimationsModule)" to the list of providers of your applicationConfig definition.
331
+ Please visit https://angular.io/guide/standalone-components#configuring-dependency-injection for more information.
332
+ `
333
+ ), [!0, animations.provideAnimations()];
334
+ if (ngModule === animations.NoopAnimationsModule)
335
+ return console.warn(
336
+ dedent`
337
+ Storybook Warning:
338
+ You have added the "NoopAnimationsModule" to the list of "imports" in your moduleMetadata definition of your Story.
339
+ In Storybook v7.0 we are using Angular's new bootstrapApplication API to mount an Angular application to the DOM, which accepts a list of providers to set up application-wide providers.
340
+ Use the 'applicationConfig' decorator from '@storybook/angular' and add the "provideNoopAnimations" function to the list of "providers".
341
+ If your Angular version does not support "provide-like" functions, use the helper function importProvidersFrom instead to set up noop animations and to extract all necessary providers from NoopAnimationsModule. For this case, please add "importProvidersFrom(NoopAnimationsModule)" to the list of providers of your applicationConfig definition.
342
+ Please visit https://angular.io/guide/standalone-components#configuring-dependency-injection for more information.
343
+ `
344
+ ), [!0, animations.provideNoopAnimations()];
345
+ } catch {
346
+ return [!1];
347
+ }
348
+ return [!1];
349
+ }, _PropertyExtractor.analyzeDecorators = (component) => {
350
+ let decorators = reflectionCapabilities3.annotations(component), isComponent2 = decorators.some((d) => _PropertyExtractor.isDecoratorInstanceOf(d, "Component")), isDirective = decorators.some((d) => _PropertyExtractor.isDecoratorInstanceOf(d, "Directive")), isPipe = decorators.some((d) => _PropertyExtractor.isDecoratorInstanceOf(d, "Pipe")), isDeclarable = isComponent2 || isDirective || isPipe, isStandalone = (isComponent2 || isDirective) && [...decorators].reverse().find(
351
+ (d) => _PropertyExtractor.isDecoratorInstanceOf(d, "Component") || _PropertyExtractor.isDecoratorInstanceOf(d, "Directive")
352
+ )?.standalone;
353
+ return isStandalone === void 0 && (isStandalone = !!(VERSION.major && Number(VERSION.major) >= 19)), { isDeclarable, isStandalone };
354
+ }, _PropertyExtractor.isDecoratorInstanceOf = (decorator, name) => {
355
+ let factory;
356
+ switch (name) {
357
+ case "Component":
358
+ factory = Component2;
359
+ break;
360
+ case "Directive":
361
+ factory = Directive2;
362
+ break;
363
+ case "Pipe":
364
+ factory = Pipe2;
365
+ break;
366
+ case "Injectable":
367
+ factory = Injectable;
368
+ break;
369
+ case "Input":
370
+ factory = Input2;
371
+ break;
372
+ case "Output":
373
+ factory = Output2;
374
+ break;
375
+ default:
376
+ throw new Error(`Unknown decorator type: ${name}`);
377
+ }
378
+ return decorator instanceof factory || decorator.ngMetadataName === name;
379
+ };
380
+ var PropertyExtractor = _PropertyExtractor;
381
+
382
+ // src/client/angular-beta/StorybookWrapperComponent.ts
383
+ var getNonInputsOutputsProps = (ngComponentInputsOutputs, props = {}) => {
384
+ let inputs = ngComponentInputsOutputs.inputs.filter((i) => i.templateName in props).map((i) => i.templateName), outputs = ngComponentInputsOutputs.outputs.filter((o) => o.templateName in props).map((o) => o.templateName);
385
+ return Object.keys(props).filter((k) => ![...inputs, ...outputs].includes(k));
386
+ }, createStorybookWrapperComponent = ({
387
+ selector,
388
+ template,
389
+ storyComponent,
390
+ styles,
391
+ moduleMetadata,
392
+ initialProps,
393
+ analyzedMetadata
394
+ }) => {
395
+ let viewChildSelector = storyComponent ?? "__storybook-noop", { imports, declarations, providers } = analyzedMetadata, StorybookComponentModule = class {
396
+ };
397
+ StorybookComponentModule = __decorateClass([
398
+ NgModule2({
399
+ declarations,
400
+ imports,
401
+ exports: [...declarations, ...imports]
402
+ })
403
+ ], StorybookComponentModule), PropertyExtractor.warnImportsModuleWithProviders(analyzedMetadata);
404
+ let StorybookWrapperComponent = class {
405
+ constructor(storyProps$, changeDetectorRef) {
406
+ this.storyProps$ = storyProps$;
407
+ this.changeDetectorRef = changeDetectorRef;
408
+ // Used in case of a component without selector
409
+ this.storyComponent = storyComponent ?? "";
410
+ }
411
+ ngOnInit() {
412
+ this.storyWrapperPropsSubscription = this.storyProps$.subscribe((storyProps = {}) => {
413
+ Object.assign(this, storyProps), this.changeDetectorRef.detectChanges(), this.changeDetectorRef.markForCheck();
414
+ });
415
+ }
416
+ ngAfterViewInit() {
417
+ if (this.storyComponentElementRef) {
418
+ let ngComponentInputsOutputs = getComponentInputsOutputs(storyComponent);
419
+ getNonInputsOutputsProps(ngComponentInputsOutputs, initialProps).forEach((p) => {
420
+ this.storyComponentElementRef[p] = initialProps[p];
421
+ }), this.storyComponentViewContainerRef.injector.get(ChangeDetectorRef).markForCheck(), this.changeDetectorRef.detectChanges(), this.storyComponentPropsSubscription = this.storyProps$.pipe(
422
+ skip(1),
423
+ map((props) => getNonInputsOutputsProps(ngComponentInputsOutputs, props).reduce((acc, p) => ({ ...acc, [p]: props[p] }), {}))
424
+ ).subscribe((props) => {
425
+ Object.assign(this.storyComponentElementRef, props), this.storyComponentViewContainerRef.injector.get(ChangeDetectorRef).markForCheck(), this.changeDetectorRef.detectChanges();
426
+ });
427
+ }
428
+ }
429
+ ngOnDestroy() {
430
+ this.storyComponentPropsSubscription != null && this.storyComponentPropsSubscription.unsubscribe(), this.storyWrapperPropsSubscription != null && this.storyWrapperPropsSubscription.unsubscribe();
431
+ }
432
+ };
433
+ return __decorateClass([
434
+ ViewChild(viewChildSelector, { static: !0 })
435
+ ], StorybookWrapperComponent.prototype, "storyComponentElementRef", 2), __decorateClass([
436
+ ViewChild(viewChildSelector, { read: ViewContainerRef, static: !0 })
437
+ ], StorybookWrapperComponent.prototype, "storyComponentViewContainerRef", 2), StorybookWrapperComponent = __decorateClass([
438
+ Component3({
439
+ selector,
440
+ template,
441
+ standalone: !0,
442
+ imports: [StorybookComponentModule],
443
+ providers,
444
+ styles,
445
+ schemas: moduleMetadata.schemas
446
+ }),
447
+ __decorateParam(0, Inject(STORY_PROPS)),
448
+ __decorateParam(1, Inject(ChangeDetectorRef))
449
+ ], StorybookWrapperComponent), StorybookWrapperComponent;
450
+ };
451
+
452
+ // src/client/angular-beta/StorybookModule.ts
453
+ var getApplication = ({
454
+ storyFnAngular,
455
+ component,
456
+ targetSelector,
457
+ analyzedMetadata
458
+ }) => {
459
+ let { props, styles, moduleMetadata = {} } = storyFnAngular, { template } = storyFnAngular;
460
+ return !!hasNoTemplate(template) && component && (template = computesTemplateFromComponent(component, props, "")), createStorybookWrapperComponent({
461
+ moduleMetadata,
462
+ selector: targetSelector,
463
+ template,
464
+ storyComponent: component,
465
+ styles,
466
+ initialProps: props,
467
+ analyzedMetadata
468
+ });
469
+ };
470
+ function hasNoTemplate(template) {
471
+ return template == null;
472
+ }
473
+
474
+ // src/client/angular-beta/utils/BootstrapQueue.ts
475
+ var queue = [], isProcessing = !1, resetCompiledComponents = async () => {
476
+ try {
477
+ let { \u0275resetCompiledComponents } = await import("@angular/core");
478
+ \u0275resetCompiledComponents();
479
+ } catch {
480
+ }
481
+ }, queueBootstrapping = (fn) => new Promise((resolve, reject) => {
482
+ queue.push(() => fn().then(resolve).catch(reject)), isProcessing || processQueue();
483
+ }), processQueue = async () => {
484
+ for (isProcessing = !0; queue.length > 0; ) {
485
+ let bootstrappingFn = queue.shift();
486
+ bootstrappingFn && (await bootstrappingFn(), await resetCompiledComponents());
487
+ }
488
+ isProcessing = !1;
489
+ };
490
+
491
+ // src/client/angular-beta/utils/Zoneless.ts
492
+ var getProvideZonelessChangeDetectionFn = async () => {
493
+ let angularCore = await import("@angular/core");
494
+ return "provideExperimentalZonelessChangeDetection" in angularCore ? angularCore.provideExperimentalZonelessChangeDetection : "provideZonelessChangeDetection" in angularCore ? angularCore.provideZonelessChangeDetection : null;
495
+ };
496
+
497
+ // src/client/angular-beta/AbstractRenderer.ts
498
+ var applicationRefs = /* @__PURE__ */ new Map(), STORY_UID_ATTRIBUTE = "data-sb-story-uid", AbstractRenderer = class {
499
+ constructor() {
500
+ this.previousStoryRenderInfo = /* @__PURE__ */ new Map();
501
+ }
502
+ /** Wait and destroy the platform */
503
+ static resetApplications(domNode) {
504
+ applicationRefs.forEach((appRef, appDOMNode) => {
505
+ !appRef.destroyed && (!domNode || appDOMNode === domNode) && appRef.destroy();
506
+ });
507
+ }
508
+ /**
509
+ * Bootstrap main angular module with main component or send only new `props` with storyProps$
510
+ *
511
+ * @param storyFnAngular {StoryFnAngularReturnType}
512
+ * @param forced {boolean} If :
513
+ *
514
+ * - True render will only use the StoryFn `props' in storyProps observable that will update sotry's
515
+ * component/template properties. Improves performance without reloading the whole
516
+ * module&component if props changes
517
+ * - False fully recharges or initializes angular module & component
518
+ *
519
+ * @param component {Component}
520
+ */
521
+ async render({
522
+ storyFnAngular,
523
+ forced,
524
+ component,
525
+ targetDOMNode
526
+ }) {
527
+ let targetSelector = this.generateTargetSelectorFromStoryId(targetDOMNode.id), newStoryProps$ = new BehaviorSubject(storyFnAngular.props);
528
+ if (!this.fullRendererRequired({
529
+ targetDOMNode,
530
+ storyFnAngular,
531
+ moduleMetadata: {
532
+ ...storyFnAngular.moduleMetadata
533
+ },
534
+ forced
535
+ })) {
536
+ this.storyProps$.next(storyFnAngular.props);
537
+ return;
538
+ }
539
+ await this.beforeFullRender(targetDOMNode), this.storyProps$ && this.storyProps$.complete(), this.storyProps$ = newStoryProps$, this.initAngularRootElement(targetDOMNode, targetSelector);
540
+ let analyzedMetadata = new PropertyExtractor(storyFnAngular.moduleMetadata, component);
541
+ await analyzedMetadata.init();
542
+ let storyUid = this.generateStoryUIdFromRawStoryUid(
543
+ targetDOMNode.getAttribute(STORY_UID_ATTRIBUTE)
544
+ ), componentSelector = storyUid !== null ? `${targetSelector}[${storyUid}]` : targetSelector;
545
+ storyUid !== null && targetDOMNode.querySelector(targetSelector).toggleAttribute(storyUid, !0);
546
+ let application = getApplication({
547
+ storyFnAngular,
548
+ component,
549
+ targetSelector: componentSelector,
550
+ analyzedMetadata
551
+ }), providers = [
552
+ storyPropsProvider(newStoryProps$),
553
+ ...analyzedMetadata.applicationProviders,
554
+ ...storyFnAngular.applicationConfig?.providers ?? []
555
+ ];
556
+ if (STORYBOOK_ANGULAR_OPTIONS?.experimentalZoneless) {
557
+ let provideZonelessChangeDetectionFn = await getProvideZonelessChangeDetectionFn();
558
+ if (provideZonelessChangeDetectionFn)
559
+ providers.unshift(provideZonelessChangeDetectionFn());
560
+ else
561
+ throw new Error("Zoneless change detection requires Angular 18 or higher");
562
+ }
563
+ let applicationRef = await queueBootstrapping(() => bootstrapApplication(application, {
564
+ ...storyFnAngular.applicationConfig,
565
+ providers
566
+ }));
567
+ applicationRefs.set(targetDOMNode, applicationRef);
568
+ }
569
+ /**
570
+ * Only ASCII alphanumerics can be used as HTML tag name. https://html.spec.whatwg.org/#elements-2
571
+ *
572
+ * Therefore, stories break when non-ASCII alphanumerics are included in target selector.
573
+ * https://github.com/storybookjs/storybook/issues/15147
574
+ *
575
+ * This method returns storyId when it doesn't contain any non-ASCII alphanumerics. Otherwise, it
576
+ * generates a valid HTML tag name from storyId by removing non-ASCII alphanumerics from storyId,
577
+ * prefixing "sb-", and suffixing "-component"
578
+ *
579
+ * @memberof AbstractRenderer
580
+ * @protected
581
+ */
582
+ generateTargetSelectorFromStoryId(id) {
583
+ let invalidHtmlTag = /[^A-Za-z0-9-]/g;
584
+ return invalidHtmlTag.test(id) ? `sb-${id.replace(invalidHtmlTag, "")}-component` : id;
585
+ }
586
+ /**
587
+ * Angular is unable to handle components that have selectors with accented attributes.
588
+ *
589
+ * Therefore, stories break when meta's title contains accents.
590
+ * https://github.com/storybookjs/storybook/issues/29132
591
+ *
592
+ * This method filters accents from a given raw id. For example, this method converts
593
+ * 'Example/Button with an "é" accent' into 'Example/Button with an "e" accent'.
594
+ *
595
+ * @memberof AbstractRenderer
596
+ * @protected
597
+ */
598
+ generateStoryUIdFromRawStoryUid(rawStoryUid) {
599
+ if (rawStoryUid === null)
600
+ return rawStoryUid;
601
+ let accentCharacters = /[\u0300-\u036f]/g;
602
+ return rawStoryUid.normalize("NFD").replace(accentCharacters, "");
603
+ }
604
+ /** Adds DOM element that angular will use as bootstrap component. */
605
+ initAngularRootElement(targetDOMNode, targetSelector) {
606
+ targetDOMNode.innerHTML = "", targetDOMNode.appendChild(document.createElement(targetSelector));
607
+ }
608
+ fullRendererRequired({
609
+ targetDOMNode,
610
+ storyFnAngular,
611
+ moduleMetadata,
612
+ forced
613
+ }) {
614
+ let previousStoryRenderInfo = this.previousStoryRenderInfo.get(targetDOMNode), currentStoryRender = {
615
+ storyFnAngular,
616
+ moduleMetadataSnapshot: stringify(moduleMetadata, { maxDepth: 50 })
617
+ };
618
+ return this.previousStoryRenderInfo.set(targetDOMNode, currentStoryRender), // check `forceRender` of story RenderContext
619
+ !forced || // if it's the first rendering and storyProps$ is not init
620
+ !this.storyProps$ || !!storyFnAngular?.template && previousStoryRenderInfo?.storyFnAngular?.template !== storyFnAngular.template ? !0 : currentStoryRender.moduleMetadataSnapshot !== previousStoryRenderInfo?.moduleMetadataSnapshot;
621
+ }
622
+ };
623
+
624
+ // src/client/angular-beta/CanvasRenderer.ts
625
+ var CanvasRenderer = class _CanvasRenderer extends AbstractRenderer {
626
+ async render(options) {
627
+ await super.render(options);
628
+ }
629
+ async beforeFullRender() {
630
+ _CanvasRenderer.resetApplications();
631
+ }
632
+ };
633
+
634
+ // src/client/angular-beta/DocsRenderer.ts
635
+ import { DOCS_RENDERED, STORY_CHANGED } from "storybook/internal/core-events";
636
+ import { addons } from "storybook/preview-api";
637
+
638
+ // src/client/angular-beta/utils/StoryUID.ts
639
+ var storyCounts = /* @__PURE__ */ new Map(), getNextStoryUID = (storyId) => {
640
+ storyCounts.has(storyId) || storyCounts.set(storyId, -1);
641
+ let count = storyCounts.get(storyId) + 1;
642
+ return storyCounts.set(storyId, count), `${storyId}-${count}`;
643
+ };
644
+
645
+ // src/client/angular-beta/DocsRenderer.ts
646
+ var DocsRenderer = class _DocsRenderer extends AbstractRenderer {
647
+ async render(options) {
648
+ let channel = addons.getChannel();
649
+ channel.once(STORY_CHANGED, async () => {
650
+ await _DocsRenderer.resetApplications();
651
+ }), channel.once(DOCS_RENDERED, async () => {
652
+ await _DocsRenderer.resetApplications();
653
+ }), await super.render({ ...options, forced: !1 });
654
+ }
655
+ async beforeFullRender(domNode) {
656
+ _DocsRenderer.resetApplications(domNode);
657
+ }
658
+ initAngularRootElement(targetDOMNode, targetSelector) {
659
+ super.initAngularRootElement(targetDOMNode, targetSelector), targetDOMNode.setAttribute(STORY_UID_ATTRIBUTE, getNextStoryUID(targetDOMNode.id));
660
+ }
661
+ };
662
+
663
+ // src/client/angular-beta/RendererFactory.ts
664
+ var RendererFactory = class {
665
+ constructor() {
666
+ this.rendererMap = /* @__PURE__ */ new Map();
667
+ }
668
+ async getRendererInstance(targetDOMNode) {
669
+ let targetId = targetDOMNode.id;
670
+ if (targetDOMNode === null)
671
+ return null;
672
+ let renderType = getRenderType(targetDOMNode);
673
+ return this.lastRenderType && this.lastRenderType !== renderType && (await AbstractRenderer.resetApplications(), clearRootHTMLElement(renderType), this.rendererMap.clear()), this.rendererMap.has(targetId) || this.rendererMap.set(targetId, this.buildRenderer(renderType)), this.lastRenderType = renderType, this.rendererMap.get(targetId);
674
+ }
675
+ buildRenderer(renderType) {
676
+ return renderType === "docs" ? new DocsRenderer() : new CanvasRenderer();
677
+ }
678
+ }, getRenderType = (targetDOMNode) => targetDOMNode.id === "storybook-root" ? "canvas" : "docs";
679
+ function clearRootHTMLElement(renderType) {
680
+ switch (renderType) {
681
+ case "canvas":
682
+ global.document.getElementById("storybook-docs").innerHTML = "";
683
+ break;
684
+ case "docs":
685
+ global.document.getElementById("storybook-root").innerHTML = "";
686
+ break;
687
+ default:
688
+ break;
689
+ }
690
+ }
691
+
692
+ // src/client/render.ts
693
+ var rendererFactory = new RendererFactory(), render = (props) => ({ props });
694
+ async function renderToCanvas({ storyFn, showMain, forceRemount, storyContext: { component } }, element) {
695
+ showMain(), await (await rendererFactory.getRendererInstance(element)).render({
696
+ storyFnAngular: storyFn(),
697
+ component,
698
+ forced: !forceRemount,
699
+ targetDOMNode: element
700
+ });
701
+ }
702
+
703
+ export {
704
+ isComponent,
705
+ formatPropInTemplate,
706
+ computesTemplateFromComponent,
707
+ computesTemplateSourceFromComponent,
708
+ render,
709
+ renderToCanvas,
710
+ render_exports
711
+ };