@ng-doc/app 22.0.0-beta.2 → 22.0.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 +20 -29
- package/fesm2022/ng-doc-app-classes-content-anchor-controller.mjs +363 -0
- package/fesm2022/ng-doc-app-classes-content-anchor-controller.mjs.map +1 -0
- package/fesm2022/ng-doc-app-classes-content-controller.mjs +299 -0
- package/fesm2022/ng-doc-app-classes-content-controller.mjs.map +1 -0
- package/fesm2022/ng-doc-app-classes-default-search-engine.mjs +51 -35
- package/fesm2022/ng-doc-app-classes-default-search-engine.mjs.map +1 -1
- package/fesm2022/ng-doc-app-classes-root-page.mjs.map +1 -1
- package/fesm2022/ng-doc-app-classes-search-engine.mjs.map +1 -1
- package/fesm2022/ng-doc-app-classes.mjs +2 -0
- package/fesm2022/ng-doc-app-classes.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-api-list.mjs +173 -69
- package/fesm2022/ng-doc-app-components-api-list.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-breadcrumb.mjs +13 -10
- package/fesm2022/ng-doc-app-components-breadcrumb.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-code.mjs +152 -25
- package/fesm2022/ng-doc-app-components-code.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-command-palette.mjs +498 -0
- package/fesm2022/ng-doc-app-components-command-palette.mjs.map +1 -0
- package/fesm2022/ng-doc-app-components-copy-button.mjs +38 -21
- package/fesm2022/ng-doc-app-components-copy-button.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-demo-displayer.mjs +36 -29
- package/fesm2022/ng-doc-app-components-demo-displayer.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-demo-pane.mjs +39 -36
- package/fesm2022/ng-doc-app-components-demo-pane.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-demo.mjs +129 -44
- package/fesm2022/ng-doc-app-components-demo.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-fullscreen-button.mjs +12 -9
- package/fesm2022/ng-doc-app-components-fullscreen-button.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-fullscreen-toggle.mjs +79 -0
- package/fesm2022/ng-doc-app-components-fullscreen-toggle.mjs.map +1 -0
- package/fesm2022/ng-doc-app-components-heading-anchor.mjs +54 -21
- package/fesm2022/ng-doc-app-components-heading-anchor.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-image-viewer.mjs +183 -89
- package/fesm2022/ng-doc-app-components-image-viewer.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-kind-icon.mjs +42 -25
- package/fesm2022/ng-doc-app-components-kind-icon.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-link.mjs +12 -9
- package/fesm2022/ng-doc-app-components-link.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-members.mjs +30 -0
- package/fesm2022/ng-doc-app-components-members.mjs.map +1 -0
- package/fesm2022/ng-doc-app-components-mermaid-viewer.mjs +61 -20
- package/fesm2022/ng-doc-app-components-mermaid-viewer.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-navbar.mjs +39 -49
- package/fesm2022/ng-doc-app-components-navbar.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-page-header.mjs +73 -10
- package/fesm2022/ng-doc-app-components-page-header.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-page-link.mjs +123 -31
- package/fesm2022/ng-doc-app-components-page-link.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-page-navigation.mjs +17 -19
- package/fesm2022/ng-doc-app-components-page-navigation.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-page-wrapper.mjs +56 -35
- package/fesm2022/ng-doc-app-components-page-wrapper.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-page.mjs +168 -24
- package/fesm2022/ng-doc-app-components-page.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-playground.mjs +392 -263
- package/fesm2022/ng-doc-app-components-playground.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-root.mjs +48 -31
- package/fesm2022/ng-doc-app-components-root.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-search-result.mjs +22 -21
- package/fesm2022/ng-doc-app-components-search-result.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-search.mjs +64 -33
- package/fesm2022/ng-doc-app-components-search.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-sidebar.mjs +86 -61
- package/fesm2022/ng-doc-app-components-sidebar.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-tabs.mjs +18 -12
- package/fesm2022/ng-doc-app-components-tabs.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-theme-toggle.mjs +33 -21
- package/fesm2022/ng-doc-app-components-theme-toggle.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-toc.mjs +267 -90
- package/fesm2022/ng-doc-app-components-toc.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components.mjs +3 -1
- package/fesm2022/ng-doc-app-components.mjs.map +1 -1
- package/fesm2022/ng-doc-app-defaults-default-processors.mjs +2 -1
- package/fesm2022/ng-doc-app-defaults-default-processors.mjs.map +1 -1
- package/fesm2022/ng-doc-app-directives-code-highlighter.mjs +11 -5
- package/fesm2022/ng-doc-app-directives-code-highlighter.mjs.map +1 -1
- package/fesm2022/ng-doc-app-directives-members-filter.mjs +276 -0
- package/fesm2022/ng-doc-app-directives-members-filter.mjs.map +1 -0
- package/fesm2022/ng-doc-app-directives-route-active.mjs +34 -30
- package/fesm2022/ng-doc-app-directives-route-active.mjs.map +1 -1
- package/fesm2022/ng-doc-app-directives.mjs +1 -0
- package/fesm2022/ng-doc-app-directives.mjs.map +1 -1
- package/fesm2022/ng-doc-app-helpers.mjs +285 -1
- package/fesm2022/ng-doc-app-helpers.mjs.map +1 -1
- package/fesm2022/ng-doc-app-pipes-decode-uri-component.mjs +6 -4
- package/fesm2022/ng-doc-app-pipes-decode-uri-component.mjs.map +1 -1
- package/fesm2022/ng-doc-app-pipes-extract-value.mjs +6 -4
- package/fesm2022/ng-doc-app-pipes-extract-value.mjs.map +1 -1
- package/fesm2022/ng-doc-app-pipes-filter-by-text.mjs +7 -4
- package/fesm2022/ng-doc-app-pipes-filter-by-text.mjs.map +1 -1
- package/fesm2022/ng-doc-app-pipes-sanitize-html.mjs +8 -5
- package/fesm2022/ng-doc-app-pipes-sanitize-html.mjs.map +1 -1
- package/fesm2022/ng-doc-app-processors-page-processor.mjs +86 -23
- package/fesm2022/ng-doc-app-processors-page-processor.mjs.map +1 -1
- package/fesm2022/ng-doc-app-processors-processors-tooltip.mjs +26 -25
- package/fesm2022/ng-doc-app-processors-processors-tooltip.mjs.map +1 -1
- package/fesm2022/ng-doc-app-processors-processors.mjs +12 -1
- package/fesm2022/ng-doc-app-processors-processors.mjs.map +1 -1
- package/fesm2022/ng-doc-app-providers-ng-doc-app.mjs +31 -2
- package/fesm2022/ng-doc-app-providers-ng-doc-app.mjs.map +1 -1
- package/fesm2022/ng-doc-app-services-content-scroll-intent.mjs +122 -0
- package/fesm2022/ng-doc-app-services-content-scroll-intent.mjs.map +1 -0
- package/fesm2022/ng-doc-app-services-content-state.mjs +57 -0
- package/fesm2022/ng-doc-app-services-content-state.mjs.map +1 -0
- package/fesm2022/ng-doc-app-services-fullscreen-route.mjs +74 -0
- package/fesm2022/ng-doc-app-services-fullscreen-route.mjs.map +1 -0
- package/fesm2022/ng-doc-app-services-highlighter.mjs +83 -14
- package/fesm2022/ng-doc-app-services-highlighter.mjs.map +1 -1
- package/fesm2022/ng-doc-app-services-route-preloader.mjs +360 -0
- package/fesm2022/ng-doc-app-services-route-preloader.mjs.map +1 -0
- package/fesm2022/ng-doc-app-services-shortcuts.mjs +214 -0
- package/fesm2022/ng-doc-app-services-shortcuts.mjs.map +1 -0
- package/fesm2022/ng-doc-app-services-sidebar.mjs +59 -25
- package/fesm2022/ng-doc-app-services-sidebar.mjs.map +1 -1
- package/fesm2022/ng-doc-app-services-store.mjs +8 -8
- package/fesm2022/ng-doc-app-services-store.mjs.map +1 -1
- package/fesm2022/ng-doc-app-services-theme.mjs +32 -12
- package/fesm2022/ng-doc-app-services-theme.mjs.map +1 -1
- package/fesm2022/ng-doc-app-services.mjs +143 -0
- package/fesm2022/ng-doc-app-services.mjs.map +1 -1
- package/fesm2022/ng-doc-app-tokens.mjs +7 -28
- package/fesm2022/ng-doc-app-tokens.mjs.map +1 -1
- package/fesm2022/ng-doc-app-type-controls-boolean-control.mjs +18 -9
- package/fesm2022/ng-doc-app-type-controls-boolean-control.mjs.map +1 -1
- package/fesm2022/ng-doc-app-type-controls-number-control.mjs +12 -9
- package/fesm2022/ng-doc-app-type-controls-number-control.mjs.map +1 -1
- package/fesm2022/ng-doc-app-type-controls-string-control.mjs +12 -9
- package/fesm2022/ng-doc-app-type-controls-string-control.mjs.map +1 -1
- package/fesm2022/ng-doc-app-type-controls-type-alias-control.mjs +22 -16
- package/fesm2022/ng-doc-app-type-controls-type-alias-control.mjs.map +1 -1
- package/package.json +69 -28
- package/styles/global.css +1125 -201
- package/styles/main.css +1125 -201
- package/styles/themes/dark.css +78 -56
- package/types/ng-doc-app-classes-content-anchor-controller.d.ts +54 -0
- package/types/ng-doc-app-classes-content-controller.d.ts +94 -0
- package/types/ng-doc-app-classes-default-search-engine.d.ts +9 -1
- package/types/ng-doc-app-classes-root-page.d.ts +6 -1
- package/types/ng-doc-app-classes-search-engine.d.ts +5 -0
- package/types/ng-doc-app-classes.d.ts +2 -0
- package/types/ng-doc-app-components-api-list.d.ts +69 -20
- package/types/ng-doc-app-components-breadcrumb.d.ts +8 -3
- package/types/ng-doc-app-components-code.d.ts +46 -12
- package/types/ng-doc-app-components-command-palette.d.ts +147 -0
- package/types/ng-doc-app-components-copy-button.d.ts +18 -6
- package/types/ng-doc-app-components-demo-displayer.d.ts +23 -10
- package/types/ng-doc-app-components-demo-pane.d.ts +19 -15
- package/types/ng-doc-app-components-demo.d.ts +62 -15
- package/types/ng-doc-app-components-fullscreen-button.d.ts +4 -2
- package/types/ng-doc-app-components-fullscreen-toggle.d.ts +24 -0
- package/types/ng-doc-app-components-heading-anchor.d.ts +26 -7
- package/types/ng-doc-app-components-image-viewer.d.ts +71 -7
- package/types/ng-doc-app-components-kind-icon.d.ts +28 -7
- package/types/ng-doc-app-components-link.d.ts +6 -2
- package/types/ng-doc-app-components-members.d.ts +13 -0
- package/types/ng-doc-app-components-mermaid-viewer.d.ts +21 -6
- package/types/ng-doc-app-components-navbar.d.ts +25 -15
- package/types/ng-doc-app-components-page-header.d.ts +28 -4
- package/types/ng-doc-app-components-page-link.d.ts +34 -15
- package/types/ng-doc-app-components-page-navigation.d.ts +10 -5
- package/types/ng-doc-app-components-page-wrapper.d.ts +35 -11
- package/types/ng-doc-app-components-page.d.ts +57 -6
- package/types/ng-doc-app-components-playground.d.ts +146 -78
- package/types/ng-doc-app-components-root.d.ts +28 -7
- package/types/ng-doc-app-components-search-result.d.ts +14 -6
- package/types/ng-doc-app-components-search.d.ts +19 -7
- package/types/ng-doc-app-components-tabs.d.ts +13 -4
- package/types/ng-doc-app-components-theme-toggle.d.ts +18 -5
- package/types/ng-doc-app-components-toc.d.ts +76 -29
- package/types/ng-doc-app-components.d.ts +3 -1
- package/types/ng-doc-app-directives-code-highlighter.d.ts +8 -4
- package/types/ng-doc-app-directives-members-filter.d.ts +61 -0
- package/types/ng-doc-app-directives-route-active.d.ts +21 -7
- package/types/ng-doc-app-directives.d.ts +1 -0
- package/types/ng-doc-app-helpers.d.ts +124 -3
- package/types/ng-doc-app-interfaces.d.ts +48 -28
- package/types/ng-doc-app-pipes-decode-uri-component.d.ts +3 -0
- package/types/ng-doc-app-pipes-extract-value.d.ts +3 -0
- package/types/ng-doc-app-pipes-filter-by-text.d.ts +4 -0
- package/types/ng-doc-app-pipes-sanitize-html.d.ts +4 -2
- package/types/ng-doc-app-processors-page-processor.d.ts +39 -10
- package/types/ng-doc-app-processors-processors-tooltip.d.ts +11 -10
- package/types/ng-doc-app-processors-processors.d.ts +5 -1
- package/types/ng-doc-app-providers-ng-doc-app.d.ts +17 -0
- package/types/ng-doc-app-services-content-scroll-intent.d.ts +52 -0
- package/types/ng-doc-app-services-content-state.d.ts +40 -0
- package/types/ng-doc-app-services-fullscreen-route.d.ts +35 -0
- package/types/ng-doc-app-services-highlighter.d.ts +40 -5
- package/types/ng-doc-app-services-route-preloader.d.ts +109 -0
- package/types/ng-doc-app-services-shortcuts.d.ts +96 -0
- package/types/ng-doc-app-services-sidebar.d.ts +24 -4
- package/types/ng-doc-app-services-store.d.ts +24 -1
- package/types/ng-doc-app-services-theme.d.ts +19 -3
- package/types/ng-doc-app-services.d.ts +77 -0
- package/types/ng-doc-app-tokens.d.ts +10 -30
- package/types/ng-doc-app-type-controls-boolean-control.d.ts +11 -6
- package/types/ng-doc-app-type-controls-number-control.d.ts +5 -3
- package/types/ng-doc-app-type-controls-string-control.d.ts +5 -3
- package/types/ng-doc-app-type-controls-type-alias-control.d.ts +13 -6
- package/fesm2022/ng-doc-app-components-search-dialog.mjs +0 -78
- package/fesm2022/ng-doc-app-components-search-dialog.mjs.map +0 -1
- package/types/ng-doc-app-components-search-dialog.d.ts +0 -28
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import { input, viewChild, ViewContainerRef, signal, inject, Injector, DestroyRef, PendingTasks, ChangeDetectionStrategy, Component, computed, effect, untracked, reflectComponentType, model, output, isDevMode, ChangeDetectorRef, Directive } from '@angular/core';
|
|
3
3
|
import { extractFunctionDefaults } from '@ng-doc/core/helpers/extract-function-defaults';
|
|
4
4
|
import { Subject, take } from 'rxjs';
|
|
5
5
|
import * as i1 from '@angular/forms';
|
|
@@ -7,57 +7,84 @@ import { FormsModule, FormBuilder } from '@angular/forms';
|
|
|
7
7
|
import { NgDocRootPage } from '@ng-doc/app/classes/root-page';
|
|
8
8
|
import { isSameObject } from '@ng-doc/core/helpers/is-same-object';
|
|
9
9
|
import { objectKeys } from '@ng-doc/core/helpers/object-keys';
|
|
10
|
-
import { NgDocLabelComponent, NgDocTooltipDirective,
|
|
10
|
+
import { NgDocLabelComponent, NgDocTooltipDirective, NgDocCheckboxComponent, NgDocIconComponent, NgDocBindPipe, NgDocExecutePipe, NgDocAsArrayPipe } from '@ng-doc/ui-kit';
|
|
11
11
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
12
12
|
import { NgDocDemoDisplayerComponent } from '@ng-doc/app/components/demo-displayer';
|
|
13
13
|
import { formatHtml, isPlaygroundProperty } from '@ng-doc/app/helpers';
|
|
14
14
|
import { getPlaygroundDemoToken } from '@ng-doc/app/providers/playground-demo';
|
|
15
15
|
import { buildPlaygroundDemoPipeTemplate, buildPlaygroundDemoTemplate } from '@ng-doc/core/helpers/build-playground-demo-template';
|
|
16
16
|
import { stringify } from '@ng-doc/core/helpers/stringify';
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import { AsyncPipe, KeyValuePipe } from '@angular/common';
|
|
17
|
+
import { startWith, takeUntil } from 'rxjs/operators';
|
|
18
|
+
import { KeyValuePipe } from '@angular/common';
|
|
20
19
|
import { getTokenForType } from '@ng-doc/app/providers/type-control';
|
|
21
20
|
import { extractValueOrThrow } from '@ng-doc/core/helpers/extract-value';
|
|
22
21
|
import { isPresent } from '@ng-doc/core/helpers/is-present';
|
|
22
|
+
import { NgDocKindIconComponent } from '@ng-doc/app/components/kind-icon';
|
|
23
23
|
import { NgDocSanitizeHtmlPipe } from '@ng-doc/app/pipes';
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* One demo of a playground: it creates the generated playground class of its selector (or pipe),
|
|
27
|
+
* passes it the form's values and shows the code of the current state.
|
|
28
|
+
*/
|
|
25
29
|
class NgDocPlaygroundDemoComponent {
|
|
26
30
|
constructor() {
|
|
27
|
-
|
|
28
|
-
this.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
this.
|
|
32
|
-
|
|
31
|
+
/** The name of the playground in the page configuration. */
|
|
32
|
+
this.id = input('', /* @ts-ignore */
|
|
33
|
+
...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
34
|
+
/** The name of the pipe, when the target is a pipe. */
|
|
35
|
+
this.pipeName = input('', /* @ts-ignore */
|
|
36
|
+
...(ngDevMode ? [{ debugName: "pipeName" }] : /* istanbul ignore next */ []));
|
|
37
|
+
/** The selector of the target this demo renders. */
|
|
38
|
+
this.selector = input('', /* @ts-ignore */
|
|
39
|
+
...(ngDevMode ? [{ debugName: "selector" }] : /* istanbul ignore next */ []));
|
|
40
|
+
/** The playground configuration, extended by the action's options. */
|
|
41
|
+
this.configuration = input(undefined, /* @ts-ignore */
|
|
42
|
+
...(ngDevMode ? [{ debugName: "configuration" }] : /* istanbul ignore next */ []));
|
|
43
|
+
/** The inputs of the target. */
|
|
44
|
+
this.properties = input(undefined, /* @ts-ignore */
|
|
45
|
+
...(ngDevMode ? [{ debugName: "properties" }] : /* istanbul ignore next */ []));
|
|
46
|
+
/** Whether the demo is created again each time a value changes. */
|
|
47
|
+
this.recreateDemo = input(false, /* @ts-ignore */
|
|
48
|
+
...(ngDevMode ? [{ debugName: "recreateDemo" }] : /* istanbul ignore next */ []));
|
|
49
|
+
/** The values of the inputs and content slots. */
|
|
50
|
+
this.form = input(undefined, /* @ts-ignore */
|
|
51
|
+
...(ngDevMode ? [{ debugName: "form" }] : /* istanbul ignore next */ []));
|
|
52
|
+
/** Whether the code of the demo is shown. */
|
|
53
|
+
this.expanded = input(false, /* @ts-ignore */
|
|
54
|
+
...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
|
|
55
|
+
/** Where the playground class is created. */
|
|
56
|
+
this.demoOutlet = viewChild('demoOutlet', { ...(ngDevMode ? { debugName: "demoOutlet" } : /* istanbul ignore next */ {}), read: ViewContainerRef });
|
|
57
|
+
this.code = signal('', /* @ts-ignore */
|
|
58
|
+
...(ngDevMode ? [{ debugName: "code" }] : /* istanbul ignore next */ []));
|
|
33
59
|
this.injector = inject(Injector);
|
|
34
|
-
this.changeDetectorRef = inject(ChangeDetectorRef);
|
|
35
60
|
this.destroyRef = inject(DestroyRef);
|
|
61
|
+
this.pendingTasks = inject(PendingTasks);
|
|
36
62
|
this.unsubscribe$ = new Subject();
|
|
37
63
|
}
|
|
38
64
|
async ngOnChanges({ form, id }) {
|
|
39
65
|
if (form || id) {
|
|
40
66
|
this.unsubscribe$.next();
|
|
41
|
-
const demoInjector = getPlaygroundDemoToken(this.id);
|
|
67
|
+
const demoInjector = getPlaygroundDemoToken(this.id());
|
|
42
68
|
if (demoInjector) {
|
|
43
69
|
const demos = this.injector.get(demoInjector, []);
|
|
44
|
-
this.playgroundDemo = demos.find((demo) => demo.selector === this.selector || demo.selector === this.pipeName);
|
|
70
|
+
this.playgroundDemo = demos.find((demo) => demo.selector === this.selector() || demo.selector === this.pipeName());
|
|
45
71
|
}
|
|
46
72
|
await this.updateDemo();
|
|
47
|
-
this.form
|
|
48
|
-
|
|
73
|
+
const form = this.form();
|
|
74
|
+
form?.valueChanges
|
|
75
|
+
.pipe(startWith(form.value), takeUntil(this.unsubscribe$), takeUntilDestroyed(this.destroyRef))
|
|
49
76
|
.subscribe((data) => this.updateDemo(data));
|
|
50
77
|
}
|
|
51
78
|
}
|
|
52
79
|
async updateDemo(data) {
|
|
53
|
-
if (this.recreateDemo || !this.demoRef) {
|
|
80
|
+
if (this.recreateDemo() || !this.demoRef) {
|
|
54
81
|
this.createDemo();
|
|
55
82
|
}
|
|
56
83
|
if (data) {
|
|
57
84
|
this.demoRef?.setInput('properties', data.properties ?? {});
|
|
58
85
|
this.demoRef?.setInput('content', data.content ?? {});
|
|
59
|
-
this.demoRef?.setInput('actionData', this.configuration?.data ?? {});
|
|
60
|
-
if (this.recreateDemo) {
|
|
86
|
+
this.demoRef?.setInput('actionData', this.configuration()?.data ?? {});
|
|
87
|
+
if (this.recreateDemo()) {
|
|
61
88
|
this.demoRef?.instance.onReattached.subscribe(() => {
|
|
62
89
|
this.demoRef?.changeDetectorRef.detectChanges();
|
|
63
90
|
});
|
|
@@ -68,28 +95,35 @@ class NgDocPlaygroundDemoComponent {
|
|
|
68
95
|
createDemo() {
|
|
69
96
|
if (this.playgroundDemo) {
|
|
70
97
|
this.demoRef?.destroy();
|
|
71
|
-
this.demoRef = this.demoOutlet?.createComponent(this.playgroundDemo);
|
|
98
|
+
this.demoRef = this.demoOutlet()?.createComponent(this.playgroundDemo);
|
|
72
99
|
this.demoRef?.changeDetectorRef.markForCheck();
|
|
73
100
|
}
|
|
74
101
|
}
|
|
75
102
|
async updateCodeView() {
|
|
76
|
-
const template = this.pipeName
|
|
77
|
-
? buildPlaygroundDemoPipeTemplate(this.configuration?.template ?? '', this.pipeName, this.getActiveContent(), this.getPipeActiveInputs())
|
|
78
|
-
: buildPlaygroundDemoTemplate(this.configuration?.template ?? '', this.selector, this.getActiveContent(), this.getActiveInputs());
|
|
79
|
-
|
|
80
|
-
|
|
103
|
+
const template = this.pipeName()
|
|
104
|
+
? buildPlaygroundDemoPipeTemplate(this.configuration()?.template ?? '', this.pipeName(), this.getActiveContent(), this.getPipeActiveInputs())
|
|
105
|
+
: buildPlaygroundDemoTemplate(this.configuration()?.template ?? '', this.selector(), this.getActiveContent(), this.getActiveInputs());
|
|
106
|
+
// Formatting loads the formatter asynchronously. Zoneless SSR waits only for pending tasks, so
|
|
107
|
+
// the page would otherwise be serialized before the code view is filled.
|
|
108
|
+
const done = this.pendingTasks.add();
|
|
109
|
+
try {
|
|
110
|
+
this.code.set(await formatHtml(template));
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
done();
|
|
114
|
+
}
|
|
81
115
|
}
|
|
82
116
|
getActiveContent() {
|
|
83
|
-
const formData = this.form?.controls.content.value ?? {};
|
|
117
|
+
const formData = this.form()?.controls.content.value ?? {};
|
|
84
118
|
return objectKeys(formData).reduce((result, key) => {
|
|
85
|
-
result[key] = formData[key] ? this.configuration?.content?.[key].template ?? '' : '';
|
|
119
|
+
result[key] = formData[key] ? this.configuration()?.content?.[key].template ?? '' : '';
|
|
86
120
|
return result;
|
|
87
121
|
}, {});
|
|
88
122
|
}
|
|
89
123
|
getActiveInputs() {
|
|
90
|
-
const formData = this.form?.controls.properties.value ?? {};
|
|
124
|
+
const formData = this.form()?.controls.properties.value ?? {};
|
|
91
125
|
return objectKeys(formData).reduce((result, key) => {
|
|
92
|
-
const inputName = this.properties?.[key]?.inputName ?? key;
|
|
126
|
+
const inputName = this.properties()?.[key]?.inputName ?? key;
|
|
93
127
|
const value = formData[key];
|
|
94
128
|
const property = this.demoRef?.instance?.defaultValues[key];
|
|
95
129
|
if (property !== value) {
|
|
@@ -99,7 +133,7 @@ class NgDocPlaygroundDemoComponent {
|
|
|
99
133
|
}, {});
|
|
100
134
|
}
|
|
101
135
|
getPipeActiveInputs() {
|
|
102
|
-
const formData = this.form?.controls.properties.value ?? {};
|
|
136
|
+
const formData = this.form()?.controls.properties.value ?? {};
|
|
103
137
|
let changedInputIndex = -1;
|
|
104
138
|
return objectKeys(formData)
|
|
105
139
|
.map((key, i) => {
|
|
@@ -120,128 +154,208 @@ class NgDocPlaygroundDemoComponent {
|
|
|
120
154
|
this.unsubscribe$.next();
|
|
121
155
|
this.unsubscribe$.complete();
|
|
122
156
|
}
|
|
123
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
124
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
157
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPlaygroundDemoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
158
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.2.1", type: NgDocPlaygroundDemoComponent, isStandalone: true, selector: "ng-doc-playground-demo", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, pipeName: { classPropertyName: "pipeName", publicName: "pipeName", isSignal: true, isRequired: false, transformFunction: null }, selector: { classPropertyName: "selector", publicName: "selector", isSignal: true, isRequired: false, transformFunction: null }, configuration: { classPropertyName: "configuration", publicName: "configuration", isSignal: true, isRequired: false, transformFunction: null }, properties: { classPropertyName: "properties", publicName: "properties", isSignal: true, isRequired: false, transformFunction: null }, recreateDemo: { classPropertyName: "recreateDemo", publicName: "recreateDemo", isSignal: true, isRequired: false, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "demoOutlet", first: true, predicate: ["demoOutlet"], descendants: true, read: ViewContainerRef, isSignal: true }], usesOnChanges: true, ngImport: i0, template: "<ng-doc-demo-displayer\n [code]=\"code()\"\n [border]=\"false\"\n [expanded]=\"expanded()\"\n language=\"angular-html\">\n <ng-container #demoOutlet></ng-container>\n</ng-doc-demo-displayer>\n", styles: [":host{display:flex;flex-direction:column}ng-doc-demo-displayer{flex:1 1 auto}\n"], dependencies: [{ kind: "component", type: NgDocDemoDisplayerComponent, selector: "ng-doc-demo-displayer", inputs: ["codeContent", "code", "language", "container", "border", "expanded"], outputs: ["expandedChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
125
159
|
}
|
|
126
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
160
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPlaygroundDemoComponent, decorators: [{
|
|
127
161
|
type: Component,
|
|
128
|
-
args: [{ selector: 'ng-doc-playground-demo', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgDocDemoDisplayerComponent], template: "<ng-doc-demo-displayer
|
|
129
|
-
}], propDecorators: { id: [{
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
type: Input
|
|
133
|
-
}], selector: [{
|
|
134
|
-
type: Input
|
|
135
|
-
}], configuration: [{
|
|
136
|
-
type: Input
|
|
137
|
-
}], properties: [{
|
|
138
|
-
type: Input
|
|
139
|
-
}], recreateDemo: [{
|
|
140
|
-
type: Input
|
|
141
|
-
}], form: [{
|
|
142
|
-
type: Input
|
|
143
|
-
}], expanded: [{
|
|
144
|
-
type: Input
|
|
145
|
-
}], demoOutlet: [{
|
|
146
|
-
type: ViewChild,
|
|
147
|
-
args: ['demoOutlet', { static: true, read: ViewContainerRef }]
|
|
148
|
-
}] } });
|
|
162
|
+
args: [{ selector: 'ng-doc-playground-demo', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgDocDemoDisplayerComponent], template: "<ng-doc-demo-displayer\n [code]=\"code()\"\n [border]=\"false\"\n [expanded]=\"expanded()\"\n language=\"angular-html\">\n <ng-container #demoOutlet></ng-container>\n</ng-doc-demo-displayer>\n", styles: [":host{display:flex;flex-direction:column}ng-doc-demo-displayer{flex:1 1 auto}\n"] }]
|
|
163
|
+
}], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], pipeName: [{ type: i0.Input, args: [{ isSignal: true, alias: "pipeName", required: false }] }], selector: [{ type: i0.Input, args: [{ isSignal: true, alias: "selector", required: false }] }], configuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "configuration", required: false }] }], properties: [{ type: i0.Input, args: [{ isSignal: true, alias: "properties", required: false }] }], recreateDemo: [{ type: i0.Input, args: [{ isSignal: true, alias: "recreateDemo", required: false }] }], form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: false }] }], expanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "expanded", required: false }] }], demoOutlet: [{ type: i0.ViewChild, args: ['demoOutlet', { ...{
|
|
164
|
+
read: ViewContainerRef,
|
|
165
|
+
}, isSignal: true }] }] } });
|
|
149
166
|
|
|
167
|
+
/** Value types that have a chip colour. */
|
|
168
|
+
const CHIP_TYPES = new Set([
|
|
169
|
+
'string',
|
|
170
|
+
'number',
|
|
171
|
+
'boolean',
|
|
172
|
+
'object',
|
|
173
|
+
'null',
|
|
174
|
+
'undefined',
|
|
175
|
+
]);
|
|
176
|
+
/**
|
|
177
|
+
* One row of the playground inspector: the input's name with its type chip, and the type
|
|
178
|
+
* control that edits it, bound to the input's form control.
|
|
179
|
+
*/
|
|
150
180
|
class NgDocPlaygroundPropertyComponent {
|
|
151
181
|
constructor() {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
182
|
+
/** Name of the input. */
|
|
183
|
+
this.name = input('', /* @ts-ignore */
|
|
184
|
+
...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
|
|
185
|
+
/** The input, or the content slot. */
|
|
186
|
+
this.property = input(undefined, /* @ts-ignore */
|
|
187
|
+
...(ngDevMode ? [{ debugName: "property" }] : /* istanbul ignore next */ []));
|
|
188
|
+
/** The type control that edits the input. */
|
|
189
|
+
this.typeControl = input(undefined, /* @ts-ignore */
|
|
190
|
+
...(ngDevMode ? [{ debugName: "typeControl" }] : /* istanbul ignore next */ []));
|
|
191
|
+
/** Form control of the input. */
|
|
192
|
+
this.control = input(undefined, /* @ts-ignore */
|
|
193
|
+
...(ngDevMode ? [{ debugName: "control" }] : /* istanbul ignore next */ []));
|
|
194
|
+
/** Default value of the input. */
|
|
195
|
+
this.defaultValue = input(undefined, /* @ts-ignore */
|
|
196
|
+
...(ngDevMode ? [{ debugName: "defaultValue" }] : /* istanbul ignore next */ []));
|
|
197
|
+
/** Whether a type control is rendered. */
|
|
198
|
+
this.hasPropertyControl = signal(false, /* @ts-ignore */
|
|
199
|
+
...(ngDevMode ? [{ debugName: "hasPropertyControl" }] : /* istanbul ignore next */ []));
|
|
200
|
+
/** Description of the input, shown in the tooltip of its name. */
|
|
201
|
+
this.tooltipContent = computed(() => {
|
|
202
|
+
const property = this.property();
|
|
203
|
+
return property && isPlaygroundProperty(property) ? property.description ?? '' : '';
|
|
204
|
+
}, /* @ts-ignore */
|
|
205
|
+
...(ngDevMode ? [{ debugName: "tooltipContent" }] : /* istanbul ignore next */ []));
|
|
206
|
+
/** Options of the type control provider. */
|
|
207
|
+
this.option = computed(() => this.typeControl()?.options, /* @ts-ignore */
|
|
208
|
+
...(ngDevMode ? [{ debugName: "option" }] : /* istanbul ignore next */ []));
|
|
209
|
+
/** The value type shown as a chip under the name, or an empty string. */
|
|
210
|
+
this.typeChip = computed(() => valueType(this.property()), /* @ts-ignore */
|
|
211
|
+
...(ngDevMode ? [{ debugName: "typeChip" }] : /* istanbul ignore next */ []));
|
|
212
|
+
this.propertyOutlet = viewChild.required('propertyOutlet', { ...(ngDevMode ? { debugName: "propertyOutlet" } : /* istanbul ignore next */ {}), read: ViewContainerRef });
|
|
213
|
+
// A plain effect, not an after-render hook: it runs during change detection on the server
|
|
214
|
+
// too, so server-rendered and prerendered pages include the controls. The outlet is a static
|
|
215
|
+
// node of this view, so it exists by then. It runs again only when an input it reads changes.
|
|
216
|
+
effect(() => {
|
|
217
|
+
const property = this.property();
|
|
218
|
+
const typeControl = this.typeControl();
|
|
219
|
+
const control = this.control();
|
|
220
|
+
const defaultValue = this.defaultValue();
|
|
221
|
+
untracked(() => this.createControl(property, typeControl, control, defaultValue));
|
|
222
|
+
});
|
|
223
|
+
inject(DestroyRef).onDestroy(() => this.propertyTypeControl?.destroy());
|
|
224
|
+
}
|
|
225
|
+
createControl(property, typeControl, formControl, defaultValue) {
|
|
226
|
+
if (!property || !typeControl) {
|
|
227
|
+
return;
|
|
177
228
|
}
|
|
229
|
+
this.propertyTypeControl?.destroy();
|
|
230
|
+
const control = this.propertyOutlet().createComponent(typeControl.control);
|
|
231
|
+
this.propertyTypeControl = control;
|
|
232
|
+
setTypeControlField(control, 'name', this.name());
|
|
233
|
+
setTypeControlField(control, 'description', this.tooltipContent());
|
|
234
|
+
setTypeControlField(control, 'options', isPlaygroundProperty(property) ? property.options : undefined);
|
|
235
|
+
setTypeControlField(control, 'default', defaultValue);
|
|
236
|
+
setTypeControlField(control, 'isManual', isPlaygroundProperty(property) ? property.isManual : undefined);
|
|
237
|
+
control.instance.writeValue(formControl?.value);
|
|
238
|
+
if (formControl) {
|
|
239
|
+
formControl.registerOnChange((value) => control.instance.writeValue(value));
|
|
240
|
+
control.instance.registerOnChange((value) => formControl.setValue(value));
|
|
241
|
+
control.instance.registerOnTouched(() => formControl.markAsTouched());
|
|
242
|
+
}
|
|
243
|
+
this.hasPropertyControl.set(true);
|
|
178
244
|
}
|
|
179
|
-
|
|
180
|
-
|
|
245
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPlaygroundPropertyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
246
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.1", type: NgDocPlaygroundPropertyComponent, isStandalone: true, selector: "ng-doc-playground-property", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, property: { classPropertyName: "property", publicName: "property", isSignal: true, isRequired: false, transformFunction: null }, typeControl: { classPropertyName: "typeControl", publicName: "typeControl", isSignal: true, isRequired: false, transformFunction: null }, control: { classPropertyName: "control", publicName: "control", isSignal: true, isRequired: false, transformFunction: null }, defaultValue: { classPropertyName: "defaultValue", publicName: "defaultValue", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-has-property-control": "hasPropertyControl()" } }, viewQueries: [{ propertyName: "propertyOutlet", first: true, predicate: ["propertyOutlet"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: "<label\n class=\"ng-doc-playground-property-label\"\n [class.with-label]=\"!option()?.hideLabel\"\n [ng-doc-label]=\"option()?.hideLabel ? '' : labelContent\">\n <ng-template #labelContent>\n <span\n class=\"ng-doc-playground-property-name\"\n [ngDocTooltip]=\"tooltipTemplate\"\n [canOpen]=\"!!tooltipContent()\"\n [positions]=\"['left-center', 'top-right', 'bottom-right']\"\n >{{ name() }}</span\n >\n @if (typeChip(); as type) {\n <ng-doc-kind-icon [kind]=\"type\" type=\"type\"></ng-doc-kind-icon>\n }\n <ng-template #tooltipTemplate>\n <div [innerHTML]=\"tooltipContent() | ngDocSanitizeHtml\"></div>\n </ng-template>\n </ng-template>\n <ng-container #propertyOutlet></ng-container>\n</label>\n", styles: [":host{display:block}:host[data-has-property-control=false]{display:none}.ng-doc-playground-property-label.with-label{display:grid;grid-template-columns:84px minmax(0,1fr);align-items:center;gap:var(--ng-doc-space-3)}.ng-doc-playground-property-label.with-label ::ng-deep>.ng-doc-label{display:grid;justify-items:start;gap:var(--ng-doc-space-1);min-width:0;margin:0}.ng-doc-playground-property-label.with-label ::ng-deep>.ng-doc-content{width:100%;min-width:0}.ng-doc-playground-property-name{max-width:100%;overflow:hidden;text-overflow:ellipsis;font-family:var(--ng-doc-code-font);font-size:13px;line-height:18px;font-weight:500;color:var(--ng-doc-heading-color)}\n"], dependencies: [{ kind: "component", type: NgDocLabelComponent, selector: "label[ng-doc-label]", inputs: ["ng-doc-label", "align"] }, { kind: "directive", type: NgDocTooltipDirective, selector: "[ngDocTooltip]", inputs: ["ngDocTooltip", "delay", "displayOrigin", "pointerOrigin", "positions", "canOpen", "panelClass", "minHeight", "maxHeight", "height", "minWidth", "maxWidth", "width"], outputs: ["beforeOpen", "afterOpen", "beforeClose", "afterClose"], exportAs: ["ngDocTooltip"] }, { kind: "component", type: NgDocKindIconComponent, selector: "ng-doc-kind-icon", inputs: ["kind", "type", "size"] }, { kind: "pipe", type: NgDocSanitizeHtmlPipe, name: "ngDocSanitizeHtml" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
247
|
+
}
|
|
248
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPlaygroundPropertyComponent, decorators: [{
|
|
249
|
+
type: Component,
|
|
250
|
+
args: [{ selector: 'ng-doc-playground-property', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
251
|
+
NgDocLabelComponent,
|
|
252
|
+
NgDocTooltipDirective,
|
|
253
|
+
NgDocSanitizeHtmlPipe,
|
|
254
|
+
NgDocKindIconComponent,
|
|
255
|
+
], host: {
|
|
256
|
+
'[attr.data-has-property-control]': 'hasPropertyControl()',
|
|
257
|
+
}, template: "<label\n class=\"ng-doc-playground-property-label\"\n [class.with-label]=\"!option()?.hideLabel\"\n [ng-doc-label]=\"option()?.hideLabel ? '' : labelContent\">\n <ng-template #labelContent>\n <span\n class=\"ng-doc-playground-property-name\"\n [ngDocTooltip]=\"tooltipTemplate\"\n [canOpen]=\"!!tooltipContent()\"\n [positions]=\"['left-center', 'top-right', 'bottom-right']\"\n >{{ name() }}</span\n >\n @if (typeChip(); as type) {\n <ng-doc-kind-icon [kind]=\"type\" type=\"type\"></ng-doc-kind-icon>\n }\n <ng-template #tooltipTemplate>\n <div [innerHTML]=\"tooltipContent() | ngDocSanitizeHtml\"></div>\n </ng-template>\n </ng-template>\n <ng-container #propertyOutlet></ng-container>\n</label>\n", styles: [":host{display:block}:host[data-has-property-control=false]{display:none}.ng-doc-playground-property-label.with-label{display:grid;grid-template-columns:84px minmax(0,1fr);align-items:center;gap:var(--ng-doc-space-3)}.ng-doc-playground-property-label.with-label ::ng-deep>.ng-doc-label{display:grid;justify-items:start;gap:var(--ng-doc-space-1);min-width:0;margin:0}.ng-doc-playground-property-label.with-label ::ng-deep>.ng-doc-content{width:100%;min-width:0}.ng-doc-playground-property-name{max-width:100%;overflow:hidden;text-overflow:ellipsis;font-family:var(--ng-doc-code-font);font-size:13px;line-height:18px;font-weight:500;color:var(--ng-doc-heading-color)}\n"] }]
|
|
258
|
+
}], ctorParameters: () => [], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], property: [{ type: i0.Input, args: [{ isSignal: true, alias: "property", required: false }] }], typeControl: [{ type: i0.Input, args: [{ isSignal: true, alias: "typeControl", required: false }] }], control: [{ type: i0.Input, args: [{ isSignal: true, alias: "control", required: false }] }], defaultValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValue", required: false }] }], propertyOutlet: [{ type: i0.ViewChild, args: ['propertyOutlet', { ...{
|
|
259
|
+
read: ViewContainerRef,
|
|
260
|
+
}, isSignal: true }] }] } });
|
|
261
|
+
/**
|
|
262
|
+
* The value type of an input: its declared type when it is a primitive, else the type of the first
|
|
263
|
+
* value of its type alias. Content slots are booleans.
|
|
264
|
+
* @param property - The input or the content slot.
|
|
265
|
+
*/
|
|
266
|
+
function valueType(property) {
|
|
267
|
+
if (!property) {
|
|
268
|
+
return '';
|
|
269
|
+
}
|
|
270
|
+
if (!isPlaygroundProperty(property)) {
|
|
271
|
+
return 'boolean';
|
|
181
272
|
}
|
|
182
|
-
|
|
183
|
-
return
|
|
184
|
-
|
|
185
|
-
|
|
273
|
+
if (CHIP_TYPES.has(property.type)) {
|
|
274
|
+
return property.type;
|
|
275
|
+
}
|
|
276
|
+
const option = property.options?.[0];
|
|
277
|
+
if (option !== undefined) {
|
|
278
|
+
try {
|
|
279
|
+
const type = typeof (property.isManual ? option : extractValueOrThrow(option));
|
|
280
|
+
return CHIP_TYPES.has(type) ? type : '';
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
return '';
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return '';
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Sets a field of a type control: through `ComponentRef.setInput()` when the control declares it
|
|
290
|
+
* as an input (a signal input or a decorator input), otherwise by assigning the plain field.
|
|
291
|
+
* @param control - The created type control.
|
|
292
|
+
* @param field - Name of the field.
|
|
293
|
+
* @param value - Value to set.
|
|
294
|
+
*/
|
|
295
|
+
function setTypeControlField(control, field, value) {
|
|
296
|
+
const input = reflectComponentType(control.componentType)?.inputs.find(({ propName }) => propName === field);
|
|
297
|
+
if (input) {
|
|
298
|
+
control.setInput(input.templateName, value);
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
control.instance[field] = value;
|
|
186
302
|
}
|
|
187
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgDocPlaygroundPropertyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
188
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: NgDocPlaygroundPropertyComponent, isStandalone: true, selector: "ng-doc-playground-property", inputs: { name: "name", property: "property", typeControl: "typeControl", control: "control", defaultValue: "defaultValue" }, host: { properties: { "attr.data-has-property-control": "this.hasPropertyControl" } }, viewQueries: [{ propertyName: "propertyOutlet", first: true, predicate: ["propertyOutlet"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: "<label [ng-doc-label]=\"option?.hideLabel ? '' : labelContent\">\n\t<ng-template #labelContent>\n\t\t<span\n\t\t\t[ngDocTooltip]=\"tooltipTemplate\"\n\t\t\t[canOpen]=\"!!tooltipContent\"\n\t\t\t[positions]=\"['left-center', 'top-right', 'bottom-right']\"\n\t\t\t>{{ name }}</span\n\t\t>\n\t\t<ng-template #tooltipTemplate>\n\t\t\t<div [innerHTML]=\"tooltipContent | ngDocSanitizeHtml\"></div>\n\t\t</ng-template>\n\t</ng-template>\n\t<ng-container #propertyOutlet></ng-container>\n</label>\n", styles: [":host{display:block}:host[data-has-property-control=false]{display:none}\n"], dependencies: [{ kind: "component", type: NgDocLabelComponent, selector: "label[ng-doc-label]", inputs: ["ng-doc-label", "align"] }, { kind: "directive", type: NgDocTooltipDirective, selector: "[ngDocTooltip]", inputs: ["ngDocTooltip", "delay", "displayOrigin", "pointerOrigin", "positions", "canOpen", "panelClass", "minHeight", "maxHeight", "height", "minWidth", "maxWidth", "width"], outputs: ["beforeOpen", "afterOpen", "beforeClose", "afterClose"], exportAs: ["ngDocTooltip"] }, { kind: "pipe", type: NgDocSanitizeHtmlPipe, name: "ngDocSanitizeHtml" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
189
303
|
}
|
|
190
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgDocPlaygroundPropertyComponent, decorators: [{
|
|
191
|
-
type: Component,
|
|
192
|
-
args: [{ selector: 'ng-doc-playground-property', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgDocLabelComponent, NgDocTooltipDirective, NgDocSanitizeHtmlPipe], template: "<label [ng-doc-label]=\"option?.hideLabel ? '' : labelContent\">\n\t<ng-template #labelContent>\n\t\t<span\n\t\t\t[ngDocTooltip]=\"tooltipTemplate\"\n\t\t\t[canOpen]=\"!!tooltipContent\"\n\t\t\t[positions]=\"['left-center', 'top-right', 'bottom-right']\"\n\t\t\t>{{ name }}</span\n\t\t>\n\t\t<ng-template #tooltipTemplate>\n\t\t\t<div [innerHTML]=\"tooltipContent | ngDocSanitizeHtml\"></div>\n\t\t</ng-template>\n\t</ng-template>\n\t<ng-container #propertyOutlet></ng-container>\n</label>\n", styles: [":host{display:block}:host[data-has-property-control=false]{display:none}\n"] }]
|
|
193
|
-
}], propDecorators: { name: [{
|
|
194
|
-
type: Input
|
|
195
|
-
}], property: [{
|
|
196
|
-
type: Input
|
|
197
|
-
}], typeControl: [{
|
|
198
|
-
type: Input
|
|
199
|
-
}], control: [{
|
|
200
|
-
type: Input
|
|
201
|
-
}], defaultValue: [{
|
|
202
|
-
type: Input
|
|
203
|
-
}], propertyOutlet: [{
|
|
204
|
-
type: ViewChild,
|
|
205
|
-
args: ['propertyOutlet', { read: ViewContainerRef, static: true }]
|
|
206
|
-
}], hasPropertyControl: [{
|
|
207
|
-
type: HostBinding,
|
|
208
|
-
args: ['attr.data-has-property-control']
|
|
209
|
-
}] } });
|
|
210
304
|
|
|
305
|
+
/**
|
|
306
|
+
* Orders inputs without an `order` by name in English whatever the locale, so a prerendered
|
|
307
|
+
* playground does not depend on the machine that built it.
|
|
308
|
+
*/
|
|
309
|
+
const INPUT_ORDER = new Intl.Collator('en');
|
|
310
|
+
/**
|
|
311
|
+
* The playground inspector: the demos, and beside them (below them in a container narrower than
|
|
312
|
+
* 640px) the Recreate setting and a control per input and content slot.
|
|
313
|
+
*/
|
|
211
314
|
class NgDocPlaygroundPropertiesComponent {
|
|
212
315
|
constructor() {
|
|
213
|
-
this.breakpointObserver = inject(BreakpointObserver);
|
|
214
316
|
this.injector = inject(Injector);
|
|
215
|
-
|
|
216
|
-
this.
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
this.
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
this.
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
317
|
+
/** The form of the playground. */
|
|
318
|
+
this.form = input.required(/* @ts-ignore */
|
|
319
|
+
...(ngDevMode ? [{ debugName: "form" }] : /* istanbul ignore next */ []));
|
|
320
|
+
/** The inputs of the playground's target. */
|
|
321
|
+
this.properties = input(undefined, /* @ts-ignore */
|
|
322
|
+
...(ngDevMode ? [{ debugName: "properties" }] : /* istanbul ignore next */ []));
|
|
323
|
+
/** Inputs that get no control. */
|
|
324
|
+
this.ignoreInputs = input([], /* @ts-ignore */
|
|
325
|
+
...(ngDevMode ? [{ debugName: "ignoreInputs" }] : /* istanbul ignore next */ []));
|
|
326
|
+
/** Content slots of the playground. */
|
|
327
|
+
this.dynamicContent = input(undefined, /* @ts-ignore */
|
|
328
|
+
...(ngDevMode ? [{ debugName: "dynamicContent" }] : /* istanbul ignore next */ []));
|
|
329
|
+
/** Default values of the inputs; the inspector renders once they are known. */
|
|
330
|
+
this.defaultValues = input(undefined, /* @ts-ignore */
|
|
331
|
+
...(ngDevMode ? [{ debugName: "defaultValues" }] : /* istanbul ignore next */ []));
|
|
332
|
+
/** Whether the inspector is hidden, leaving the demos only. */
|
|
333
|
+
this.hideSidePanel = input(false, /* @ts-ignore */
|
|
334
|
+
...(ngDevMode ? [{ debugName: "hideSidePanel" }] : /* istanbul ignore next */ []));
|
|
335
|
+
/** Where the inspector goes: right of the demos, or below them at full width. */
|
|
336
|
+
this.inspectorPosition = input('right', /* @ts-ignore */
|
|
337
|
+
...(ngDevMode ? [{ debugName: "inspectorPosition" }] : /* istanbul ignore next */ []));
|
|
338
|
+
/** Whether the demo is recreated each time an input changes. */
|
|
339
|
+
this.recreateDemo = model(false, /* @ts-ignore */
|
|
340
|
+
...(ngDevMode ? [{ debugName: "recreateDemo" }] : /* istanbul ignore next */ []));
|
|
341
|
+
/** Whether the Reset button is shown. */
|
|
342
|
+
this.showResetButton = input(false, /* @ts-ignore */
|
|
343
|
+
...(ngDevMode ? [{ debugName: "showResetButton" }] : /* istanbul ignore next */ []));
|
|
344
|
+
/** Emits when the reader resets the form. */
|
|
345
|
+
this.resetForm = output();
|
|
346
|
+
/** The control of each input, in display order. */
|
|
347
|
+
this.propertyControls = computed(() => {
|
|
348
|
+
const properties = this.properties();
|
|
349
|
+
const ignoreInputs = this.ignoreInputs();
|
|
350
|
+
if (!properties) {
|
|
351
|
+
return [];
|
|
352
|
+
}
|
|
353
|
+
return objectKeys(properties)
|
|
354
|
+
.filter((key) => ignoreInputs?.includes(String(key)) !== true)
|
|
232
355
|
.map((key) => {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
if (typeControl) {
|
|
237
|
-
return {
|
|
238
|
-
propertyName: String(key),
|
|
239
|
-
property,
|
|
240
|
-
typeControl,
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
return null;
|
|
356
|
+
const property = properties[key];
|
|
357
|
+
const typeControl = this.getTypeControl(property);
|
|
358
|
+
return typeControl ? { propertyName: String(key), property, typeControl } : null;
|
|
245
359
|
})
|
|
246
360
|
.filter(isPresent)
|
|
247
361
|
.sort((a, b) => {
|
|
@@ -256,16 +370,26 @@ class NgDocPlaygroundPropertiesComponent {
|
|
|
256
370
|
if (isPresent(bOrder)) {
|
|
257
371
|
return 1;
|
|
258
372
|
}
|
|
259
|
-
return a.property.inputName
|
|
373
|
+
return INPUT_ORDER.compare(a.property.inputName, b.property.inputName);
|
|
260
374
|
});
|
|
261
|
-
}
|
|
375
|
+
}, /* @ts-ignore */
|
|
376
|
+
...(ngDevMode ? [{ debugName: "propertyControls" }] : /* istanbul ignore next */ []));
|
|
377
|
+
/** The control of content slots. */
|
|
378
|
+
this.contentTypeControl = this.getControlForType('boolean');
|
|
262
379
|
}
|
|
380
|
+
/**
|
|
381
|
+
* The form control of an input or a content slot.
|
|
382
|
+
* @param controlType - `properties` or `content`.
|
|
383
|
+
* @param key - Name of the input or slot.
|
|
384
|
+
*/
|
|
263
385
|
getFormControl(controlType, key) {
|
|
264
|
-
return this.form.get(controlType)?.get(key);
|
|
386
|
+
return this.form().get(controlType)?.get(key);
|
|
265
387
|
}
|
|
266
388
|
getTypeControl(property) {
|
|
267
389
|
const type = property.type;
|
|
390
|
+
const primitive = optionalPrimitive(type);
|
|
268
391
|
const typeControl = this.getControlForType(type) ??
|
|
392
|
+
(primitive ? this.getControlForType(primitive) : undefined) ??
|
|
269
393
|
this.getControlForTypeAlias(isPlaygroundProperty(property) ? property.options : undefined, property.isManual);
|
|
270
394
|
if (!typeControl && isDevMode()) {
|
|
271
395
|
console.warn(`NgDocPlayground didn't find the control for the @Input "${property.inputName}", the type "${type}" was not recognized'`);
|
|
@@ -295,211 +419,216 @@ class NgDocPlaygroundPropertiesComponent {
|
|
|
295
419
|
}
|
|
296
420
|
return undefined;
|
|
297
421
|
}
|
|
298
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
299
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.
|
|
422
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPlaygroundPropertiesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
423
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.1", type: NgDocPlaygroundPropertiesComponent, isStandalone: true, selector: "ng-doc-playground-properties", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null }, properties: { classPropertyName: "properties", publicName: "properties", isSignal: true, isRequired: false, transformFunction: null }, ignoreInputs: { classPropertyName: "ignoreInputs", publicName: "ignoreInputs", isSignal: true, isRequired: false, transformFunction: null }, dynamicContent: { classPropertyName: "dynamicContent", publicName: "dynamicContent", isSignal: true, isRequired: false, transformFunction: null }, defaultValues: { classPropertyName: "defaultValues", publicName: "defaultValues", isSignal: true, isRequired: false, transformFunction: null }, hideSidePanel: { classPropertyName: "hideSidePanel", publicName: "hideSidePanel", isSignal: true, isRequired: false, transformFunction: null }, inspectorPosition: { classPropertyName: "inspectorPosition", publicName: "inspectorPosition", isSignal: true, isRequired: false, transformFunction: null }, recreateDemo: { classPropertyName: "recreateDemo", publicName: "recreateDemo", isSignal: true, isRequired: false, transformFunction: null }, showResetButton: { classPropertyName: "showResetButton", publicName: "showResetButton", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { recreateDemo: "recreateDemoChange", resetForm: "resetForm" }, ngImport: i0, template: "@if (defaultValues(); as defaultValues) {\n <div\n class=\"ng-doc-playground-properties-wrapper\"\n [class.no-side-panel]=\"hideSidePanel()\"\n [class.inspector-bottom]=\"inspectorPosition() === 'bottom'\">\n <div class=\"ng-doc-playground-demos\">\n <ng-content></ng-content>\n </div>\n @if (!hideSidePanel()) {\n <div class=\"ng-doc-playground-properties\">\n <div class=\"ng-doc-playground-header\">\n <h4>Playground</h4>\n @if (showResetButton()) {\n <button type=\"button\" class=\"ng-doc-playground-reset\" (click)=\"resetForm.emit()\">\n Reset\n </button>\n }\n </div>\n <div class=\"ng-doc-playground-setting\">\n <ng-doc-checkbox [ngModel]=\"recreateDemo()\" (ngModelChange)=\"recreateDemo.set($event)\">\n Recreate\n </ng-doc-checkbox>\n <ng-doc-icon\n class=\"ng-doc-playground-info\"\n icon=\"info\"\n role=\"img\"\n aria-label=\"Recreates the demo every time one of the inputs changes\"\n [ngDocTooltip]=\"'Recreates the demo every time one of the inputs changes'\"\n [positions]=\"['bottom-right', 'left-center']\"></ng-doc-icon>\n </div>\n <div class=\"ng-doc-playground-divider\"></div>\n @if (propertyControls().length) {\n <h5 class=\"ng-doc-title\">Settings</h5>\n <div class=\"ng-doc-playground-property-list\">\n @for (propertyControl of propertyControls(); track propertyControl.propertyName) {\n <ng-doc-playground-property\n [name]=\"propertyControl.property.inputName\"\n [property]=\"propertyControl.property\"\n [typeControl]=\"propertyControl.typeControl\"\n [defaultValue]=\"defaultValues[propertyControl.propertyName]\"\n [control]=\"\n getFormControl | bind: this | execute: 'properties' : propertyControl.propertyName\n \">\n </ng-doc-playground-property>\n }\n </div>\n }\n @if ((dynamicContent() | keyvalue)?.length) {\n <h5 class=\"ng-doc-title\">Content</h5>\n <div class=\"ng-doc-playground-property-list\">\n @for (content of dynamicContent() | keyvalue; track content.key) {\n <ng-doc-playground-property\n [name]=\"content.value.label\"\n [property]=\"content.value\"\n [typeControl]=\"contentTypeControl\"\n [control]=\"getFormControl | bind: this | execute: 'content' : content.key\">\n </ng-doc-playground-property>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;container:ng-doc-playground/inline-size}.ng-doc-playground-properties-wrapper{display:grid;grid-template-columns:minmax(0,1fr) var(--ng-doc-playground-inspector-width);align-items:stretch;border:var(--ng-doc-demo-displayer-border);border-radius:var(--ng-doc-demo-displayer-border-radius);overflow:clip;background-color:var(--ng-doc-demo-displayer-background, var(--ng-doc-background))}.ng-doc-playground-properties-wrapper.no-side-panel{grid-template-columns:minmax(0,1fr)}.ng-doc-playground-properties-wrapper:not(.no-side-panel):not(.inspector-bottom) .ng-doc-playground-demos{position:sticky;top:calc(var(--ng-doc-page-sticky-offset) + var(--ng-doc-base-gutter));align-self:start;z-index:4}.ng-doc-playground-demos{display:flex;flex-direction:column;min-width:0}.ng-doc-playground-properties-wrapper:not(.no-side-panel):not(.inspector-bottom) .ng-doc-playground-demos{min-height:min(100%,100dvh - var(--ng-doc-page-sticky-offset) - 2 * var(--ng-doc-base-gutter))}.ng-doc-playground-properties{min-width:0;background:var(--ng-doc-base-1);border-left:1px solid var(--ng-doc-border-color);font-family:var(--ng-doc-font-family);font-size:14px;line-height:20px;color:var(--ng-doc-text);--ng-doc-input-height: 36px;--ng-doc-input-border: var(--ng-doc-playground-input-border);--ng-doc-checkbox-border: var(--ng-doc-playground-input-border)}.ng-doc-playground-header{display:flex;align-items:center;gap:var(--ng-doc-space-2);height:52px;padding:0 var(--ng-doc-space-3) 0 var(--ng-doc-space-4)}.ng-doc-playground-header h4{margin:0;font-family:var(--ng-doc-heading-font-family);font-size:15px;line-height:22px;font-weight:600;letter-spacing:0;color:var(--ng-doc-heading-color)}.ng-doc-playground-reset{display:inline-flex;align-items:center;height:28px;margin-left:auto;padding:0 10px;border:1px solid var(--ng-doc-border-color);border-radius:var(--ng-doc-radius-md);background:var(--ng-doc-background);font:inherit;font-size:12px;font-weight:500;color:var(--ng-doc-heading-color);cursor:pointer}.ng-doc-playground-reset:hover{border-color:var(--ng-doc-border-hover-color)}.ng-doc-playground-reset:focus-visible{outline:none;box-shadow:var(--ng-doc-focus-ring)}.ng-doc-playground-setting{display:flex;align-items:center;gap:6px;padding:0 var(--ng-doc-space-4) var(--ng-doc-space-3)}.ng-doc-playground-info{--ng-doc-icon-color: var(--ng-doc-text-muted)}.ng-doc-playground-divider{height:1px;background:var(--ng-doc-border-color)}h5.ng-doc-title{margin:0;padding:var(--ng-doc-space-3) var(--ng-doc-space-4) var(--ng-doc-space-1);font-family:var(--ng-doc-font-family);font-size:11px;line-height:16px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--ng-doc-text-muted)}ng-doc-playground-property{padding:var(--ng-doc-space-2) var(--ng-doc-space-4)}ng-doc-playground-property+ng-doc-playground-property{border-top:1px solid var(--ng-doc-base-2)}.ng-doc-playground-property-list:last-child{padding-bottom:var(--ng-doc-space-2)}.ng-doc-playground-properties-wrapper.inspector-bottom{grid-template-columns:minmax(0,1fr)}.ng-doc-playground-properties-wrapper.inspector-bottom .ng-doc-playground-properties{border-left:0;border-top:1px solid var(--ng-doc-border-color)}.ng-doc-playground-properties-wrapper.inspector-bottom .ng-doc-playground-property-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,320px),1fr));column-gap:var(--ng-doc-space-4)}.ng-doc-playground-properties-wrapper.inspector-bottom ng-doc-playground-property+ng-doc-playground-property{border-top:0}@container ng-doc-playground (max-width: 640px){.ng-doc-playground-properties-wrapper{grid-template-columns:minmax(0,1fr)}.ng-doc-playground-properties-wrapper:not(.no-side-panel) .ng-doc-playground-demos{position:static}.ng-doc-playground-properties{border-left:0;border-top:1px solid var(--ng-doc-border-color)}}\n"], dependencies: [{ kind: "component", type: NgDocCheckboxComponent, selector: "ng-doc-checkbox", inputs: ["color"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgDocTooltipDirective, selector: "[ngDocTooltip]", inputs: ["ngDocTooltip", "delay", "displayOrigin", "pointerOrigin", "positions", "canOpen", "panelClass", "minHeight", "maxHeight", "height", "minWidth", "maxWidth", "width"], outputs: ["beforeOpen", "afterOpen", "beforeClose", "afterClose"], exportAs: ["ngDocTooltip"] }, { kind: "component", type: NgDocIconComponent, selector: "ng-doc-icon", inputs: ["icon", "customIcon", "size"] }, { kind: "component", type: NgDocPlaygroundPropertyComponent, selector: "ng-doc-playground-property", inputs: ["name", "property", "typeControl", "control", "defaultValue"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: NgDocBindPipe, name: "bind" }, { kind: "pipe", type: NgDocExecutePipe, name: "execute" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
300
424
|
}
|
|
301
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
425
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPlaygroundPropertiesComponent, decorators: [{
|
|
302
426
|
type: Component,
|
|
303
427
|
args: [{ selector: 'ng-doc-playground-properties', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
304
|
-
NgDocTextComponent,
|
|
305
|
-
NgDocButtonComponent,
|
|
306
428
|
NgDocCheckboxComponent,
|
|
307
429
|
FormsModule,
|
|
308
430
|
NgDocTooltipDirective,
|
|
309
431
|
NgDocIconComponent,
|
|
310
|
-
NgDocTextRightDirective,
|
|
311
432
|
NgDocPlaygroundPropertyComponent,
|
|
312
|
-
AsyncPipe,
|
|
313
433
|
KeyValuePipe,
|
|
314
434
|
NgDocBindPipe,
|
|
315
435
|
NgDocExecutePipe,
|
|
316
|
-
], template: "@if (defaultValues) {\n <div
|
|
317
|
-
}],
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
}] } });
|
|
436
|
+
], template: "@if (defaultValues(); as defaultValues) {\n <div\n class=\"ng-doc-playground-properties-wrapper\"\n [class.no-side-panel]=\"hideSidePanel()\"\n [class.inspector-bottom]=\"inspectorPosition() === 'bottom'\">\n <div class=\"ng-doc-playground-demos\">\n <ng-content></ng-content>\n </div>\n @if (!hideSidePanel()) {\n <div class=\"ng-doc-playground-properties\">\n <div class=\"ng-doc-playground-header\">\n <h4>Playground</h4>\n @if (showResetButton()) {\n <button type=\"button\" class=\"ng-doc-playground-reset\" (click)=\"resetForm.emit()\">\n Reset\n </button>\n }\n </div>\n <div class=\"ng-doc-playground-setting\">\n <ng-doc-checkbox [ngModel]=\"recreateDemo()\" (ngModelChange)=\"recreateDemo.set($event)\">\n Recreate\n </ng-doc-checkbox>\n <ng-doc-icon\n class=\"ng-doc-playground-info\"\n icon=\"info\"\n role=\"img\"\n aria-label=\"Recreates the demo every time one of the inputs changes\"\n [ngDocTooltip]=\"'Recreates the demo every time one of the inputs changes'\"\n [positions]=\"['bottom-right', 'left-center']\"></ng-doc-icon>\n </div>\n <div class=\"ng-doc-playground-divider\"></div>\n @if (propertyControls().length) {\n <h5 class=\"ng-doc-title\">Settings</h5>\n <div class=\"ng-doc-playground-property-list\">\n @for (propertyControl of propertyControls(); track propertyControl.propertyName) {\n <ng-doc-playground-property\n [name]=\"propertyControl.property.inputName\"\n [property]=\"propertyControl.property\"\n [typeControl]=\"propertyControl.typeControl\"\n [defaultValue]=\"defaultValues[propertyControl.propertyName]\"\n [control]=\"\n getFormControl | bind: this | execute: 'properties' : propertyControl.propertyName\n \">\n </ng-doc-playground-property>\n }\n </div>\n }\n @if ((dynamicContent() | keyvalue)?.length) {\n <h5 class=\"ng-doc-title\">Content</h5>\n <div class=\"ng-doc-playground-property-list\">\n @for (content of dynamicContent() | keyvalue; track content.key) {\n <ng-doc-playground-property\n [name]=\"content.value.label\"\n [property]=\"content.value\"\n [typeControl]=\"contentTypeControl\"\n [control]=\"getFormControl | bind: this | execute: 'content' : content.key\">\n </ng-doc-playground-property>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;container:ng-doc-playground/inline-size}.ng-doc-playground-properties-wrapper{display:grid;grid-template-columns:minmax(0,1fr) var(--ng-doc-playground-inspector-width);align-items:stretch;border:var(--ng-doc-demo-displayer-border);border-radius:var(--ng-doc-demo-displayer-border-radius);overflow:clip;background-color:var(--ng-doc-demo-displayer-background, var(--ng-doc-background))}.ng-doc-playground-properties-wrapper.no-side-panel{grid-template-columns:minmax(0,1fr)}.ng-doc-playground-properties-wrapper:not(.no-side-panel):not(.inspector-bottom) .ng-doc-playground-demos{position:sticky;top:calc(var(--ng-doc-page-sticky-offset) + var(--ng-doc-base-gutter));align-self:start;z-index:4}.ng-doc-playground-demos{display:flex;flex-direction:column;min-width:0}.ng-doc-playground-properties-wrapper:not(.no-side-panel):not(.inspector-bottom) .ng-doc-playground-demos{min-height:min(100%,100dvh - var(--ng-doc-page-sticky-offset) - 2 * var(--ng-doc-base-gutter))}.ng-doc-playground-properties{min-width:0;background:var(--ng-doc-base-1);border-left:1px solid var(--ng-doc-border-color);font-family:var(--ng-doc-font-family);font-size:14px;line-height:20px;color:var(--ng-doc-text);--ng-doc-input-height: 36px;--ng-doc-input-border: var(--ng-doc-playground-input-border);--ng-doc-checkbox-border: var(--ng-doc-playground-input-border)}.ng-doc-playground-header{display:flex;align-items:center;gap:var(--ng-doc-space-2);height:52px;padding:0 var(--ng-doc-space-3) 0 var(--ng-doc-space-4)}.ng-doc-playground-header h4{margin:0;font-family:var(--ng-doc-heading-font-family);font-size:15px;line-height:22px;font-weight:600;letter-spacing:0;color:var(--ng-doc-heading-color)}.ng-doc-playground-reset{display:inline-flex;align-items:center;height:28px;margin-left:auto;padding:0 10px;border:1px solid var(--ng-doc-border-color);border-radius:var(--ng-doc-radius-md);background:var(--ng-doc-background);font:inherit;font-size:12px;font-weight:500;color:var(--ng-doc-heading-color);cursor:pointer}.ng-doc-playground-reset:hover{border-color:var(--ng-doc-border-hover-color)}.ng-doc-playground-reset:focus-visible{outline:none;box-shadow:var(--ng-doc-focus-ring)}.ng-doc-playground-setting{display:flex;align-items:center;gap:6px;padding:0 var(--ng-doc-space-4) var(--ng-doc-space-3)}.ng-doc-playground-info{--ng-doc-icon-color: var(--ng-doc-text-muted)}.ng-doc-playground-divider{height:1px;background:var(--ng-doc-border-color)}h5.ng-doc-title{margin:0;padding:var(--ng-doc-space-3) var(--ng-doc-space-4) var(--ng-doc-space-1);font-family:var(--ng-doc-font-family);font-size:11px;line-height:16px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--ng-doc-text-muted)}ng-doc-playground-property{padding:var(--ng-doc-space-2) var(--ng-doc-space-4)}ng-doc-playground-property+ng-doc-playground-property{border-top:1px solid var(--ng-doc-base-2)}.ng-doc-playground-property-list:last-child{padding-bottom:var(--ng-doc-space-2)}.ng-doc-playground-properties-wrapper.inspector-bottom{grid-template-columns:minmax(0,1fr)}.ng-doc-playground-properties-wrapper.inspector-bottom .ng-doc-playground-properties{border-left:0;border-top:1px solid var(--ng-doc-border-color)}.ng-doc-playground-properties-wrapper.inspector-bottom .ng-doc-playground-property-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,320px),1fr));column-gap:var(--ng-doc-space-4)}.ng-doc-playground-properties-wrapper.inspector-bottom ng-doc-playground-property+ng-doc-playground-property{border-top:0}@container ng-doc-playground (max-width: 640px){.ng-doc-playground-properties-wrapper{grid-template-columns:minmax(0,1fr)}.ng-doc-playground-properties-wrapper:not(.no-side-panel) .ng-doc-playground-demos{position:static}.ng-doc-playground-properties{border-left:0;border-top:1px solid var(--ng-doc-border-color)}}\n"] }]
|
|
437
|
+
}], propDecorators: { form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: true }] }], properties: [{ type: i0.Input, args: [{ isSignal: true, alias: "properties", required: false }] }], ignoreInputs: [{ type: i0.Input, args: [{ isSignal: true, alias: "ignoreInputs", required: false }] }], dynamicContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "dynamicContent", required: false }] }], defaultValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValues", required: false }] }], hideSidePanel: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideSidePanel", required: false }] }], inspectorPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "inspectorPosition", required: false }] }], recreateDemo: [{ type: i0.Input, args: [{ isSignal: true, alias: "recreateDemo", required: false }] }, { type: i0.Output, args: ["recreateDemoChange"] }], showResetButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showResetButton", required: false }] }], resetForm: [{ type: i0.Output, args: ["resetForm"] }] } });
|
|
438
|
+
/** The types whose control also edits an optional or nullable input of the type. */
|
|
439
|
+
const PRIMITIVE_TYPES = new Set(['string', 'number', 'boolean']);
|
|
440
|
+
/**
|
|
441
|
+
* The primitive of an optional or nullable primitive input type, such as `string` of
|
|
442
|
+
* `string | undefined` (an optional `@Input() label?: string`, `input<string>()` or
|
|
443
|
+
* `model<string>()`) or of `number | null`, so that the input gets the primitive's control.
|
|
444
|
+
* Other types are matched by their exact name only: a custom control registered for `Position`
|
|
445
|
+
* does not receive the `undefined` of a `Position | undefined` input unless it is registered for
|
|
446
|
+
* that type too.
|
|
447
|
+
* @param type - The input type as the builder printed it.
|
|
448
|
+
* @returns The primitive, or `undefined` when the type is not one.
|
|
449
|
+
*/
|
|
450
|
+
function optionalPrimitive(type) {
|
|
451
|
+
const members = type.split('|').map((member) => member.trim());
|
|
452
|
+
const rest = members.filter((member) => member !== 'undefined' && member !== 'null');
|
|
453
|
+
return rest.length === 1 && rest.length < members.length && PRIMITIVE_TYPES.has(rest[0])
|
|
454
|
+
? rest[0]
|
|
455
|
+
: undefined;
|
|
456
|
+
}
|
|
338
457
|
|
|
458
|
+
/**
|
|
459
|
+
* A playground: an inspector with a control per input and content slot of its target, and a demo
|
|
460
|
+
* per selector (or the pipe) rendered with the chosen values.
|
|
461
|
+
*/
|
|
339
462
|
class NgDocPlaygroundComponent {
|
|
340
463
|
constructor() {
|
|
341
464
|
this.rootPage = inject(NgDocRootPage);
|
|
342
465
|
this.formBuilder = inject(FormBuilder);
|
|
343
|
-
|
|
344
|
-
this.
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
this.
|
|
466
|
+
/** The name of the playground in the page configuration. */
|
|
467
|
+
this.id = input.required(/* @ts-ignore */
|
|
468
|
+
...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
469
|
+
/** The name of the pipe, when the target is a pipe. */
|
|
470
|
+
this.pipeName = input('', /* @ts-ignore */
|
|
471
|
+
...(ngDevMode ? [{ debugName: "pipeName" }] : /* istanbul ignore next */ []));
|
|
472
|
+
/** The selectors of the target to render a demo for. */
|
|
473
|
+
this.selectors = input([], /* @ts-ignore */
|
|
474
|
+
...(ngDevMode ? [{ debugName: "selectors" }] : /* istanbul ignore next */ []));
|
|
475
|
+
/** The inputs of the target. */
|
|
476
|
+
this.properties = input(undefined, /* @ts-ignore */
|
|
477
|
+
...(ngDevMode ? [{ debugName: "properties" }] : /* istanbul ignore next */ []));
|
|
478
|
+
/** Options of the playground action; they extend the playground configuration. */
|
|
479
|
+
this.options = input({}, /* @ts-ignore */
|
|
480
|
+
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
481
|
+
/** Whether the demo is created again each time a value changes. */
|
|
482
|
+
this.recreateDemo = signal(false, /* @ts-ignore */
|
|
483
|
+
...(ngDevMode ? [{ debugName: "recreateDemo" }] : /* istanbul ignore next */ []));
|
|
484
|
+
/** The values of the inputs and content slots. */
|
|
485
|
+
this.formGroup = signal(undefined, /* @ts-ignore */
|
|
486
|
+
...(ngDevMode ? [{ debugName: "formGroup" }] : /* istanbul ignore next */ []));
|
|
487
|
+
/** The default values of the target's inputs, reported by the first demo. */
|
|
488
|
+
this.defaultValues = signal(undefined, /* @ts-ignore */
|
|
489
|
+
...(ngDevMode ? [{ debugName: "defaultValues" }] : /* istanbul ignore next */ []));
|
|
490
|
+
/** The playground configuration of the page, extended by the options. */
|
|
491
|
+
this.configuration = computed(() => Object.assign({}, this.rootPage.page?.playgrounds?.[this.id()], this.options()), /* @ts-ignore */
|
|
492
|
+
...(ngDevMode ? [{ debugName: "configuration" }] : /* istanbul ignore next */ []));
|
|
348
493
|
this.defaultProperties = {};
|
|
349
494
|
this.defaultContent = {};
|
|
350
495
|
}
|
|
351
|
-
ngOnChanges({ options }) {
|
|
352
|
-
if (options) {
|
|
353
|
-
// Join configuration with options
|
|
354
|
-
this.configuration = Object.assign({}, this.rootPage.page?.playgrounds?.[this.id], this.options);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
496
|
ngAfterViewInit() {
|
|
358
497
|
this.defaultProperties = this.getPropertiesFormValues();
|
|
359
498
|
this.defaultContent = this.getContentFormValues();
|
|
360
499
|
const propertiesForm = this.formBuilder.group(this.defaultProperties);
|
|
361
500
|
const contentForm = this.formBuilder.group(this.defaultContent);
|
|
362
|
-
|
|
501
|
+
const formGroup = this.formBuilder.group({
|
|
363
502
|
properties: propertiesForm,
|
|
364
503
|
content: contentForm,
|
|
365
504
|
});
|
|
366
505
|
// `patchValue` is needed to set `undefined` values, otherwise they will be ignored by the Angular form
|
|
367
|
-
|
|
368
|
-
properties: Object.assign({}, this.defaultProperties, this.configuration.inputs),
|
|
506
|
+
formGroup.patchValue({
|
|
507
|
+
properties: Object.assign({}, this.defaultProperties, this.configuration().inputs),
|
|
369
508
|
content: this.defaultContent,
|
|
370
509
|
});
|
|
510
|
+
this.formGroup.set(formGroup);
|
|
371
511
|
}
|
|
372
512
|
isDefaultState() {
|
|
373
|
-
|
|
513
|
+
const formGroup = this.formGroup();
|
|
514
|
+
if (!formGroup) {
|
|
374
515
|
return false;
|
|
375
516
|
}
|
|
376
|
-
return (isSameObject(
|
|
377
|
-
isSameObject(
|
|
517
|
+
return (isSameObject(formGroup.value.properties ?? {}, this.defaultValues() ?? {}) &&
|
|
518
|
+
isSameObject(formGroup.value.content ?? {}, this.defaultContent ?? {}));
|
|
378
519
|
}
|
|
379
520
|
getPropertiesFormValues() {
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
}
|
|
521
|
+
const defaultValues = this.defaultValues();
|
|
522
|
+
const formValues = objectKeys(this.properties() ?? {}).reduce((controls, key) => {
|
|
523
|
+
controls[key] = defaultValues ? defaultValues[key] : undefined;
|
|
384
524
|
return controls;
|
|
385
525
|
}, {});
|
|
386
|
-
return Object.assign({}, formValues, this.configuration.defaults);
|
|
526
|
+
return Object.assign({}, formValues, this.configuration().defaults);
|
|
387
527
|
}
|
|
388
528
|
getContentFormValues() {
|
|
389
|
-
return objectKeys(this.configuration
|
|
390
|
-
|
|
391
|
-
controls[key] = false;
|
|
392
|
-
}
|
|
529
|
+
return objectKeys(this.configuration().content ?? {}).reduce((controls, key) => {
|
|
530
|
+
controls[key] = false;
|
|
393
531
|
return controls;
|
|
394
532
|
}, {});
|
|
395
533
|
}
|
|
534
|
+
/** Sets every input and content slot back to its default value. */
|
|
396
535
|
resetForm() {
|
|
397
|
-
this.formGroup
|
|
398
|
-
|
|
536
|
+
const formGroup = this.formGroup();
|
|
537
|
+
formGroup?.reset({}, { emitEvent: false });
|
|
538
|
+
formGroup?.patchValue({
|
|
399
539
|
properties: this.defaultProperties,
|
|
400
540
|
content: this.defaultContent,
|
|
401
541
|
});
|
|
402
542
|
}
|
|
403
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
404
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.
|
|
543
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPlaygroundComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
544
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.1", type: NgDocPlaygroundComponent, isStandalone: true, selector: "ng-doc-playground", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: true, transformFunction: null }, pipeName: { classPropertyName: "pipeName", publicName: "pipeName", isSignal: true, isRequired: false, transformFunction: null }, selectors: { classPropertyName: "selectors", publicName: "selectors", isSignal: true, isRequired: false, transformFunction: null }, properties: { classPropertyName: "properties", publicName: "properties", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (configuration(); as configuration) {\n <ng-doc-playground-properties\n [form]=\"formGroup()!\"\n [properties]=\"properties()\"\n [ignoreInputs]=\"configuration.hiddenInputs\"\n [dynamicContent]=\"configuration.content\"\n [hideSidePanel]=\"configuration.hideSidePanel ?? false\"\n [inspectorPosition]=\"configuration.inspectorPosition ?? 'right'\"\n [defaultValues]=\"defaultValues()\"\n [showResetButton]=\"!isDefaultState()\"\n [(recreateDemo)]=\"recreateDemo\"\n (resetForm)=\"resetForm()\">\n @for (selector of configuration.selectors ?? selectors() | asArray; track selector) {\n <ng-doc-playground-demo\n [id]=\"id()\"\n [selector]=\"selector\"\n [properties]=\"properties()\"\n [configuration]=\"configuration\"\n [recreateDemo]=\"recreateDemo()\"\n [form]=\"formGroup()\"\n [expanded]=\"configuration.expanded ?? false\">\n </ng-doc-playground-demo>\n }\n @if (pipeName()) {\n <ng-doc-playground-demo\n [id]=\"id()\"\n [pipeName]=\"pipeName()\"\n [properties]=\"properties()\"\n [configuration]=\"configuration\"\n [recreateDemo]=\"recreateDemo()\"\n [form]=\"formGroup()\">\n </ng-doc-playground-demo>\n }\n </ng-doc-playground-properties>\n}\n", styles: [":host{display:block;margin:var(--ng-doc-playground-margin)}ng-doc-playground-demo:last-child{flex:1 1 auto}ng-doc-playground-demo+ng-doc-playground-demo{border-top:1px solid color-mix(in srgb,var(--ng-doc-border-color) 70%,transparent)}\n"], dependencies: [{ kind: "component", type: NgDocPlaygroundPropertiesComponent, selector: "ng-doc-playground-properties", inputs: ["form", "properties", "ignoreInputs", "dynamicContent", "defaultValues", "hideSidePanel", "inspectorPosition", "recreateDemo", "showResetButton"], outputs: ["recreateDemoChange", "resetForm"] }, { kind: "component", type: NgDocPlaygroundDemoComponent, selector: "ng-doc-playground-demo", inputs: ["id", "pipeName", "selector", "configuration", "properties", "recreateDemo", "form", "expanded"] }, { kind: "pipe", type: NgDocAsArrayPipe, name: "asArray" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
405
545
|
}
|
|
406
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
546
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPlaygroundComponent, decorators: [{
|
|
407
547
|
type: Component,
|
|
408
|
-
args: [{ selector: 'ng-doc-playground', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgDocPlaygroundPropertiesComponent, NgDocPlaygroundDemoComponent, NgDocAsArrayPipe], template: "@if (configuration) {\n <ng-doc-playground-properties\n [form]=\"formGroup
|
|
409
|
-
}],
|
|
410
|
-
type: Input,
|
|
411
|
-
args: [{ required: true }]
|
|
412
|
-
}], pipeName: [{
|
|
413
|
-
type: Input
|
|
414
|
-
}], selectors: [{
|
|
415
|
-
type: Input
|
|
416
|
-
}], properties: [{
|
|
417
|
-
type: Input
|
|
418
|
-
}], options: [{
|
|
419
|
-
type: Input
|
|
420
|
-
}] } });
|
|
548
|
+
args: [{ selector: 'ng-doc-playground', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgDocPlaygroundPropertiesComponent, NgDocPlaygroundDemoComponent, NgDocAsArrayPipe], template: "@if (configuration(); as configuration) {\n <ng-doc-playground-properties\n [form]=\"formGroup()!\"\n [properties]=\"properties()\"\n [ignoreInputs]=\"configuration.hiddenInputs\"\n [dynamicContent]=\"configuration.content\"\n [hideSidePanel]=\"configuration.hideSidePanel ?? false\"\n [inspectorPosition]=\"configuration.inspectorPosition ?? 'right'\"\n [defaultValues]=\"defaultValues()\"\n [showResetButton]=\"!isDefaultState()\"\n [(recreateDemo)]=\"recreateDemo\"\n (resetForm)=\"resetForm()\">\n @for (selector of configuration.selectors ?? selectors() | asArray; track selector) {\n <ng-doc-playground-demo\n [id]=\"id()\"\n [selector]=\"selector\"\n [properties]=\"properties()\"\n [configuration]=\"configuration\"\n [recreateDemo]=\"recreateDemo()\"\n [form]=\"formGroup()\"\n [expanded]=\"configuration.expanded ?? false\">\n </ng-doc-playground-demo>\n }\n @if (pipeName()) {\n <ng-doc-playground-demo\n [id]=\"id()\"\n [pipeName]=\"pipeName()\"\n [properties]=\"properties()\"\n [configuration]=\"configuration\"\n [recreateDemo]=\"recreateDemo()\"\n [form]=\"formGroup()\">\n </ng-doc-playground-demo>\n }\n </ng-doc-playground-properties>\n}\n", styles: [":host{display:block;margin:var(--ng-doc-playground-margin)}ng-doc-playground-demo:last-child{flex:1 1 auto}ng-doc-playground-demo+ng-doc-playground-demo{border-top:1px solid color-mix(in srgb,var(--ng-doc-border-color) 70%,transparent)}\n"] }]
|
|
549
|
+
}], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: true }] }], pipeName: [{ type: i0.Input, args: [{ isSignal: true, alias: "pipeName", required: false }] }], selectors: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectors", required: false }] }], properties: [{ type: i0.Input, args: [{ isSignal: true, alias: "properties", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }] } });
|
|
421
550
|
|
|
422
551
|
/**
|
|
423
|
-
* Base class
|
|
552
|
+
* Base class of the playground classes the builder generates, one per playground and selector.
|
|
553
|
+
* A generated class renders the playground template with the target's inputs bound to
|
|
554
|
+
* `properties()`, and queries the target with `viewChild()`.
|
|
424
555
|
*/
|
|
425
556
|
class NgDocBasePlayground {
|
|
426
557
|
static { this.selector = 'unknown'; }
|
|
427
|
-
constructor(
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
this.
|
|
431
|
-
|
|
558
|
+
constructor() {
|
|
559
|
+
/** Values of the target's inputs, by property name. */
|
|
560
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
561
|
+
this.properties = input({}, /* @ts-ignore */
|
|
562
|
+
...(ngDevMode ? [{ debugName: "properties" }] : /* istanbul ignore next */ []));
|
|
563
|
+
/** The `data` given to the playground action; it extends the configuration's `data`. */
|
|
564
|
+
this.actionData = input({}, /* @ts-ignore */
|
|
565
|
+
...(ngDevMode ? [{ debugName: "actionData" }] : /* istanbul ignore next */ []));
|
|
566
|
+
/** Whether each content slot is shown, by slot name. */
|
|
567
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
568
|
+
this.content = input({}, /* @ts-ignore */
|
|
569
|
+
...(ngDevMode ? [{ debugName: "content" }] : /* istanbul ignore next */ []));
|
|
570
|
+
/** The default values of the target's inputs, read before the template binds them. */
|
|
432
571
|
this.defaultValues = {};
|
|
433
572
|
this.reattached = new Subject();
|
|
434
573
|
this.playgroundContainer = inject(NgDocPlaygroundComponent);
|
|
435
574
|
this.changeDetectorRef = inject(ChangeDetectorRef);
|
|
575
|
+
// The view is not checked until the default values of the target are read, so the
|
|
576
|
+
// template's bindings cannot overwrite them first.
|
|
436
577
|
this.changeDetectorRef.detach();
|
|
437
578
|
}
|
|
579
|
+
/** Emits once, after the view is attached again and checks the template's bindings. */
|
|
438
580
|
get onReattached() {
|
|
439
581
|
return this.reattached.pipe(take(1));
|
|
440
582
|
}
|
|
583
|
+
/** The playground `data`: the configuration's data extended by the action's data. */
|
|
584
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
585
|
+
get data() {
|
|
586
|
+
return Object.assign({}, this.configData, this.actionData());
|
|
587
|
+
}
|
|
441
588
|
ngOnInit() {
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
? // @ts-expect-error we do not know the type of the playground
|
|
454
|
-
this.playground[key]()
|
|
455
|
-
: // @ts-expect-error we do not know the type of the playground
|
|
456
|
-
this.playground[key];
|
|
457
|
-
}
|
|
458
|
-
catch (e) {
|
|
459
|
-
// we do catch here because some of the playground properties can be getters and throw an error
|
|
460
|
-
}
|
|
589
|
+
// The target is created with the view, but the view has not been checked yet, so its inputs
|
|
590
|
+
// still hold their defaults. Signal inputs are read by calling them.
|
|
591
|
+
const playground = this.playground();
|
|
592
|
+
if (playground) {
|
|
593
|
+
this.defaultValues = Object.keys(playground).reduce((values, key) => {
|
|
594
|
+
try {
|
|
595
|
+
const value = playground[key];
|
|
596
|
+
values[key] = typeof value === 'function' ? value.call(playground) : value;
|
|
597
|
+
}
|
|
598
|
+
catch {
|
|
599
|
+
// Some properties are getters or functions that throw without their context.
|
|
461
600
|
}
|
|
462
601
|
return values;
|
|
463
602
|
}, {});
|
|
464
603
|
}
|
|
465
|
-
else if (this.
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
return
|
|
604
|
+
else if (this.target) {
|
|
605
|
+
// A pipe: the defaults of its `transform` parameters after the value itself.
|
|
606
|
+
const defaults = extractFunctionDefaults(this.target.prototype.transform);
|
|
607
|
+
this.defaultValues = Object.keys(this.playgroundContainer.properties() ?? {}).reduce((values, key, i) => {
|
|
608
|
+
values[key] = defaults[i + 1];
|
|
609
|
+
return values;
|
|
471
610
|
}, {});
|
|
472
611
|
}
|
|
473
612
|
else {
|
|
474
613
|
throw new Error('Playground is not defined or initialized');
|
|
475
614
|
}
|
|
476
|
-
if (!this.playgroundContainer.defaultValues) {
|
|
477
|
-
this.playgroundContainer.defaultValues
|
|
615
|
+
if (!this.playgroundContainer.defaultValues()) {
|
|
616
|
+
this.playgroundContainer.defaultValues.set(this.defaultValues);
|
|
478
617
|
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
attach the change detector to have correct inputs values.
|
|
482
|
-
*/
|
|
618
|
+
// The demo sets the playground's inputs right after it creates this view; the view is
|
|
619
|
+
// attached again once they are set, so its first check renders the playground's values.
|
|
483
620
|
Promise.resolve().then(() => {
|
|
484
621
|
this.changeDetectorRef.reattach();
|
|
622
|
+
this.changeDetectorRef.markForCheck();
|
|
485
623
|
this.reattached.next();
|
|
486
624
|
});
|
|
487
625
|
}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
}
|
|
491
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgDocBasePlayground, deps: "invalid", target: i0.ɵɵFactoryTarget.Directive }); }
|
|
492
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: NgDocBasePlayground, isStandalone: true, inputs: { properties: "properties", actionData: "actionData", content: "content" }, ngImport: i0 }); }
|
|
626
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocBasePlayground, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
627
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.2.1", type: NgDocBasePlayground, isStandalone: true, inputs: { properties: { classPropertyName: "properties", publicName: "properties", isSignal: true, isRequired: false, transformFunction: null }, actionData: { classPropertyName: "actionData", publicName: "actionData", isSignal: true, isRequired: false, transformFunction: null }, content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
|
|
493
628
|
}
|
|
494
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
629
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocBasePlayground, decorators: [{
|
|
495
630
|
type: Directive
|
|
496
|
-
}], ctorParameters: () => [{ type:
|
|
497
|
-
type: Input
|
|
498
|
-
}], actionData: [{
|
|
499
|
-
type: Input
|
|
500
|
-
}], content: [{
|
|
501
|
-
type: Input
|
|
502
|
-
}] } });
|
|
631
|
+
}], ctorParameters: () => [], propDecorators: { properties: [{ type: i0.Input, args: [{ isSignal: true, alias: "properties", required: false }] }], actionData: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionData", required: false }] }], content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }] } });
|
|
503
632
|
|
|
504
633
|
/**
|
|
505
634
|
* Generated bundle index. Do not edit.
|