@ng-prism/core 22.4.1 → 22.6.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 +2 -0
- package/dist/app/canvas/prism-canvas-toolbar.component.d.ts +33 -2
- package/dist/app/canvas/prism-canvas-toolbar.component.d.ts.map +1 -1
- package/dist/app/canvas/prism-canvas-toolbar.component.js +135 -28
- package/dist/app/canvas/state-chips.d.ts +50 -0
- package/dist/app/canvas/state-chips.d.ts.map +1 -0
- package/dist/app/canvas/state-chips.js +40 -0
- package/dist/app/component-head/prism-component-head.component.d.ts +1 -0
- package/dist/app/component-head/prism-component-head.component.d.ts.map +1 -1
- package/dist/app/component-head/prism-component-head.component.js +11 -6
- package/dist/app/component-head/prism-head-info.component.d.ts +2 -1
- package/dist/app/component-head/prism-head-info.component.d.ts.map +1 -1
- package/dist/app/component-head/prism-head-info.component.js +30 -7
- package/dist/app/directives/resize-value.d.ts +1 -1
- package/dist/app/directives/resize-value.js +1 -1
- package/dist/app/discovery-manifest.d.ts +2 -2
- package/dist/app/discovery-manifest.d.ts.map +1 -1
- package/dist/app/discovery-manifest.js +22 -4
- package/dist/app/overview/open-in-playground.d.ts +11 -0
- package/dist/app/overview/open-in-playground.d.ts.map +1 -0
- package/dist/app/overview/open-in-playground.js +12 -0
- package/dist/app/overview/overview-matrix.d.ts +79 -0
- package/dist/app/overview/overview-matrix.d.ts.map +1 -0
- package/dist/app/overview/overview-matrix.js +98 -0
- package/dist/app/overview/overview-visibility.d.ts +10 -2
- package/dist/app/overview/overview-visibility.d.ts.map +1 -1
- package/dist/app/overview/overview-visibility.js +14 -3
- package/dist/app/overview/prism-overview-cell.component.d.ts +29 -2
- package/dist/app/overview/prism-overview-cell.component.d.ts.map +1 -1
- package/dist/app/overview/prism-overview-cell.component.js +145 -27
- package/dist/app/overview/prism-overview-matrix.component.d.ts +29 -0
- package/dist/app/overview/prism-overview-matrix.component.d.ts.map +1 -0
- package/dist/app/overview/prism-overview-matrix.component.js +164 -0
- package/dist/app/overview/prism-overview.component.d.ts +4 -0
- package/dist/app/overview/prism-overview.component.d.ts.map +1 -1
- package/dist/app/overview/prism-overview.component.js +37 -14
- package/dist/app/panels/a11y/a11y-core.plugin.d.ts.map +1 -1
- package/dist/app/panels/a11y/a11y-core.plugin.js +0 -1
- package/dist/app/panels/controls/controls-plugin.d.ts.map +1 -1
- package/dist/app/panels/controls/controls-plugin.js +1 -2
- package/dist/app/panels/events/events-plugin.d.ts.map +1 -1
- package/dist/app/panels/events/events-plugin.js +1 -2
- package/dist/app/pseudo/pseudo-selector.d.ts +24 -0
- package/dist/app/pseudo/pseudo-selector.d.ts.map +1 -0
- package/dist/app/pseudo/pseudo-selector.js +136 -0
- package/dist/app/pseudo/pseudo-state-marker.d.ts +66 -0
- package/dist/app/pseudo/pseudo-state-marker.d.ts.map +1 -0
- package/dist/app/pseudo/pseudo-state-marker.js +165 -0
- package/dist/app/pseudo/pseudo-stylesheets.d.ts +49 -0
- package/dist/app/pseudo/pseudo-stylesheets.d.ts.map +1 -0
- package/dist/app/pseudo/pseudo-stylesheets.js +137 -0
- package/dist/app/pseudo/pseudo-targets.d.ts +11 -0
- package/dist/app/pseudo/pseudo-targets.d.ts.map +1 -0
- package/dist/app/pseudo/pseudo-targets.js +46 -0
- package/dist/app/pseudo/state-fit.d.ts +28 -0
- package/dist/app/pseudo/state-fit.d.ts.map +1 -0
- package/dist/app/pseudo/state-fit.js +97 -0
- package/dist/app/renderer/input-bindings.d.ts +16 -0
- package/dist/app/renderer/input-bindings.d.ts.map +1 -0
- package/dist/app/renderer/input-bindings.js +21 -0
- package/dist/app/renderer/known-inputs.d.ts +8 -1
- package/dist/app/renderer/known-inputs.d.ts.map +1 -1
- package/dist/app/renderer/known-inputs.js +13 -5
- package/dist/app/renderer/prism-renderer.component.d.ts +18 -1
- package/dist/app/renderer/prism-renderer.component.d.ts.map +1 -1
- package/dist/app/renderer/prism-renderer.component.js +68 -22
- package/dist/app/renderer/projectable-content.d.ts +8 -1
- package/dist/app/renderer/projectable-content.d.ts.map +1 -1
- package/dist/app/renderer/projectable-content.js +40 -29
- package/dist/app/renderer/rendered-key.d.ts +38 -0
- package/dist/app/renderer/rendered-key.d.ts.map +1 -0
- package/dist/app/renderer/rendered-key.js +34 -0
- package/dist/app/renderer/snippet-generator.js +7 -5
- package/dist/app/services/prism-capture.service.d.ts +2 -0
- package/dist/app/services/prism-capture.service.d.ts.map +1 -1
- package/dist/app/services/prism-capture.service.js +25 -0
- package/dist/app/services/prism-pseudo-state.service.d.ts +93 -0
- package/dist/app/services/prism-pseudo-state.service.d.ts.map +1 -0
- package/dist/app/services/prism-pseudo-state.service.js +155 -0
- package/dist/app/services/prism-renderer.service.d.ts +17 -0
- package/dist/app/services/prism-renderer.service.d.ts.map +1 -1
- package/dist/app/services/prism-renderer.service.js +37 -2
- package/dist/app/services/prism-url-state.service.d.ts.map +1 -1
- package/dist/app/services/prism-url-state.service.js +39 -8
- package/dist/app/theme/prism-default-theme.d.ts.map +1 -1
- package/dist/app/theme/prism-default-theme.js +6 -5
- package/dist/builder/config-loader/deprecated-options.d.ts +7 -0
- package/dist/builder/config-loader/deprecated-options.d.ts.map +1 -0
- package/dist/builder/config-loader/deprecated-options.js +23 -0
- package/dist/builder/manifest/runtime-manifest.generator.d.ts.map +1 -1
- package/dist/builder/manifest/runtime-manifest.generator.js +3 -2
- package/dist/builder/scanner/component.scanner.d.ts.map +1 -1
- package/dist/builder/scanner/component.scanner.js +27 -0
- package/dist/builder/scanner/entry-point-discovery.d.ts +5 -0
- package/dist/builder/scanner/entry-point-discovery.d.ts.map +1 -1
- package/dist/builder/scanner/entry-point-discovery.js +14 -0
- package/dist/builder/scanner/entry-point.scanner.d.ts +3 -1
- package/dist/builder/scanner/entry-point.scanner.d.ts.map +1 -1
- package/dist/builder/scanner/entry-point.scanner.js +7 -6
- package/dist/builder/scanner/input.extractor.d.ts.map +1 -1
- package/dist/builder/scanner/input.extractor.js +22 -3
- package/dist/builder/scanner/pseudo-states.d.ts +12 -0
- package/dist/builder/scanner/pseudo-states.d.ts.map +1 -0
- package/dist/builder/scanner/pseudo-states.js +58 -0
- package/dist/builder/scanner/scanner.d.ts +2 -2
- package/dist/builder/scanner/scanner.d.ts.map +1 -1
- package/dist/builder/scanner/scanner.js +16 -6
- package/dist/builder/scanner/showcase-diagnostics.js +9 -9
- package/dist/builder/scanner/showcase-states.d.ts +17 -0
- package/dist/builder/scanner/showcase-states.d.ts.map +1 -0
- package/dist/builder/scanner/showcase-states.js +58 -0
- package/dist/builder/scanner/source-file-cache.d.ts +26 -0
- package/dist/builder/scanner/source-file-cache.d.ts.map +1 -0
- package/dist/builder/scanner/source-file-cache.js +60 -0
- package/dist/builder/shared/prism-pipeline.d.ts.map +1 -1
- package/dist/builder/shared/prism-pipeline.js +28 -13
- package/dist/decorator/index.d.ts +1 -1
- package/dist/decorator/index.d.ts.map +1 -1
- package/dist/decorator/showcase.types.d.ts +33 -0
- package/dist/decorator/showcase.types.d.ts.map +1 -1
- package/dist/plugin/index.d.ts +3 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1 -0
- package/dist/plugin/plugin.types.d.ts +53 -7
- package/dist/plugin/plugin.types.d.ts.map +1 -1
- package/dist/shared/pseudo-state.type.d.ts +22 -0
- package/dist/shared/pseudo-state.type.d.ts.map +1 -0
- package/dist/shared/pseudo-state.type.js +2 -0
- package/package.json +1 -1
- package/src/builder/build/schema.json +6 -6
- package/src/builder/serve/schema.json +6 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { computed, inject, Injectable, signal } from '@angular/core';
|
|
1
|
+
import { computed, effect, inject, Injectable, signal, untracked } from '@angular/core';
|
|
2
2
|
import { PrismNavigationService } from './prism-navigation.service.js';
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
4
|
export function computeVariantState(comp, index, options = {}) {
|
|
@@ -57,6 +57,13 @@ export class PrismRendererService {
|
|
|
57
57
|
navigationService = inject(PrismNavigationService);
|
|
58
58
|
activeVariantIndex = signal(0, /* @ts-ignore */
|
|
59
59
|
...(ngDevMode ? [{ debugName: "activeVariantIndex" }] : /* istanbul ignore next */ []));
|
|
60
|
+
/**
|
|
61
|
+
* Position in `ShowcaseConfig.states` of the component-level state on the
|
|
62
|
+
* canvas, `null` for none. Part of the addressed cell next to the variant:
|
|
63
|
+
* it survives a variant change and goes with the component.
|
|
64
|
+
*/
|
|
65
|
+
activeStateIndex = signal(null, /* @ts-ignore */
|
|
66
|
+
...(ngDevMode ? [{ debugName: "activeStateIndex" }] : /* istanbul ignore next */ []));
|
|
60
67
|
inputValues = signal({}, /* @ts-ignore */
|
|
61
68
|
...(ngDevMode ? [{ debugName: "inputValues" }] : /* istanbul ignore next */ []));
|
|
62
69
|
activeContent = signal(undefined, /* @ts-ignore */
|
|
@@ -78,20 +85,45 @@ export class PrismRendererService {
|
|
|
78
85
|
return count;
|
|
79
86
|
}, /* @ts-ignore */
|
|
80
87
|
...(ngDevMode ? [{ debugName: "dirtyInputCount" }] : /* istanbul ignore next */ []));
|
|
88
|
+
/** The component the variant, the state and the inputs belong to, `null` before the first. */
|
|
81
89
|
_lastClassName = null;
|
|
90
|
+
constructor() {
|
|
91
|
+
// The variant and the state go with the component in every view, so the reset on a switch follows
|
|
92
|
+
// navigation, not the renderer: the shell mounts `<prism-renderer>` in the Playground only, and the Overview
|
|
93
|
+
// keeps its view when the sidebar picks another component. A root effect, created before the URL service's,
|
|
94
|
+
// so it runs first in the same flush and the URL never sees the previous component's cell on the new one.
|
|
95
|
+
effect(() => {
|
|
96
|
+
const comp = this.navigationService.activeComponent();
|
|
97
|
+
if (comp)
|
|
98
|
+
untracked(() => this.reconcileForComponent(comp));
|
|
99
|
+
});
|
|
100
|
+
}
|
|
82
101
|
resetForComponent(comp) {
|
|
83
102
|
this._lastClassName = comp.meta.className;
|
|
84
103
|
this.activeVariantIndex.set(0);
|
|
104
|
+
this.activeStateIndex.set(null);
|
|
85
105
|
this.applyVariant(0, comp);
|
|
86
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Brings the variant, the state and the inputs in line with `comp`: a full
|
|
109
|
+
* reset when it is another component than the last one, else the variant
|
|
110
|
+
* and the state clamped to what it still declares and the inputs kept.
|
|
111
|
+
* Runs on every navigation and again when the renderer mounts, which then
|
|
112
|
+
* finds the component current and keeps what an Overview cell or a restore
|
|
113
|
+
* selected.
|
|
114
|
+
*/
|
|
87
115
|
reconcileForComponent(comp) {
|
|
88
116
|
const prev = this._lastClassName;
|
|
89
117
|
this._lastClassName = comp.meta.className;
|
|
90
118
|
if (prev !== null && prev !== comp.meta.className) {
|
|
91
119
|
this.activeVariantIndex.set(0);
|
|
120
|
+
this.activeStateIndex.set(null);
|
|
92
121
|
this.applyVariant(0, comp);
|
|
93
122
|
return;
|
|
94
123
|
}
|
|
124
|
+
const stateIndex = this.activeStateIndex();
|
|
125
|
+
if (stateIndex !== null && stateIndex >= (comp.meta.showcaseConfig.states?.length ?? 0))
|
|
126
|
+
this.activeStateIndex.set(null);
|
|
95
127
|
const variants = comp.meta.showcaseConfig.variants ?? [];
|
|
96
128
|
const maxIndex = Math.max(0, variants.length - 1);
|
|
97
129
|
const preservedIndex = Math.min(this.activeVariantIndex(), maxIndex);
|
|
@@ -125,6 +157,9 @@ export class PrismRendererService {
|
|
|
125
157
|
if (comp)
|
|
126
158
|
this.applyVariant(index, comp);
|
|
127
159
|
}
|
|
160
|
+
selectState(index) {
|
|
161
|
+
this.activeStateIndex.set(index);
|
|
162
|
+
}
|
|
128
163
|
updateInput(name, value) {
|
|
129
164
|
this.inputValues.update((prev) => ({ ...prev, [name]: value }));
|
|
130
165
|
}
|
|
@@ -147,4 +182,4 @@ export class PrismRendererService {
|
|
|
147
182
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PrismRendererService, [{
|
|
148
183
|
type: Injectable,
|
|
149
184
|
args: [{ providedIn: 'root' }]
|
|
150
|
-
}],
|
|
185
|
+
}], () => [], null); })();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prism-url-state.service.d.ts","sourceRoot":"","sources":["../../../src/app/services/prism-url-state.service.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"prism-url-state.service.d.ts","sourceRoot":"","sources":["../../../src/app/services/prism-url-state.service.ts"],"names":[],"mappings":";AAiCA,qBACa,oBAAoB;IAC7B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgC;IAChE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAkC;IACpE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgC;IAChE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA6B;IAC1D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAC/C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAE7C,OAAO,CAAC,YAAY,CAAS;IAE7B,IAAI,IAAI,IAAI;IAsBZ,OAAO,CAAC,cAAc;IA2DtB,OAAO,CAAC,UAAU;yCA3FT,oBAAoB;;CAmIhC"}
|
|
@@ -8,10 +8,25 @@ import * as i0 from "@angular/core";
|
|
|
8
8
|
const PARAM_COMPONENT = 'component';
|
|
9
9
|
const PARAM_PAGE = 'page';
|
|
10
10
|
const PARAM_VARIANT = 'variant';
|
|
11
|
+
const PARAM_STATE = 'state';
|
|
11
12
|
const PARAM_VIEW = 'view';
|
|
12
13
|
const DEFAULT_VIEW = 'renderer';
|
|
13
14
|
const PARAM_PANEL = 'panel';
|
|
14
15
|
const DEFAULT_PANEL = 'controls';
|
|
16
|
+
/** The index a `variant` parameter addresses in a list of `count` variants, `0` for anything that is not one. */
|
|
17
|
+
function parseVariantIndex(param, count) {
|
|
18
|
+
if (param === null)
|
|
19
|
+
return 0;
|
|
20
|
+
const index = parseInt(param, 10);
|
|
21
|
+
return !Number.isNaN(index) && index >= 0 && index < count ? index : 0;
|
|
22
|
+
}
|
|
23
|
+
/** The index a `state` parameter addresses in a list of `count` states, `null` for anything that is not one. */
|
|
24
|
+
function parseStateIndex(param, count) {
|
|
25
|
+
if (param === null || !/^\d+$/.test(param))
|
|
26
|
+
return null;
|
|
27
|
+
const index = Number(param);
|
|
28
|
+
return index < count ? index : null;
|
|
29
|
+
}
|
|
15
30
|
export class PrismUrlStateService {
|
|
16
31
|
manifestService = inject(PrismManifestService);
|
|
17
32
|
navigationService = inject(PrismNavigationService);
|
|
@@ -27,11 +42,12 @@ export class PrismUrlStateService {
|
|
|
27
42
|
effect(() => {
|
|
28
43
|
const item = this.navigationService.activeItem();
|
|
29
44
|
const variantIndex = this.rendererService.activeVariantIndex();
|
|
45
|
+
const stateIndex = this.rendererService.activeStateIndex();
|
|
30
46
|
const viewId = this.panelService.activeViewId();
|
|
31
47
|
const panelId = this.panelService.activePanelId();
|
|
32
48
|
if (this.suppressSync)
|
|
33
49
|
return;
|
|
34
|
-
this.writeToUrl(item, variantIndex, viewId, panelId);
|
|
50
|
+
this.writeToUrl(item, variantIndex, stateIndex, viewId, panelId);
|
|
35
51
|
}, { injector: this.injector });
|
|
36
52
|
window.addEventListener('popstate', () => this.restoreFromUrl());
|
|
37
53
|
}
|
|
@@ -40,21 +56,32 @@ export class PrismUrlStateService {
|
|
|
40
56
|
const componentClassName = params.get(PARAM_COMPONENT);
|
|
41
57
|
const pageTitle = params.get(PARAM_PAGE);
|
|
42
58
|
const variantParam = params.get(PARAM_VARIANT);
|
|
59
|
+
const stateParam = params.get(PARAM_STATE);
|
|
43
60
|
const viewId = params.get(PARAM_VIEW);
|
|
44
61
|
const panelId = params.get(PARAM_PANEL);
|
|
62
|
+
let stateIndex = null;
|
|
45
63
|
this.suppressSync = true;
|
|
46
64
|
try {
|
|
47
65
|
if (componentClassName) {
|
|
48
66
|
const comp = this.manifestService.components().find((c) => c.meta.className === componentClassName);
|
|
49
67
|
if (comp) {
|
|
68
|
+
const previousClassName = this.navigationService.activeComponent()?.meta.className;
|
|
50
69
|
this.navigationService.select(comp);
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
70
|
+
// Switching to another component resets the variant and the state
|
|
71
|
+
// once `PrismRendererService` follows the navigation, after this
|
|
72
|
+
// restore. Starting the component here makes it the current one
|
|
73
|
+
// before the indexes below are set, so that reset, and the renderer
|
|
74
|
+
// mounting it, keep them (a popstate between components). Not for
|
|
75
|
+
// the component already on screen: a popstate that addresses it (a
|
|
76
|
+
// hash link inside it fires one) must keep the control overrides.
|
|
77
|
+
if (previousClassName !== comp.meta.className) {
|
|
78
|
+
this.rendererService.resetForComponent(comp);
|
|
57
79
|
}
|
|
80
|
+
const variantIndex = parseVariantIndex(variantParam, comp.meta.showcaseConfig.variants?.length ?? 1);
|
|
81
|
+
if (variantIndex !== this.rendererService.activeVariantIndex()) {
|
|
82
|
+
this.rendererService.selectVariant(variantIndex);
|
|
83
|
+
}
|
|
84
|
+
stateIndex = parseStateIndex(stateParam, comp.meta.showcaseConfig.states?.length ?? 0);
|
|
58
85
|
}
|
|
59
86
|
}
|
|
60
87
|
else if (pageTitle) {
|
|
@@ -63,6 +90,7 @@ export class PrismUrlStateService {
|
|
|
63
90
|
this.navigationService.selectPage(page);
|
|
64
91
|
}
|
|
65
92
|
}
|
|
93
|
+
this.rendererService.selectState(stateIndex);
|
|
66
94
|
if (viewId) {
|
|
67
95
|
this.panelService.activeViewId.set(viewId);
|
|
68
96
|
}
|
|
@@ -74,7 +102,7 @@ export class PrismUrlStateService {
|
|
|
74
102
|
this.suppressSync = false;
|
|
75
103
|
}
|
|
76
104
|
}
|
|
77
|
-
writeToUrl(item, variantIndex, viewId, panelId) {
|
|
105
|
+
writeToUrl(item, variantIndex, stateIndex, viewId, panelId) {
|
|
78
106
|
// Built from scratch, never from the current search string: parameters the
|
|
79
107
|
// app does not own must not survive a navigation. `?capture=1` relies on
|
|
80
108
|
// this; the "capture flag" specs pin the guarantee.
|
|
@@ -84,6 +112,9 @@ export class PrismUrlStateService {
|
|
|
84
112
|
if (variantIndex > 0) {
|
|
85
113
|
params.set(PARAM_VARIANT, String(variantIndex));
|
|
86
114
|
}
|
|
115
|
+
if (stateIndex !== null) {
|
|
116
|
+
params.set(PARAM_STATE, String(stateIndex));
|
|
117
|
+
}
|
|
87
118
|
}
|
|
88
119
|
else if (item?.kind === 'page') {
|
|
89
120
|
params.set(PARAM_PAGE, item.data.title);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prism-default-theme.d.ts","sourceRoot":"","sources":["../../../src/app/theme/prism-default-theme.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAyCnD,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAyCpD,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"prism-default-theme.d.ts","sourceRoot":"","sources":["../../../src/app/theme/prism-default-theme.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAyCnD,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAyCpD,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA2DpD,CAAC;AAEF,eAAO,MAAM,mBAAmB,wBAAmB,CAAC"}
|
|
@@ -91,13 +91,14 @@ export const PRISM_BASE_TOKENS = {
|
|
|
91
91
|
'--dur-base': '0.2s',
|
|
92
92
|
'--dur-slow': '0.3s',
|
|
93
93
|
/**
|
|
94
|
-
* Chrome density.
|
|
95
|
-
*
|
|
94
|
+
* Chrome density. A consuming app compacts or loosens the entire interface
|
|
95
|
+
* with one token in ng-prism.config.ts:
|
|
96
96
|
*
|
|
97
|
-
*
|
|
97
|
+
* theme: { '--density': '0.8' }
|
|
98
98
|
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
99
|
+
* The band heights below resolve it on <html>, where every token is set,
|
|
100
|
+
* so a --density on a descendant such as prism-shell doesn't reach them.
|
|
101
|
+
* There is no signal, service or menu behind this.
|
|
101
102
|
*/
|
|
102
103
|
'--density': '1',
|
|
103
104
|
'--band-header': 'calc(40px * var(--density))',
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { NgPrismConfig } from '../../plugin/plugin.types.js';
|
|
2
|
+
/**
|
|
3
|
+
* One notice per deprecated option the config or one of its plugins sets.
|
|
4
|
+
* They never had an effect, so the notice only asks to remove them.
|
|
5
|
+
*/
|
|
6
|
+
export declare function describeDeprecatedOptions(config: NgPrismConfig, configFile: string): string[];
|
|
7
|
+
//# sourceMappingURL=deprecated-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deprecated-options.d.ts","sourceRoot":"","sources":["../../../src/builder/config-loader/deprecated-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAOlE;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAe7F"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Config options declared since the first release that nothing has ever read. */
|
|
2
|
+
const DEPRECATED_CONFIG_OPTIONS = ['ui', 'themeStylesheet', 'headless', 'appComponent'];
|
|
3
|
+
const NEVER_HAD_AN_EFFECT = 'which is deprecated and will be removed in 23.0.0. It has never had an effect; remove it.';
|
|
4
|
+
/**
|
|
5
|
+
* One notice per deprecated option the config or one of its plugins sets.
|
|
6
|
+
* They never had an effect, so the notice only asks to remove them.
|
|
7
|
+
*/
|
|
8
|
+
export function describeDeprecatedOptions(config, configFile) {
|
|
9
|
+
const notices = [];
|
|
10
|
+
for (const option of DEPRECATED_CONFIG_OPTIONS) {
|
|
11
|
+
if (config[option] !== undefined)
|
|
12
|
+
notices.push(`${configFile} sets "${option}", ${NEVER_HAD_AN_EFFECT}`);
|
|
13
|
+
}
|
|
14
|
+
for (const plugin of config.plugins ?? []) {
|
|
15
|
+
if (plugin.wrapComponent !== undefined)
|
|
16
|
+
notices.push(`plugin "${plugin.name}" sets wrapComponent, ${NEVER_HAD_AN_EFFECT}`);
|
|
17
|
+
for (const panel of plugin.panels ?? []) {
|
|
18
|
+
if (panel.position !== undefined)
|
|
19
|
+
notices.push(`plugin "${plugin.name}" sets position on panel "${panel.id}", ${NEVER_HAD_AN_EFFECT}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return notices;
|
|
23
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-manifest.generator.d.ts","sourceRoot":"","sources":["../../../src/builder/manifest/runtime-manifest.generator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAa,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAGhF,MAAM,WAAW,sBAAsB;IACnC,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;
|
|
1
|
+
{"version":3,"file":"runtime-manifest.generator.d.ts","sourceRoot":"","sources":["../../../src/builder/manifest/runtime-manifest.generator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAa,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAGhF,MAAM,WAAW,sBAAsB;IACnC,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAqHD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,sBAAsB,GAAG,MAAM,CAkF/E"}
|
|
@@ -68,8 +68,9 @@ function generateWrapperClass(comp) {
|
|
|
68
68
|
attrs = '';
|
|
69
69
|
importsArray = `[${comp.className}]`;
|
|
70
70
|
}
|
|
71
|
-
|
|
72
|
-
const
|
|
71
|
+
// The wrapper declares its inputs and outputs under the member names and binds the directive's public ones.
|
|
72
|
+
const inputBindings = bindableInputs.map((i) => ` [${i.alias ?? i.name}]="${i.name}()"`).join('');
|
|
73
|
+
const outputBindings = comp.outputs.map((o) => ` (${o.alias ?? o.name})="${o.name}.emit($event)"`).join('');
|
|
73
74
|
const template = `<${tag}${attrs} ${directiveAttr}${inputBindings}${outputBindings}>{{ __prismContent__() }}</${tag}>`;
|
|
74
75
|
const members = [];
|
|
75
76
|
for (const i of bindableInputs) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.scanner.d.ts","sourceRoot":"","sources":["../../../src/builder/scanner/component.scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"component.scanner.d.ts","sourceRoot":"","sources":["../../../src/builder/scanner/component.scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAkDrE;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,WAAW,EAAE,WAAW,GAAE,MAAM,EAAO,EAAE,OAAO,cAAoB,GAAG,gBAAgB,EAAE,CAsEzJ"}
|
|
@@ -4,7 +4,9 @@ import { CANVAS_LAYOUTS } from '../../shared/canvas-layout.type.js';
|
|
|
4
4
|
import { evaluateExpression, evaluateStatic, findDecorator, getDecoratorArgument, UNEVALUABLE } from './ast-utils.js';
|
|
5
5
|
import { getClassHierarchy } from './class-hierarchy.js';
|
|
6
6
|
import { extractInputs, extractOutputs } from './input.extractor.js';
|
|
7
|
+
import { describeValue, readPseudoStates } from './pseudo-states.js';
|
|
7
8
|
import { describeDeprecatedProviders, describeUnevaluable, describeUnreadableBase } from './showcase-diagnostics.js';
|
|
9
|
+
import { readShowcaseStates } from './showcase-states.js';
|
|
8
10
|
const COMPONENT_STATUSES = ['stable', 'beta', 'wip', 'deprecated'];
|
|
9
11
|
function isComponentStatus(value) {
|
|
10
12
|
return typeof value === 'string' && COMPONENT_STATUSES.includes(value);
|
|
@@ -122,6 +124,8 @@ function extractShowcaseConfig(decorator, className, report, checker) {
|
|
|
122
124
|
return undefined;
|
|
123
125
|
// Reported once for the whole field below, wherever it came from: the literal, a spread or a constant.
|
|
124
126
|
let providers;
|
|
127
|
+
// A state the evaluator dropped whole leaves no element behind, so its position is noted to keep the later states where the source has them.
|
|
128
|
+
const unevaluableStates = new Set();
|
|
125
129
|
const raw = evaluateStatic(arg, {
|
|
126
130
|
checker,
|
|
127
131
|
report: (issue) => {
|
|
@@ -129,6 +133,8 @@ function extractShowcaseConfig(decorator, className, report, checker) {
|
|
|
129
133
|
providers ??= issue.node;
|
|
130
134
|
return;
|
|
131
135
|
}
|
|
136
|
+
if (issue.path[0] === 'states' && issue.path.length === 2 && typeof issue.path[1] === 'number')
|
|
137
|
+
unevaluableStates.add(issue.path[1]);
|
|
132
138
|
report(describeUnevaluable(className, arg, issue));
|
|
133
139
|
}
|
|
134
140
|
});
|
|
@@ -168,6 +174,16 @@ function extractShowcaseConfig(decorator, className, report, checker) {
|
|
|
168
174
|
config.host = obj['host'];
|
|
169
175
|
if (obj['renderPage'])
|
|
170
176
|
config.renderPage = obj['renderPage'];
|
|
177
|
+
if (obj['states'] !== undefined) {
|
|
178
|
+
if (config.renderPage) {
|
|
179
|
+
report(`${className} declares states together with renderPage; a component page has no Overview to show them in. Skipping states.`);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
const states = readShowcaseStates(obj['states'], className, report, unevaluableStates);
|
|
183
|
+
if (states)
|
|
184
|
+
config.states = states;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
171
187
|
if (obj['status'] !== undefined) {
|
|
172
188
|
if (isComponentStatus(obj['status'])) {
|
|
173
189
|
config.status = obj['status'];
|
|
@@ -210,6 +226,17 @@ function extractShowcaseConfig(decorator, className, report, checker) {
|
|
|
210
226
|
`invalid canvasLayout "${String(variant['canvasLayout'])}", expected one of: ${CANVAS_LAYOUTS.join(', ')}. Skipping.`);
|
|
211
227
|
delete cleaned['canvasLayout'];
|
|
212
228
|
}
|
|
229
|
+
if (variant['pseudo'] !== undefined) {
|
|
230
|
+
const pseudo = readPseudoStates(variant['pseudo'], `${className} variant "${String(variant['name'])}"`, report);
|
|
231
|
+
if (pseudo)
|
|
232
|
+
cleaned['pseudo'] = pseudo;
|
|
233
|
+
else
|
|
234
|
+
delete cleaned['pseudo'];
|
|
235
|
+
}
|
|
236
|
+
if (variant['states'] !== undefined && variant['states'] !== false) {
|
|
237
|
+
report(`${className} variant "${String(variant['name'])}" declares invalid states ${describeValue(variant['states'])}, expected false. Skipping.`);
|
|
238
|
+
delete cleaned['states'];
|
|
239
|
+
}
|
|
213
240
|
return cleaned;
|
|
214
241
|
});
|
|
215
242
|
}
|
|
@@ -3,4 +3,9 @@ export interface DiscoveredEntryPoint {
|
|
|
3
3
|
importPath: string;
|
|
4
4
|
}
|
|
5
5
|
export declare function discoverSecondaryEntryPoints(libraryRoot: string, baseImportPath: string): DiscoveredEntryPoint[];
|
|
6
|
+
/**
|
|
7
|
+
* The primary entry file of the library at `libraryRoot`: `lib.entryFile` of its
|
|
8
|
+
* own `ng-package.json`, or `undefined` when there is no such file.
|
|
9
|
+
*/
|
|
10
|
+
export declare function findPrimaryEntryFile(libraryRoot: string): string | undefined;
|
|
6
11
|
//# sourceMappingURL=entry-point-discovery.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry-point-discovery.d.ts","sourceRoot":"","sources":["../../../src/builder/scanner/entry-point-discovery.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,oBAAoB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,4BAA4B,CAAC,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAKhH"}
|
|
1
|
+
{"version":3,"file":"entry-point-discovery.d.ts","sourceRoot":"","sources":["../../../src/builder/scanner/entry-point-discovery.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,oBAAoB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,4BAA4B,CAAC,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAKhH;AAKD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAS5E"}
|
|
@@ -5,6 +5,20 @@ export function discoverSecondaryEntryPoints(libraryRoot, baseImportPath) {
|
|
|
5
5
|
findNgPackageJsons(libraryRoot, libraryRoot, baseImportPath, entryPoints);
|
|
6
6
|
return entryPoints;
|
|
7
7
|
}
|
|
8
|
+
/** ng-packagr's default for `lib.entryFile`. */
|
|
9
|
+
const NG_PACKAGR_DEFAULT_ENTRY_FILE = 'src/public_api.ts';
|
|
10
|
+
/**
|
|
11
|
+
* The primary entry file of the library at `libraryRoot`: `lib.entryFile` of its
|
|
12
|
+
* own `ng-package.json`, or `undefined` when there is no such file.
|
|
13
|
+
*/
|
|
14
|
+
export function findPrimaryEntryFile(libraryRoot) {
|
|
15
|
+
const ngPackagePath = join(libraryRoot, 'ng-package.json');
|
|
16
|
+
if (!existsSync(ngPackagePath))
|
|
17
|
+
return undefined;
|
|
18
|
+
const ngPackage = JSON.parse(readFileSync(ngPackagePath, 'utf-8'));
|
|
19
|
+
const entryFilePath = join(libraryRoot, ngPackage.lib?.entryFile ?? NG_PACKAGR_DEFAULT_ENTRY_FILE);
|
|
20
|
+
return existsSync(entryFilePath) ? entryFilePath : undefined;
|
|
21
|
+
}
|
|
8
22
|
function findNgPackageJsons(dir, libraryRoot, baseImportPath, result) {
|
|
9
23
|
const isLibraryRoot = dir === libraryRoot;
|
|
10
24
|
const ngPackagePath = join(dir, 'ng-package.json');
|
|
@@ -2,6 +2,8 @@ import ts from 'typescript';
|
|
|
2
2
|
export interface EntryPointInput {
|
|
3
3
|
entryFile: string;
|
|
4
4
|
importPath: string;
|
|
5
|
+
/** The library's primary entry point. A component it re-exports from a secondary one keeps that one, silently. */
|
|
6
|
+
primary?: boolean;
|
|
5
7
|
}
|
|
6
8
|
export interface ResolvedEntryPoint extends EntryPointInput {
|
|
7
9
|
exports: ts.Symbol[];
|
|
@@ -18,5 +20,5 @@ export interface MultiEntryResult {
|
|
|
18
20
|
*
|
|
19
21
|
* Re-exports (`export * from '...'`) are resolved automatically by TypeScript.
|
|
20
22
|
*/
|
|
21
|
-
export declare function resolveEntryPointExports(entryPoints: ReadonlyArray<EntryPointInput>, compilerOptions: ts.CompilerOptions, previousProgram?: ts.Program): MultiEntryResult;
|
|
23
|
+
export declare function resolveEntryPointExports(entryPoints: ReadonlyArray<EntryPointInput>, compilerOptions: ts.CompilerOptions, previousProgram?: ts.Program, host?: ts.CompilerHost): MultiEntryResult;
|
|
22
24
|
//# sourceMappingURL=entry-point.scanner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry-point.scanner.d.ts","sourceRoot":"","sources":["../../../src/builder/scanner/entry-point.scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"entry-point.scanner.d.ts","sourceRoot":"","sources":["../../../src/builder/scanner/entry-point.scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,kHAAkH;IAClH,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IACvD,OAAO,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC;IACpB,OAAO,EAAE,kBAAkB,EAAE,CAAC;CACjC;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACpC,WAAW,EAAE,aAAa,CAAC,eAAe,CAAC,EAC3C,eAAe,EAAE,EAAE,CAAC,eAAe,EACnC,eAAe,CAAC,EAAE,EAAE,CAAC,OAAO,EAC5B,IAAI,CAAC,EAAE,EAAE,CAAC,YAAY,GACvB,gBAAgB,CA8BlB"}
|
|
@@ -7,23 +7,24 @@ import ts from 'typescript';
|
|
|
7
7
|
*
|
|
8
8
|
* Re-exports (`export * from '...'`) are resolved automatically by TypeScript.
|
|
9
9
|
*/
|
|
10
|
-
export function resolveEntryPointExports(entryPoints, compilerOptions, previousProgram) {
|
|
11
|
-
const program = ts.createProgram(entryPoints.map((e) => e.entryFile), compilerOptions,
|
|
10
|
+
export function resolveEntryPointExports(entryPoints, compilerOptions, previousProgram, host) {
|
|
11
|
+
const program = ts.createProgram(entryPoints.map((e) => e.entryFile), compilerOptions, host, previousProgram);
|
|
12
12
|
const checker = program.getTypeChecker();
|
|
13
|
-
const entries = entryPoints.map((
|
|
13
|
+
const entries = entryPoints.map((entryPoint) => {
|
|
14
|
+
const { entryFile } = entryPoint;
|
|
14
15
|
try {
|
|
15
16
|
const sourceFile = program.getSourceFile(entryFile);
|
|
16
17
|
if (!sourceFile) {
|
|
17
18
|
console.warn(`⚠ ng-prism: source file not found for entry point ${entryFile}, skipping.`);
|
|
18
|
-
return {
|
|
19
|
+
return { ...entryPoint, exports: [] };
|
|
19
20
|
}
|
|
20
21
|
const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
|
|
21
22
|
const exports = moduleSymbol ? checker.getExportsOfModule(moduleSymbol) : [];
|
|
22
|
-
return {
|
|
23
|
+
return { ...entryPoint, exports };
|
|
23
24
|
}
|
|
24
25
|
catch (err) {
|
|
25
26
|
console.error(`⚠ ng-prism: failed to resolve exports for ${entryFile}: ${err instanceof Error ? err.message : String(err)}`);
|
|
26
|
-
return {
|
|
27
|
+
return { ...entryPoint, exports: [] };
|
|
27
28
|
}
|
|
28
29
|
});
|
|
29
30
|
return { program, entries };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.extractor.d.ts","sourceRoot":"","sources":["../../../src/builder/scanner/input.extractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAI1E;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,EAAE,CAAC,gBAAgB,EAAE,OAAO,EAAE,EAAE,CAAC,WAAW,EAAE,SAAS,gDAAwC,GAAG,SAAS,EAAE,CAuCrJ;
|
|
1
|
+
{"version":3,"file":"input.extractor.d.ts","sourceRoot":"","sources":["../../../src/builder/scanner/input.extractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAI1E;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,EAAE,CAAC,gBAAgB,EAAE,OAAO,EAAE,EAAE,CAAC,WAAW,EAAE,SAAS,gDAAwC,GAAG,SAAS,EAAE,CAuCrJ;AAwFD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,EAAE,CAAC,gBAAgB,EAAE,OAAO,EAAE,EAAE,CAAC,WAAW,EAAE,SAAS,gDAAwC,GAAG,UAAU,EAAE,CA4BvJ"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
import { evaluateStatic, findDecorator, getDecoratorArgument, getJsDocComment } from './ast-utils.js';
|
|
2
|
+
import { evaluateExpression, evaluateStatic, findDecorator, getDecoratorArgument, getJsDocComment } from './ast-utils.js';
|
|
3
3
|
import { getClassHierarchy } from './class-hierarchy.js';
|
|
4
4
|
/**
|
|
5
5
|
* Extract all @Input(), input() and model() signal metadata from a class
|
|
@@ -58,12 +58,14 @@ function readInput(member, name, checker, owner, subclass) {
|
|
|
58
58
|
const inputDecorator = findDecorator(member, 'Input');
|
|
59
59
|
if (inputDecorator) {
|
|
60
60
|
const required = isDecoratorInputRequired(inputDecorator);
|
|
61
|
+
const alias = readAlias(getDecoratorArgument(inputDecorator), name, checker);
|
|
61
62
|
const defaultValue = readInitialValue(member, checker);
|
|
62
63
|
const doc = getJsDocComment(member, checker);
|
|
63
64
|
const instantiated = subclass && usesTypeParameters(member.type ?? member.initializer, owner, checker) ? getInstantiatedType(name, subclass, checker) : undefined;
|
|
64
65
|
const { type, values, rawType } = instantiated ? mapType(instantiated, checker) : resolveDecoratorInputType(member, checker);
|
|
65
66
|
return {
|
|
66
67
|
name,
|
|
68
|
+
...(alias && { alias }),
|
|
67
69
|
type,
|
|
68
70
|
rawType,
|
|
69
71
|
required,
|
|
@@ -76,6 +78,8 @@ function readInput(member, name, checker, owner, subclass) {
|
|
|
76
78
|
if (!signalCall)
|
|
77
79
|
return undefined;
|
|
78
80
|
const required = isSignalInputRequired(signalCall);
|
|
81
|
+
// `input(initial, options)`, but `input.required(options)`.
|
|
82
|
+
const alias = readAlias(signalCall.arguments[required ? 0 : 1], name, checker);
|
|
79
83
|
const defaultValue = readInitialValue(member, checker);
|
|
80
84
|
const doc = getJsDocComment(member, checker);
|
|
81
85
|
const declaredType = signalCall.typeArguments?.[0] ?? signalCall.arguments[0];
|
|
@@ -84,6 +88,7 @@ function readInput(member, name, checker, owner, subclass) {
|
|
|
84
88
|
const { type, values, rawType } = instantiated ? mapType(instantiated, checker) : resolveSignalInputType(signalCall, checker);
|
|
85
89
|
return {
|
|
86
90
|
name,
|
|
91
|
+
...(alias && { alias }),
|
|
87
92
|
type,
|
|
88
93
|
rawType,
|
|
89
94
|
required,
|
|
@@ -92,6 +97,17 @@ function readInput(member, name, checker, owner, subclass) {
|
|
|
92
97
|
...(doc && { doc })
|
|
93
98
|
};
|
|
94
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* The `alias` of an input or output, from a decorator argument (`'x'` or
|
|
102
|
+
* `{ alias: 'x' }`) or the options of `input()`, `model()` and `output()`.
|
|
103
|
+
* It counts when the builder can evaluate it statically to a string (a literal
|
|
104
|
+
* or a constant) that differs from the member name.
|
|
105
|
+
*/
|
|
106
|
+
function readAlias(arg, name, checker) {
|
|
107
|
+
const value = arg ? evaluateExpression(arg, checker) : undefined;
|
|
108
|
+
const alias = typeof value === 'object' && value !== null ? value['alias'] : value;
|
|
109
|
+
return typeof alias === 'string' && alias !== name ? alias : undefined;
|
|
110
|
+
}
|
|
95
111
|
/**
|
|
96
112
|
* Extract all @Output() and output() signal metadata from a class declaration
|
|
97
113
|
* and the base classes Angular inherits outputs from.
|
|
@@ -108,11 +124,14 @@ export function extractOutputs(classDecl, checker, hierarchy = getClassHierarchy
|
|
|
108
124
|
const name = member.name && ts.isIdentifier(member.name) ? member.name.text : undefined;
|
|
109
125
|
if (!name || seen.has(name))
|
|
110
126
|
continue;
|
|
111
|
-
|
|
127
|
+
const outputDecorator = findDecorator(member, 'Output');
|
|
128
|
+
if (!outputDecorator && !isOutputSignal(member))
|
|
112
129
|
continue;
|
|
113
130
|
const doc = getJsDocComment(member, checker);
|
|
131
|
+
const options = outputDecorator ? getDecoratorArgument(outputDecorator) : member.initializer.arguments[0];
|
|
132
|
+
const alias = readAlias(options, name, checker);
|
|
114
133
|
seen.add(name);
|
|
115
|
-
outputs.push({ name, ...(doc && { doc }) });
|
|
134
|
+
outputs.push({ name, ...(alias && { alias }), ...(doc && { doc }) });
|
|
116
135
|
}
|
|
117
136
|
}
|
|
118
137
|
return outputs;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ForcedPseudoStates } from '../../shared/pseudo-state.type.js';
|
|
2
|
+
export declare function describeValue(value: unknown): string;
|
|
3
|
+
/**
|
|
4
|
+
* `Variant.pseudo` as the scanner evaluated it, with everything it cannot use
|
|
5
|
+
* reported and dropped: a value that is no object, an unknown state, and a
|
|
6
|
+
* target that is neither `true` nor selectors. `undefined` when nothing is left.
|
|
7
|
+
*
|
|
8
|
+
* Selectors are checked to be non-empty strings only. Whether one parses is up
|
|
9
|
+
* to the browser, which warns about it once the variant renders.
|
|
10
|
+
*/
|
|
11
|
+
export declare function readPseudoStates(value: unknown, where: string, report: (message: string) => void): ForcedPseudoStates | undefined;
|
|
12
|
+
//# sourceMappingURL=pseudo-states.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pseudo-states.d.ts","sourceRoot":"","sources":["../../../src/builder/scanner/pseudo-states.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAsD,MAAM,mCAAmC,CAAC;AAUhI,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGpD;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,kBAAkB,GAAG,SAAS,CAmBjI"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { PSEUDO_STATES } from '../../shared/pseudo-state.type.js';
|
|
2
|
+
function isPseudoState(value) {
|
|
3
|
+
return PSEUDO_STATES.includes(value);
|
|
4
|
+
}
|
|
5
|
+
function isSelector(value) {
|
|
6
|
+
return typeof value === 'string' && value.trim() !== '';
|
|
7
|
+
}
|
|
8
|
+
export function describeValue(value) {
|
|
9
|
+
if (typeof value === 'string' || (typeof value === 'object' && value !== null))
|
|
10
|
+
return JSON.stringify(value) ?? String(value);
|
|
11
|
+
return String(value);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* `Variant.pseudo` as the scanner evaluated it, with everything it cannot use
|
|
15
|
+
* reported and dropped: a value that is no object, an unknown state, and a
|
|
16
|
+
* target that is neither `true` nor selectors. `undefined` when nothing is left.
|
|
17
|
+
*
|
|
18
|
+
* Selectors are checked to be non-empty strings only. Whether one parses is up
|
|
19
|
+
* to the browser, which warns about it once the variant renders.
|
|
20
|
+
*/
|
|
21
|
+
export function readPseudoStates(value, where, report) {
|
|
22
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
23
|
+
report(`${where} declares invalid pseudo ${describeValue(value)}, expected an object mapping pseudo states to true or selectors. Skipping.`);
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
const states = {};
|
|
27
|
+
for (const [state, target] of Object.entries(value)) {
|
|
28
|
+
if (!isPseudoState(state)) {
|
|
29
|
+
report(`${where} declares unknown pseudo state "${state}", expected one of: ${PSEUDO_STATES.join(', ')}. Skipping.`);
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const read = readTarget(target, `${where} declares pseudo state "${state}"`, report);
|
|
33
|
+
if (read !== undefined)
|
|
34
|
+
states[state] = read;
|
|
35
|
+
}
|
|
36
|
+
return Object.keys(states).length > 0 ? states : undefined;
|
|
37
|
+
}
|
|
38
|
+
function readTarget(target, where, report) {
|
|
39
|
+
if (target === true || isSelector(target))
|
|
40
|
+
return target;
|
|
41
|
+
if (typeof target === 'string') {
|
|
42
|
+
report(`${where} with an empty selector. Skipping.`);
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
if (Array.isArray(target)) {
|
|
46
|
+
const selectors = target.filter(isSelector);
|
|
47
|
+
const invalid = target.filter((entry) => !isSelector(entry));
|
|
48
|
+
if (invalid.length > 0) {
|
|
49
|
+
report(`${where} with ${invalid.map(describeValue).join(', ')} in its selector list, expected non-empty strings. Skipping ${invalid.length === 1 ? 'it' : 'them'}.`);
|
|
50
|
+
}
|
|
51
|
+
else if (selectors.length === 0) {
|
|
52
|
+
report(`${where} with an empty selector list. Skipping.`);
|
|
53
|
+
}
|
|
54
|
+
return selectors.length > 0 ? selectors : undefined;
|
|
55
|
+
}
|
|
56
|
+
report(`${where} with invalid target ${describeValue(target)}, expected true, a selector or a list of selectors. Skipping.`);
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
@@ -20,8 +20,8 @@ export interface Scanner {
|
|
|
20
20
|
* transitive type graph (Angular framework typings, etc.) is parsed once and shared via
|
|
21
21
|
* the program's `TypeChecker`, instead of N programs that each load Material/CDK/RxJS.
|
|
22
22
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* On rebuild, the source-file cache hands TypeScript the already parsed SourceFile of
|
|
24
|
+
* every unchanged file, so only the changed files are parsed again.
|
|
25
25
|
*/
|
|
26
26
|
export declare function createScanner(options: CreateScannerOptions): Scanner;
|
|
27
27
|
//# sourceMappingURL=scanner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../../src/builder/scanner/scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAErE,OAAO,EAAE,KAAK,eAAe,EAA4B,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../../src/builder/scanner/scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAErE,OAAO,EAAE,KAAK,eAAe,EAA4B,MAAM,0BAA0B,CAAC;AAG1F,MAAM,WAAW,oBAAoB;IACjC,WAAW,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC5C,eAAe,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC;CACxC;AAED,MAAM,WAAW,UAAU;IACvB,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B,0FAA0F;IAC1F,WAAW,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,OAAO;IACpB,kFAAkF;IAClF,IAAI,IAAI,UAAU,CAAC;CACtB;AAkBD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CA0DpE"}
|