@ng-prism/core 21.12.0-beta.0 → 21.12.0-beta.2
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/dist/app/header/prism-header-widget-host.component.d.ts +11 -0
- package/dist/app/header/prism-header-widget-host.component.d.ts.map +1 -0
- package/dist/app/header/prism-header-widget-host.component.js +57 -0
- package/dist/app/header/prism-header.component.d.ts +3 -0
- package/dist/app/header/prism-header.component.d.ts.map +1 -1
- package/dist/app/header/prism-header.component.js +76 -20
- package/dist/app/panels/a11y/a11y-header-badge.component.d.ts +16 -0
- package/dist/app/panels/a11y/a11y-header-badge.component.d.ts.map +1 -0
- package/dist/app/panels/a11y/a11y-header-badge.component.js +84 -0
- package/dist/app/panels/a11y/a11y-thresholds.d.ts +6 -0
- package/dist/app/panels/a11y/a11y-thresholds.d.ts.map +1 -0
- package/dist/app/panels/a11y/a11y-thresholds.js +13 -0
- package/dist/app/panels/a11y/a11y.types.d.ts +33 -0
- package/dist/app/panels/a11y/a11y.types.d.ts.map +1 -1
- package/dist/app/panels/builtin-header-widgets.d.ts +3 -0
- package/dist/app/panels/builtin-header-widgets.d.ts.map +1 -0
- package/dist/app/panels/builtin-header-widgets.js +9 -0
- package/dist/app/panels/panel-host/prism-panel-host.component.d.ts +16 -5
- package/dist/app/panels/panel-host/prism-panel-host.component.d.ts.map +1 -1
- package/dist/app/panels/panel-host/prism-panel-host.component.js +91 -44
- package/dist/app/provide-prism.d.ts.map +1 -1
- package/dist/app/provide-prism.js +11 -0
- package/dist/app/renderer/prism-renderer.component.d.ts +2 -0
- package/dist/app/renderer/prism-renderer.component.d.ts.map +1 -1
- package/dist/app/renderer/prism-renderer.component.js +18 -3
- package/dist/app/services/prism-panel.service.d.ts +5 -0
- package/dist/app/services/prism-panel.service.d.ts.map +1 -1
- package/dist/app/services/prism-panel.service.js +7 -3
- package/dist/app/services/prism-plugin.service.d.ts +4 -1
- package/dist/app/services/prism-plugin.service.d.ts.map +1 -1
- package/dist/app/services/prism-plugin.service.js +11 -0
- package/dist/builder/a11y/a11y-report-reader.d.ts +12 -0
- package/dist/builder/a11y/a11y-report-reader.d.ts.map +1 -0
- package/dist/builder/a11y/a11y-report-reader.js +49 -0
- package/dist/builder/manifest/runtime-manifest.generator.d.ts +1 -0
- package/dist/builder/manifest/runtime-manifest.generator.d.ts.map +1 -1
- package/dist/builder/manifest/runtime-manifest.generator.js +8 -1
- package/dist/builder/plugin-runner/plugin-runner.d.ts.map +1 -1
- package/dist/builder/plugin-runner/plugin-runner.js +3 -1
- package/dist/builder/shared/prism-pipeline.d.ts.map +1 -1
- package/dist/builder/shared/prism-pipeline.js +19 -1
- package/dist/cli/audit-a11y/aggregator.d.ts +10 -0
- package/dist/cli/audit-a11y/aggregator.d.ts.map +1 -0
- package/dist/cli/audit-a11y/aggregator.js +64 -0
- package/dist/cli/audit-a11y/auditor.d.ts +14 -0
- package/dist/cli/audit-a11y/auditor.d.ts.map +1 -0
- package/dist/cli/audit-a11y/auditor.js +104 -0
- package/dist/cli/audit-a11y/cli.d.ts +3 -0
- package/dist/cli/audit-a11y/cli.d.ts.map +1 -0
- package/dist/cli/audit-a11y/cli.js +143 -0
- package/dist/cli/audit-a11y/index.d.ts +4 -0
- package/dist/cli/audit-a11y/index.d.ts.map +1 -0
- package/dist/cli/audit-a11y/index.js +3 -0
- package/dist/cli/audit-a11y/static-server.d.ts +11 -0
- package/dist/cli/audit-a11y/static-server.d.ts.map +1 -0
- package/dist/cli/audit-a11y/static-server.js +61 -0
- package/dist/plugin/index.d.ts +2 -2
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1 -1
- package/dist/plugin/plugin.types.d.ts +33 -0
- package/dist/plugin/plugin.types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NgComponentOutlet } from '@angular/common';
|
|
2
|
-
import { Component, computed, effect, EnvironmentInjector, inject, signal, ChangeDetectionStrategy, } from '@angular/core';
|
|
2
|
+
import { Component, computed, effect, EnvironmentInjector, inject, signal, ChangeDetectionStrategy, untracked, } from '@angular/core';
|
|
3
3
|
import { PrismIconComponent } from '../../icons/prism-icon.component.js';
|
|
4
4
|
import { BUILTIN_PANELS } from '../builtin-panels.js';
|
|
5
5
|
import { A11yAuditService } from '../a11y/a11y-audit.service.js';
|
|
@@ -10,13 +10,13 @@ import { PrismRendererService } from '../../services/prism-renderer.service.js';
|
|
|
10
10
|
import * as i0 from "@angular/core";
|
|
11
11
|
const _forTrack0 = ($index, $item) => $item.id;
|
|
12
12
|
function PrismPanelHostComponent_For_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
13
|
-
i0.ɵɵelement(0, "prism-icon",
|
|
13
|
+
i0.ɵɵelement(0, "prism-icon", 6);
|
|
14
14
|
} if (rf & 2) {
|
|
15
15
|
const panel_r2 = i0.ɵɵnextContext().$implicit;
|
|
16
16
|
i0.ɵɵproperty("name", panel_r2.icon)("size", 13);
|
|
17
17
|
} }
|
|
18
18
|
function PrismPanelHostComponent_For_3_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
19
|
-
i0.ɵɵelementStart(0, "span",
|
|
19
|
+
i0.ɵɵelementStart(0, "span", 8);
|
|
20
20
|
i0.ɵɵtext(1);
|
|
21
21
|
i0.ɵɵelementEnd();
|
|
22
22
|
} if (rf & 2) {
|
|
@@ -27,11 +27,11 @@ function PrismPanelHostComponent_For_3_Conditional_3_Template(rf, ctx) { if (rf
|
|
|
27
27
|
} }
|
|
28
28
|
function PrismPanelHostComponent_For_3_Template(rf, ctx) { if (rf & 1) {
|
|
29
29
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
30
|
-
i0.ɵɵelementStart(0, "button",
|
|
30
|
+
i0.ɵɵelementStart(0, "button", 5);
|
|
31
31
|
i0.ɵɵlistener("click", function PrismPanelHostComponent_For_3_Template_button_click_0_listener() { const panel_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.panelService.activePanelId.set(panel_r2.id)); });
|
|
32
|
-
i0.ɵɵconditionalCreate(1, PrismPanelHostComponent_For_3_Conditional_1_Template, 1, 2, "prism-icon",
|
|
32
|
+
i0.ɵɵconditionalCreate(1, PrismPanelHostComponent_For_3_Conditional_1_Template, 1, 2, "prism-icon", 6);
|
|
33
33
|
i0.ɵɵtext(2);
|
|
34
|
-
i0.ɵɵconditionalCreate(3, PrismPanelHostComponent_For_3_Conditional_3_Template, 2, 7, "span",
|
|
34
|
+
i0.ɵɵconditionalCreate(3, PrismPanelHostComponent_For_3_Conditional_3_Template, 2, 7, "span", 7);
|
|
35
35
|
i0.ɵɵelementEnd();
|
|
36
36
|
} if (rf & 2) {
|
|
37
37
|
let tmp_15_0;
|
|
@@ -46,14 +46,19 @@ function PrismPanelHostComponent_For_3_Template(rf, ctx) { if (rf & 1) {
|
|
|
46
46
|
i0.ɵɵadvance();
|
|
47
47
|
i0.ɵɵconditional((tmp_15_0 = ctx_r2.panelBadge(panel_r2.id)) ? 3 : -1, tmp_15_0);
|
|
48
48
|
} }
|
|
49
|
-
function
|
|
49
|
+
function PrismPanelHostComponent_For_6_ng_container_1_Template(rf, ctx) { if (rf & 1) {
|
|
50
50
|
i0.ɵɵelementContainer(0);
|
|
51
51
|
} }
|
|
52
|
-
function
|
|
53
|
-
i0.ɵɵ
|
|
52
|
+
function PrismPanelHostComponent_For_6_Template(rf, ctx) { if (rf & 1) {
|
|
53
|
+
i0.ɵɵelementStart(0, "div", 4);
|
|
54
|
+
i0.ɵɵtemplate(1, PrismPanelHostComponent_For_6_ng_container_1_Template, 1, 0, "ng-container", 9);
|
|
55
|
+
i0.ɵɵelementEnd();
|
|
54
56
|
} if (rf & 2) {
|
|
57
|
+
const entry_r5 = ctx.$implicit;
|
|
55
58
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
56
|
-
i0.ɵɵproperty("
|
|
59
|
+
i0.ɵɵproperty("hidden", entry_r5.id !== ctx_r2.panelService.activePanelId());
|
|
60
|
+
i0.ɵɵadvance();
|
|
61
|
+
i0.ɵɵproperty("ngComponentOutlet", entry_r5.component)("ngComponentOutletInputs", ctx_r2.panelInputs())("ngComponentOutletInjector", entry_r5.injector ?? ctx_r2.envInjector);
|
|
57
62
|
} }
|
|
58
63
|
export class PrismPanelHostComponent {
|
|
59
64
|
pluginService = inject(PrismPluginService);
|
|
@@ -110,12 +115,12 @@ export class PrismPanelHostComponent {
|
|
|
110
115
|
return panels;
|
|
111
116
|
return panels.filter((p) => !p.isVisible || p.isVisible(comp));
|
|
112
117
|
}, ...(ngDevMode ? [{ debugName: "allPanels" }] : []));
|
|
113
|
-
resolvedComponent = signal(null, ...(ngDevMode ? [{ debugName: "resolvedComponent" }] : []));
|
|
114
118
|
panelInputs = computed(() => ({
|
|
115
119
|
activeComponent: this.nav.activeComponent(),
|
|
116
120
|
}), ...(ngDevMode ? [{ debugName: "panelInputs" }] : []));
|
|
117
121
|
lazyCache = new Map();
|
|
118
|
-
|
|
122
|
+
renderedPanels = signal(new Map(), ...(ngDevMode ? [{ debugName: "renderedPanels" }] : []));
|
|
123
|
+
renderedPanelsArray = computed(() => Array.from(this.renderedPanels().values()), ...(ngDevMode ? [{ debugName: "renderedPanelsArray" }] : []));
|
|
119
124
|
constructor() {
|
|
120
125
|
effect(() => {
|
|
121
126
|
const element = this.rendererService.renderedElement();
|
|
@@ -134,36 +139,73 @@ export class PrismPanelHostComponent {
|
|
|
134
139
|
this.auditService.scheduleAudit(element, a11yConfig);
|
|
135
140
|
});
|
|
136
141
|
effect(() => {
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
const activeId = this.panelService.activePanelId();
|
|
143
|
+
const panels = this.allPanels();
|
|
144
|
+
untracked(() => {
|
|
145
|
+
const panel = panels.find((p) => p.id === activeId) ?? null;
|
|
146
|
+
if (panel) {
|
|
147
|
+
this.ensurePanelLoaded(panel);
|
|
148
|
+
}
|
|
149
|
+
this.pruneRenderedPanels(panels, panel ? activeId : null);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
ensurePanelLoaded(panel) {
|
|
154
|
+
if (this.renderedPanels().has(panel.id))
|
|
155
|
+
return;
|
|
156
|
+
if (panel.component) {
|
|
157
|
+
this.addRenderedPanel(panel, panel.component);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (panel.loadComponent) {
|
|
161
|
+
const cached = this.lazyCache.get(panel.id);
|
|
162
|
+
if (cached) {
|
|
163
|
+
this.addRenderedPanel(panel, cached);
|
|
144
164
|
return;
|
|
145
165
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
if (
|
|
149
|
-
this.resolvedComponent.set(cached);
|
|
166
|
+
panel.loadComponent().then((comp) => {
|
|
167
|
+
this.lazyCache.set(panel.id, comp);
|
|
168
|
+
if (this.renderedPanels().has(panel.id))
|
|
150
169
|
return;
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
170
|
+
this.addRenderedPanel(panel, comp);
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
addRenderedPanel(panel, component) {
|
|
175
|
+
const next = new Map(this.renderedPanels());
|
|
176
|
+
next.set(panel.id, {
|
|
177
|
+
id: panel.id,
|
|
178
|
+
component,
|
|
179
|
+
injector: this.panelService.getInjector(panel.id),
|
|
180
|
+
keepAlive: panel.keepAlive === true,
|
|
158
181
|
});
|
|
182
|
+
this.renderedPanels.set(next);
|
|
183
|
+
}
|
|
184
|
+
pruneRenderedPanels(visiblePanels, activeId) {
|
|
185
|
+
const current = this.renderedPanels();
|
|
186
|
+
if (current.size === 0)
|
|
187
|
+
return;
|
|
188
|
+
const visibleIds = new Set(visiblePanels.map((p) => p.id));
|
|
189
|
+
const next = new Map(current);
|
|
190
|
+
let changed = false;
|
|
191
|
+
for (const [id, entry] of current) {
|
|
192
|
+
const isVisible = visibleIds.has(id);
|
|
193
|
+
const isActive = id === activeId;
|
|
194
|
+
if (!isVisible || (!isActive && !entry.keepAlive)) {
|
|
195
|
+
next.delete(id);
|
|
196
|
+
changed = true;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (changed)
|
|
200
|
+
this.renderedPanels.set(next);
|
|
159
201
|
}
|
|
160
202
|
static ɵfac = function PrismPanelHostComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || PrismPanelHostComponent)(); };
|
|
161
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PrismPanelHostComponent, selectors: [["prism-panel-host"]], decls:
|
|
203
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PrismPanelHostComponent, selectors: [["prism-panel-host"]], decls: 7, vars: 1, consts: [[1, "panel"], ["role", "tablist", 1, "panel-tabs"], ["role", "tab", 1, "p-tab", 3, "p-tab--active"], ["role", "tabpanel", 1, "panel-body", 3, "id"], [1, "panel-pane", 3, "hidden"], ["role", "tab", 1, "p-tab", 3, "click"], [3, "name", "size"], [1, "p-tab-badge", 3, "ok", "warn", "danger"], [1, "p-tab-badge"], [4, "ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector"]], template: function PrismPanelHostComponent_Template(rf, ctx) { if (rf & 1) {
|
|
162
204
|
i0.ɵɵelementStart(0, "div", 0)(1, "nav", 1);
|
|
163
205
|
i0.ɵɵrepeaterCreate(2, PrismPanelHostComponent_For_3_Template, 4, 7, "button", 2, _forTrack0);
|
|
164
206
|
i0.ɵɵelementEnd();
|
|
165
207
|
i0.ɵɵelementStart(4, "div", 3);
|
|
166
|
-
i0.ɵɵ
|
|
208
|
+
i0.ɵɵrepeaterCreate(5, PrismPanelHostComponent_For_6_Template, 2, 4, "div", 4, _forTrack0);
|
|
167
209
|
i0.ɵɵelementEnd()();
|
|
168
210
|
} if (rf & 2) {
|
|
169
211
|
i0.ɵɵadvance(2);
|
|
@@ -171,8 +213,8 @@ export class PrismPanelHostComponent {
|
|
|
171
213
|
i0.ɵɵadvance(2);
|
|
172
214
|
i0.ɵɵproperty("id", "panel-" + ctx.panelService.activePanelId());
|
|
173
215
|
i0.ɵɵadvance();
|
|
174
|
-
i0.ɵɵ
|
|
175
|
-
} }, dependencies: [NgComponentOutlet, PrismIconComponent], styles: [".panel[_ngcontent-%COMP%] {\n background: var(--prism-bg-elevated);\n border-top: 1px solid var(--prism-border);\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n height: 100%;\n }\n\n .panel-tabs[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 0 16px;\n height: 40px;\n border-bottom: 1px solid var(--prism-border);\n background: var(--prism-bg);\n overflow-x: auto;\n scrollbar-width: none;\n flex-shrink: 0;\n }\n .panel-tabs[_ngcontent-%COMP%]::-webkit-scrollbar { display: none; }\n\n .p-tab[_ngcontent-%COMP%] {\n position: relative;\n height: 100%;\n display: flex;\n align-items: center;\n gap: 7px;\n padding: 0 12px;\n font-size: var(--fs-md);\n font-weight: 500;\n color: var(--prism-text-muted);\n white-space: nowrap;\n transition: color var(--dur-fast);\n background: none;\n border: none;\n cursor: pointer;\n font-family: var(--font-sans);\n }\n .p-tab[_ngcontent-%COMP%]:hover { color: var(--prism-text-2); }\n .p-tab--active[_ngcontent-%COMP%] { color: var(--prism-text); }\n .p-tab--active[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n left: 8px;\n right: 8px;\n bottom: -1px;\n height: 2px;\n background: linear-gradient(90deg, var(--prism-primary-from), var(--prism-primary-to));\n border-radius: 1px;\n }\n\n .p-tab-badge[_ngcontent-%COMP%] {\n min-width: 16px;\n height: 16px;\n padding: 0 5px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--prism-primary) 18%, transparent);\n color: var(--prism-primary);\n font-family: var(--font-mono);\n font-size: 10px;\n font-weight: 700;\n display: grid;\n place-items: center;\n }\n .p-tab-badge.ok[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--prism-success) 18%, transparent);\n color: var(--prism-success);\n }\n .p-tab-badge.warn[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--prism-warn) 18%, transparent);\n color: var(--prism-warn);\n }\n .p-tab-badge.danger[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--prism-danger) 18%, transparent);\n color: var(--prism-danger);\n }\n\n .panel-tabs-right[_ngcontent-%COMP%] {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 4px;\n padding-left: 10px;\n }\n\n .icon-btn[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n display: grid;\n place-items: center;\n border-radius: var(--radius-sm);\n color: var(--prism-text-muted);\n background: none;\n border: none;\n cursor: pointer;\n transition: all var(--dur-fast);\n }\n .icon-btn[_ngcontent-%COMP%]:hover {\n background: var(--prism-input-bg);\n color: var(--prism-text);\n }\n\n .panel-body[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: auto;\n background: var(--prism-bg-elevated);\n }\n .panel-body[_ngcontent-%COMP%]::-webkit-scrollbar { width: 8px; height: 8px; }\n .panel-body[_ngcontent-%COMP%]::-webkit-scrollbar-thumb { background: var(--prism-border-strong); border-radius: 4px; }\n\n [_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--prism-primary);\n outline-offset: 2px;\n }"], changeDetection: 0 });
|
|
216
|
+
i0.ɵɵrepeater(ctx.renderedPanelsArray());
|
|
217
|
+
} }, dependencies: [NgComponentOutlet, PrismIconComponent], styles: [".panel[_ngcontent-%COMP%] {\n background: var(--prism-bg-elevated);\n border-top: 1px solid var(--prism-border);\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n height: 100%;\n }\n\n .panel-tabs[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 0 16px;\n height: 40px;\n border-bottom: 1px solid var(--prism-border);\n background: var(--prism-bg);\n overflow-x: auto;\n scrollbar-width: none;\n flex-shrink: 0;\n }\n .panel-tabs[_ngcontent-%COMP%]::-webkit-scrollbar { display: none; }\n\n .p-tab[_ngcontent-%COMP%] {\n position: relative;\n height: 100%;\n display: flex;\n align-items: center;\n gap: 7px;\n padding: 0 12px;\n font-size: var(--fs-md);\n font-weight: 500;\n color: var(--prism-text-muted);\n white-space: nowrap;\n transition: color var(--dur-fast);\n background: none;\n border: none;\n cursor: pointer;\n font-family: var(--font-sans);\n }\n .p-tab[_ngcontent-%COMP%]:hover { color: var(--prism-text-2); }\n .p-tab--active[_ngcontent-%COMP%] { color: var(--prism-text); }\n .p-tab--active[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n left: 8px;\n right: 8px;\n bottom: -1px;\n height: 2px;\n background: linear-gradient(90deg, var(--prism-primary-from), var(--prism-primary-to));\n border-radius: 1px;\n }\n\n .p-tab-badge[_ngcontent-%COMP%] {\n min-width: 16px;\n height: 16px;\n padding: 0 5px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--prism-primary) 18%, transparent);\n color: var(--prism-primary);\n font-family: var(--font-mono);\n font-size: 10px;\n font-weight: 700;\n display: grid;\n place-items: center;\n }\n .p-tab-badge.ok[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--prism-success) 18%, transparent);\n color: var(--prism-success);\n }\n .p-tab-badge.warn[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--prism-warn) 18%, transparent);\n color: var(--prism-warn);\n }\n .p-tab-badge.danger[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--prism-danger) 18%, transparent);\n color: var(--prism-danger);\n }\n\n .panel-tabs-right[_ngcontent-%COMP%] {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 4px;\n padding-left: 10px;\n }\n\n .icon-btn[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n display: grid;\n place-items: center;\n border-radius: var(--radius-sm);\n color: var(--prism-text-muted);\n background: none;\n border: none;\n cursor: pointer;\n transition: all var(--dur-fast);\n }\n .icon-btn[_ngcontent-%COMP%]:hover {\n background: var(--prism-input-bg);\n color: var(--prism-text);\n }\n\n .panel-body[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: auto;\n background: var(--prism-bg-elevated);\n }\n .panel-body[_ngcontent-%COMP%]::-webkit-scrollbar { width: 8px; height: 8px; }\n .panel-body[_ngcontent-%COMP%]::-webkit-scrollbar-thumb { background: var(--prism-border-strong); border-radius: 4px; }\n\n .panel-pane[_ngcontent-%COMP%] { height: 100%; }\n .panel-pane[hidden][_ngcontent-%COMP%] { display: none; }\n\n [_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--prism-primary);\n outline-offset: 2px;\n }"], changeDetection: 0 });
|
|
176
218
|
}
|
|
177
219
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PrismPanelHostComponent, [{
|
|
178
220
|
type: Component,
|
|
@@ -213,17 +255,22 @@ export class PrismPanelHostComponent {
|
|
|
213
255
|
[id]="'panel-' + panelService.activePanelId()"
|
|
214
256
|
role="tabpanel"
|
|
215
257
|
>
|
|
216
|
-
@
|
|
217
|
-
<
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
258
|
+
@for (entry of renderedPanelsArray(); track entry.id) {
|
|
259
|
+
<div
|
|
260
|
+
class="panel-pane"
|
|
261
|
+
[hidden]="entry.id !== panelService.activePanelId()"
|
|
262
|
+
>
|
|
263
|
+
<ng-container
|
|
264
|
+
*ngComponentOutlet="
|
|
265
|
+
entry.component;
|
|
266
|
+
inputs: panelInputs();
|
|
267
|
+
injector: entry.injector ?? envInjector
|
|
268
|
+
"
|
|
269
|
+
/>
|
|
270
|
+
</div>
|
|
224
271
|
}
|
|
225
272
|
</div>
|
|
226
273
|
</div>
|
|
227
|
-
`, styles: ["\n .panel {\n background: var(--prism-bg-elevated);\n border-top: 1px solid var(--prism-border);\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n height: 100%;\n }\n\n .panel-tabs {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 0 16px;\n height: 40px;\n border-bottom: 1px solid var(--prism-border);\n background: var(--prism-bg);\n overflow-x: auto;\n scrollbar-width: none;\n flex-shrink: 0;\n }\n .panel-tabs::-webkit-scrollbar { display: none; }\n\n .p-tab {\n position: relative;\n height: 100%;\n display: flex;\n align-items: center;\n gap: 7px;\n padding: 0 12px;\n font-size: var(--fs-md);\n font-weight: 500;\n color: var(--prism-text-muted);\n white-space: nowrap;\n transition: color var(--dur-fast);\n background: none;\n border: none;\n cursor: pointer;\n font-family: var(--font-sans);\n }\n .p-tab:hover { color: var(--prism-text-2); }\n .p-tab--active { color: var(--prism-text); }\n .p-tab--active::after {\n content: '';\n position: absolute;\n left: 8px;\n right: 8px;\n bottom: -1px;\n height: 2px;\n background: linear-gradient(90deg, var(--prism-primary-from), var(--prism-primary-to));\n border-radius: 1px;\n }\n\n .p-tab-badge {\n min-width: 16px;\n height: 16px;\n padding: 0 5px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--prism-primary) 18%, transparent);\n color: var(--prism-primary);\n font-family: var(--font-mono);\n font-size: 10px;\n font-weight: 700;\n display: grid;\n place-items: center;\n }\n .p-tab-badge.ok {\n background: color-mix(in srgb, var(--prism-success) 18%, transparent);\n color: var(--prism-success);\n }\n .p-tab-badge.warn {\n background: color-mix(in srgb, var(--prism-warn) 18%, transparent);\n color: var(--prism-warn);\n }\n .p-tab-badge.danger {\n background: color-mix(in srgb, var(--prism-danger) 18%, transparent);\n color: var(--prism-danger);\n }\n\n .panel-tabs-right {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 4px;\n padding-left: 10px;\n }\n\n .icon-btn {\n width: 28px;\n height: 28px;\n display: grid;\n place-items: center;\n border-radius: var(--radius-sm);\n color: var(--prism-text-muted);\n background: none;\n border: none;\n cursor: pointer;\n transition: all var(--dur-fast);\n }\n .icon-btn:hover {\n background: var(--prism-input-bg);\n color: var(--prism-text);\n }\n\n .panel-body {\n flex: 1;\n min-height: 0;\n overflow: auto;\n background: var(--prism-bg-elevated);\n }\n .panel-body::-webkit-scrollbar { width: 8px; height: 8px; }\n .panel-body::-webkit-scrollbar-thumb { background: var(--prism-border-strong); border-radius: 4px; }\n\n :focus-visible {\n outline: 2px solid var(--prism-primary);\n outline-offset: 2px;\n }\n "] }]
|
|
274
|
+
`, styles: ["\n .panel {\n background: var(--prism-bg-elevated);\n border-top: 1px solid var(--prism-border);\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n height: 100%;\n }\n\n .panel-tabs {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 0 16px;\n height: 40px;\n border-bottom: 1px solid var(--prism-border);\n background: var(--prism-bg);\n overflow-x: auto;\n scrollbar-width: none;\n flex-shrink: 0;\n }\n .panel-tabs::-webkit-scrollbar { display: none; }\n\n .p-tab {\n position: relative;\n height: 100%;\n display: flex;\n align-items: center;\n gap: 7px;\n padding: 0 12px;\n font-size: var(--fs-md);\n font-weight: 500;\n color: var(--prism-text-muted);\n white-space: nowrap;\n transition: color var(--dur-fast);\n background: none;\n border: none;\n cursor: pointer;\n font-family: var(--font-sans);\n }\n .p-tab:hover { color: var(--prism-text-2); }\n .p-tab--active { color: var(--prism-text); }\n .p-tab--active::after {\n content: '';\n position: absolute;\n left: 8px;\n right: 8px;\n bottom: -1px;\n height: 2px;\n background: linear-gradient(90deg, var(--prism-primary-from), var(--prism-primary-to));\n border-radius: 1px;\n }\n\n .p-tab-badge {\n min-width: 16px;\n height: 16px;\n padding: 0 5px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--prism-primary) 18%, transparent);\n color: var(--prism-primary);\n font-family: var(--font-mono);\n font-size: 10px;\n font-weight: 700;\n display: grid;\n place-items: center;\n }\n .p-tab-badge.ok {\n background: color-mix(in srgb, var(--prism-success) 18%, transparent);\n color: var(--prism-success);\n }\n .p-tab-badge.warn {\n background: color-mix(in srgb, var(--prism-warn) 18%, transparent);\n color: var(--prism-warn);\n }\n .p-tab-badge.danger {\n background: color-mix(in srgb, var(--prism-danger) 18%, transparent);\n color: var(--prism-danger);\n }\n\n .panel-tabs-right {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 4px;\n padding-left: 10px;\n }\n\n .icon-btn {\n width: 28px;\n height: 28px;\n display: grid;\n place-items: center;\n border-radius: var(--radius-sm);\n color: var(--prism-text-muted);\n background: none;\n border: none;\n cursor: pointer;\n transition: all var(--dur-fast);\n }\n .icon-btn:hover {\n background: var(--prism-input-bg);\n color: var(--prism-text);\n }\n\n .panel-body {\n flex: 1;\n min-height: 0;\n overflow: auto;\n background: var(--prism-bg-elevated);\n }\n .panel-body::-webkit-scrollbar { width: 8px; height: 8px; }\n .panel-body::-webkit-scrollbar-thumb { background: var(--prism-border-strong); border-radius: 4px; }\n\n .panel-pane { height: 100%; }\n .panel-pane[hidden] { display: none; }\n\n :focus-visible {\n outline: 2px solid var(--prism-primary);\n outline-offset: 2px;\n }\n "] }]
|
|
228
275
|
}], () => [], null); })();
|
|
229
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PrismPanelHostComponent, { className: "PrismPanelHostComponent", filePath: "app/panels/panel-host/prism-panel-host.component.ts", lineNumber:
|
|
276
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PrismPanelHostComponent, { className: "PrismPanelHostComponent", filePath: "app/panels/panel-host/prism-panel-host.component.ts", lineNumber: 213 }); })();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provide-prism.d.ts","sourceRoot":"","sources":["../../src/app/provide-prism.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAEpF,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAStE,MAAM,WAAW,mBAAmB;IAClC,cAAc,CAAC,EAAE,oBAAoB,EAAE,CAAC;CACzC;AAED,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,eAAe,EACzB,MAAM,CAAC,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,oBAAoB,
|
|
1
|
+
{"version":3,"file":"provide-prism.d.ts","sourceRoot":"","sources":["../../src/app/provide-prism.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAEpF,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAStE,MAAM,WAAW,mBAAmB;IAClC,cAAc,CAAC,EAAE,oBAAoB,EAAE,CAAC;CACzC;AAED,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,eAAe,EACzB,MAAM,CAAC,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,oBAAoB,CA8BtB"}
|
|
@@ -7,6 +7,17 @@ export function providePrism(manifest, config, options) {
|
|
|
7
7
|
const mergedManifest = options?.componentPages?.length
|
|
8
8
|
? { ...manifest, pages: [...(manifest.pages ?? []), ...options.componentPages.map(o => componentPage(o))] }
|
|
9
9
|
: manifest;
|
|
10
|
+
// Exposes a thin discovery view of the manifest to external audit tooling.
|
|
11
|
+
// We intentionally only expose className + variant info — no Angular type references.
|
|
12
|
+
if (typeof globalThis !== 'undefined') {
|
|
13
|
+
globalThis['__PRISM_MANIFEST__'] = {
|
|
14
|
+
components: mergedManifest.components.map((c) => ({
|
|
15
|
+
className: c.meta.className,
|
|
16
|
+
variants: c.meta.showcaseConfig.variants?.map((v, i) => ({ name: v.name, index: i })) ?? [{ name: 'Default', index: 0 }],
|
|
17
|
+
})),
|
|
18
|
+
pages: (mergedManifest.pages ?? []).map((p) => ({ title: p.title })),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
10
21
|
return makeEnvironmentProviders([
|
|
11
22
|
{ provide: PRISM_MANIFEST, useValue: mergedManifest },
|
|
12
23
|
{ provide: PRISM_BUILTIN_PANELS, useValue: BUILTIN_PANELS },
|
|
@@ -25,6 +25,8 @@ export declare class PrismRendererComponent {
|
|
|
25
25
|
private isRenderPage;
|
|
26
26
|
private readonly overlayCache;
|
|
27
27
|
readonly activeOverlay: import("@angular/core").WritableSignal<Type<unknown> | null>;
|
|
28
|
+
/** Identifier of the currently rendered component/variant (for audit tooling / e2e). */
|
|
29
|
+
protected readonly renderedKey: import("@angular/core").Signal<string | null>;
|
|
28
30
|
protected readonly overlayInputs: {
|
|
29
31
|
rendererService: PrismRendererService;
|
|
30
32
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prism-renderer.component.d.ts","sourceRoot":"","sources":["../../../src/app/renderer/prism-renderer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,QAAQ,EAER,KAAK,IAAI,EAIV,MAAM,eAAe,CAAC;AAYvB,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AAGjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;;AAIhF,
|
|
1
|
+
{"version":3,"file":"prism-renderer.component.d.ts","sourceRoot":"","sources":["../../../src/app/renderer/prism-renderer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,QAAQ,EAER,KAAK,IAAI,EAIV,MAAM,eAAe,CAAC;AAYvB,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AAGjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;;AAIhF,qBA6Ia,sBAAsB;IACjC,SAAS,CAAC,QAAQ,CAAC,IAAI,OAAQ;IAC/B,SAAS,CAAC,QAAQ,CAAC,iBAAiB,yBAAkC;IACtE,SAAS,CAAC,QAAQ,CAAC,eAAe,uBAAgC;IAClE,SAAS,CAAC,QAAQ,CAAC,aAAa,qBAA8B;IAC9D,SAAS,CAAC,QAAQ,CAAC,SAAS,wBAAiC;IAC7D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgC;IAChE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgC;IAChE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsB;IACjD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAmC;IACxD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAE3B;IAEH,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA6B;IAC1D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA8B;IAE5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAEpB;IACH,OAAO,CAAC,YAAY,CAAsC;IAC1D,OAAO,CAAC,mBAAmB,CAAsC;IACjE,OAAO,CAAC,oBAAoB,CAChB;IACZ,OAAO,CAAC,YAAY,CAAS;IAE7B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoC;IACjE,QAAQ,CAAC,aAAa,+DAAsC;IAC5D,wFAAwF;IACxF,SAAS,CAAC,QAAQ,CAAC,WAAW,gDAM3B;IACH,SAAS,CAAC,QAAQ,CAAC,aAAa;;MAA6C;IAC7E,SAAS,CAAC,QAAQ,CAAC,eAAe,yFAG/B;;IA0FH,OAAO,CAAC,eAAe;IA6FvB,OAAO,CAAC,OAAO;yCAhOJ,sBAAsB;2CAAtB,sBAAsB;CA8OlC"}
|
|
@@ -48,6 +48,16 @@ export class PrismRendererComponent {
|
|
|
48
48
|
isRenderPage = false;
|
|
49
49
|
overlayCache = new Map();
|
|
50
50
|
activeOverlay = signal(null, ...(ngDevMode ? [{ debugName: "activeOverlay" }] : []));
|
|
51
|
+
/** Identifier of the currently rendered component/variant (for audit tooling / e2e). */
|
|
52
|
+
renderedKey = computed(() => {
|
|
53
|
+
const el = this.rendererService.renderedElement();
|
|
54
|
+
if (!el)
|
|
55
|
+
return null;
|
|
56
|
+
const comp = this.navigationService.activeComponent();
|
|
57
|
+
if (!comp)
|
|
58
|
+
return null;
|
|
59
|
+
return `${comp.meta.className}:${this.rendererService.activeVariantIndex()}`;
|
|
60
|
+
}, ...(ngDevMode ? [{ debugName: "renderedKey" }] : []));
|
|
51
61
|
overlayInputs = { rendererService: this.rendererService };
|
|
52
62
|
overlayInjector = computed(() => {
|
|
53
63
|
const panelInjector = this.panelService.activePanelInjector();
|
|
@@ -207,7 +217,7 @@ export class PrismRendererComponent {
|
|
|
207
217
|
i0.ɵɵviewQuerySignal(ctx.outlet, _c0, 5, ViewContainerRef);
|
|
208
218
|
} if (rf & 2) {
|
|
209
219
|
i0.ɵɵqueryAdvance();
|
|
210
|
-
} }, decls: 11, vars:
|
|
220
|
+
} }, decls: 11, vars: 9, consts: [["outlet", ""], [1, "prism-canvas-stage"], [1, "canvas-badges"], [1, "c-badge"], [1, "stage-crosshair"], [1, "demo-wrap"], [4, "ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector"]], template: function PrismRendererComponent_Template(rf, ctx) { if (rf & 1) {
|
|
211
221
|
i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "span", 3);
|
|
212
222
|
i0.ɵɵtext(3);
|
|
213
223
|
i0.ɵɵelementEnd()();
|
|
@@ -224,6 +234,7 @@ export class PrismRendererComponent {
|
|
|
224
234
|
i0.ɵɵclassProp("visible", ctx.canvasService.guides());
|
|
225
235
|
i0.ɵɵadvance(3);
|
|
226
236
|
i0.ɵɵstyleProp("--zoom", ctx.canvasService.zoom());
|
|
237
|
+
i0.ɵɵattribute("data-prism-rendered", ctx.renderedKey());
|
|
227
238
|
i0.ɵɵadvance(3);
|
|
228
239
|
i0.ɵɵconditional(ctx.activeOverlay() ? 10 : -1);
|
|
229
240
|
} }, dependencies: [PrismCanvasRulersComponent,
|
|
@@ -254,7 +265,11 @@ export class PrismRendererComponent {
|
|
|
254
265
|
<prism-canvas-rulers />
|
|
255
266
|
<prism-canvas-bg-pill />
|
|
256
267
|
|
|
257
|
-
<div
|
|
268
|
+
<div
|
|
269
|
+
class="demo-wrap"
|
|
270
|
+
[style.--zoom]="canvasService.zoom()"
|
|
271
|
+
[attr.data-prism-rendered]="renderedKey()"
|
|
272
|
+
>
|
|
258
273
|
<ng-container #outlet />
|
|
259
274
|
@if (activeOverlay()) {
|
|
260
275
|
<ng-container
|
|
@@ -271,7 +286,7 @@ export class PrismRendererComponent {
|
|
|
271
286
|
}], () => [], { outlet: [{ type: i0.ViewChild, args: ['outlet', { ...{
|
|
272
287
|
read: ViewContainerRef,
|
|
273
288
|
}, isSignal: true }] }] }); })();
|
|
274
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PrismRendererComponent, { className: "PrismRendererComponent", filePath: "app/renderer/prism-renderer.component.ts", lineNumber:
|
|
289
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PrismRendererComponent, { className: "PrismRendererComponent", filePath: "app/renderer/prism-renderer.component.ts", lineNumber: 178 }); })();
|
|
275
290
|
function parseContentToNodes(content) {
|
|
276
291
|
if (typeof content === 'string') {
|
|
277
292
|
return [htmlToNodes(content)];
|
|
@@ -8,6 +8,11 @@ export declare class PrismPanelService {
|
|
|
8
8
|
readonly activePanelId: import("@angular/core").WritableSignal<string>;
|
|
9
9
|
readonly activeViewId: import("@angular/core").WritableSignal<string>;
|
|
10
10
|
readonly activePanelInjector: import("@angular/core").Signal<EnvironmentInjector | null>;
|
|
11
|
+
/**
|
|
12
|
+
* Returns (and lazily creates) the EnvironmentInjector scoped to the given panel.
|
|
13
|
+
* Returns `null` when the panel has no providers.
|
|
14
|
+
*/
|
|
15
|
+
getInjector(panelId: string): EnvironmentInjector | null;
|
|
11
16
|
static ɵfac: i0.ɵɵFactoryDeclaration<PrismPanelService, never>;
|
|
12
17
|
static ɵprov: i0.ɵɵInjectableDeclaration<PrismPanelService>;
|
|
13
18
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prism-panel.service.d.ts","sourceRoot":"","sources":["../../../src/app/services/prism-panel.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,mBAAmB,EAIpB,MAAM,eAAe,CAAC;;AAIvB,qBACa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA+B;IAC3D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA8B;IAC5D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgC;IAC9D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA0C;IAExE,QAAQ,CAAC,aAAa,iDAA8B;IACpD,QAAQ,CAAC,YAAY,iDAA8B;IAEnD,QAAQ,CAAC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"prism-panel.service.d.ts","sourceRoot":"","sources":["../../../src/app/services/prism-panel.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,mBAAmB,EAIpB,MAAM,eAAe,CAAC;;AAIvB,qBACa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA+B;IAC3D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA8B;IAC5D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgC;IAC9D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA0C;IAExE,QAAQ,CAAC,aAAa,iDAA8B;IACpD,QAAQ,CAAC,YAAY,iDAA8B;IAEnD,QAAQ,CAAC,mBAAmB,6DAE1B;IAEF;;;OAGG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI;yCAjB7C,iBAAiB;6CAAjB,iBAAiB;CAiC7B"}
|
|
@@ -9,8 +9,12 @@ export class PrismPanelService {
|
|
|
9
9
|
injectorCache = new Map();
|
|
10
10
|
activePanelId = signal('controls', ...(ngDevMode ? [{ debugName: "activePanelId" }] : []));
|
|
11
11
|
activeViewId = signal('renderer', ...(ngDevMode ? [{ debugName: "activeViewId" }] : []));
|
|
12
|
-
activePanelInjector = computed(() => {
|
|
13
|
-
|
|
12
|
+
activePanelInjector = computed(() => this.getInjector(this.activePanelId()), ...(ngDevMode ? [{ debugName: "activePanelInjector" }] : []));
|
|
13
|
+
/**
|
|
14
|
+
* Returns (and lazily creates) the EnvironmentInjector scoped to the given panel.
|
|
15
|
+
* Returns `null` when the panel has no providers.
|
|
16
|
+
*/
|
|
17
|
+
getInjector(panelId) {
|
|
14
18
|
const allPanels = [...this.builtinPanels, ...this.pluginService.panels()];
|
|
15
19
|
const panel = allPanels.find((p) => p.id === panelId);
|
|
16
20
|
if (!panel?.providers?.length)
|
|
@@ -21,7 +25,7 @@ export class PrismPanelService {
|
|
|
21
25
|
this.injectorCache.set(panel.id, injector);
|
|
22
26
|
}
|
|
23
27
|
return injector;
|
|
24
|
-
}
|
|
28
|
+
}
|
|
25
29
|
static ɵfac = function PrismPanelService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || PrismPanelService)(); };
|
|
26
30
|
static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: PrismPanelService, factory: PrismPanelService.ɵfac, providedIn: 'root' });
|
|
27
31
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ControlDefinition, PanelDefinition } from '../../plugin/plugin.types.js';
|
|
1
|
+
import type { ControlDefinition, HeaderWidgetDefinition, PanelDefinition } from '../../plugin/plugin.types.js';
|
|
2
2
|
import * as i0 from "@angular/core";
|
|
3
3
|
export declare class PrismPluginService {
|
|
4
4
|
private readonly config;
|
|
@@ -6,6 +6,9 @@ export declare class PrismPluginService {
|
|
|
6
6
|
readonly addonPanels: import("@angular/core").Signal<PanelDefinition[]>;
|
|
7
7
|
readonly viewPanels: import("@angular/core").Signal<PanelDefinition[]>;
|
|
8
8
|
readonly controls: import("@angular/core").Signal<ControlDefinition[]>;
|
|
9
|
+
readonly headerWidgets: import("@angular/core").Signal<HeaderWidgetDefinition[]>;
|
|
10
|
+
readonly headerWidgetsStart: import("@angular/core").Signal<HeaderWidgetDefinition[]>;
|
|
11
|
+
readonly headerWidgetsEnd: import("@angular/core").Signal<HeaderWidgetDefinition[]>;
|
|
9
12
|
static ɵfac: i0.ɵɵFactoryDeclaration<PrismPluginService, never>;
|
|
10
13
|
static ɵprov: i0.ɵɵInjectableDeclaration<PrismPluginService>;
|
|
11
14
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prism-plugin.service.d.ts","sourceRoot":"","sources":["../../../src/app/services/prism-plugin.service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"prism-plugin.service.d.ts","sourceRoot":"","sources":["../../../src/app/services/prism-plugin.service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,iBAAiB,EACjB,sBAAsB,EACtB,eAAe,EAChB,MAAM,8BAA8B,CAAC;;AAGtC,qBACa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAE/C,QAAQ,CAAC,MAAM,oDAQZ;IAEH,QAAQ,CAAC,WAAW,oDAElB;IAEF,QAAQ,CAAC,UAAU,oDAEjB;IAEF,QAAQ,CAAC,QAAQ,sDAQd;IAEH,QAAQ,CAAC,aAAa,2DAQnB;IAEH,QAAQ,CAAC,kBAAkB,2DAEzB;IAEF,QAAQ,CAAC,gBAAgB,2DAEvB;yCA/CS,kBAAkB;6CAAlB,kBAAkB;CAgD9B"}
|
|
@@ -23,6 +23,17 @@ export class PrismPluginService {
|
|
|
23
23
|
}
|
|
24
24
|
return result;
|
|
25
25
|
}, ...(ngDevMode ? [{ debugName: "controls" }] : []));
|
|
26
|
+
headerWidgets = computed(() => {
|
|
27
|
+
const result = [];
|
|
28
|
+
for (const plugin of this.config.plugins ?? []) {
|
|
29
|
+
if (plugin.headerWidgets) {
|
|
30
|
+
result.push(...plugin.headerWidgets);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return result.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
|
|
34
|
+
}, ...(ngDevMode ? [{ debugName: "headerWidgets" }] : []));
|
|
35
|
+
headerWidgetsStart = computed(() => this.headerWidgets().filter((w) => w.placement === 'start'), ...(ngDevMode ? [{ debugName: "headerWidgetsStart" }] : []));
|
|
36
|
+
headerWidgetsEnd = computed(() => this.headerWidgets().filter((w) => (w.placement ?? 'end') === 'end'), ...(ngDevMode ? [{ debugName: "headerWidgetsEnd" }] : []));
|
|
26
37
|
static ɵfac = function PrismPluginService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || PrismPluginService)(); };
|
|
27
38
|
static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: PrismPluginService, factory: PrismPluginService.ɵfac, providedIn: 'root' });
|
|
28
39
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { A11yManifestMeta, A11yReport, A11yThresholds } from '../../app/panels/a11y/a11y.types.js';
|
|
2
|
+
export declare const DEFAULT_A11Y_REPORT_PATH = "a11y-report.json";
|
|
3
|
+
export declare function loadA11yReport(reportPath: string): A11yReport | null;
|
|
4
|
+
export declare function readA11yMeta(reportPath: string, thresholdsInput?: Partial<A11yThresholds>): A11yManifestMeta | null;
|
|
5
|
+
export interface ThresholdViolation {
|
|
6
|
+
metric: 'score' | 'critical' | 'serious' | 'moderate';
|
|
7
|
+
actual: number;
|
|
8
|
+
threshold: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function checkA11yThresholds(meta: A11yManifestMeta): ThresholdViolation[];
|
|
11
|
+
export declare function clearA11yReportCache(): void;
|
|
12
|
+
//# sourceMappingURL=a11y-report-reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a11y-report-reader.d.ts","sourceRoot":"","sources":["../../../src/builder/a11y/a11y-report-reader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,UAAU,EACV,cAAc,EACf,MAAM,qCAAqC,CAAC;AAG7C,eAAO,MAAM,wBAAwB,qBAAqB,CAAC;AAI3D,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAapE;AAED,wBAAgB,YAAY,CAC1B,UAAU,EAAE,MAAM,EAClB,eAAe,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GACxC,gBAAgB,GAAG,IAAI,CAQzB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,gBAAgB,GACrB,kBAAkB,EAAE,CAkBtB;AAED,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { readFileSync, statSync } from 'node:fs';
|
|
2
|
+
import { resolveA11yThresholds } from '../../app/panels/a11y/a11y-thresholds.js';
|
|
3
|
+
export const DEFAULT_A11Y_REPORT_PATH = 'a11y-report.json';
|
|
4
|
+
const cache = new Map();
|
|
5
|
+
export function loadA11yReport(reportPath) {
|
|
6
|
+
try {
|
|
7
|
+
const mtime = statSync(reportPath).mtimeMs;
|
|
8
|
+
const cached = cache.get(reportPath);
|
|
9
|
+
if (cached && cached.mtime === mtime)
|
|
10
|
+
return cached.data;
|
|
11
|
+
const raw = readFileSync(reportPath, 'utf-8');
|
|
12
|
+
const parsed = JSON.parse(raw);
|
|
13
|
+
cache.set(reportPath, { mtime, data: parsed });
|
|
14
|
+
return parsed;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function readA11yMeta(reportPath, thresholdsInput) {
|
|
21
|
+
const report = loadA11yReport(reportPath);
|
|
22
|
+
if (!report?.total)
|
|
23
|
+
return null;
|
|
24
|
+
return {
|
|
25
|
+
total: report.total,
|
|
26
|
+
thresholds: resolveA11yThresholds(thresholdsInput),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export function checkA11yThresholds(meta) {
|
|
30
|
+
const violations = [];
|
|
31
|
+
const t = meta.thresholds;
|
|
32
|
+
const total = meta.total;
|
|
33
|
+
if (total.score < t.score) {
|
|
34
|
+
violations.push({ metric: 'score', actual: total.score, threshold: t.score });
|
|
35
|
+
}
|
|
36
|
+
if (total.critical > t.critical) {
|
|
37
|
+
violations.push({ metric: 'critical', actual: total.critical, threshold: t.critical });
|
|
38
|
+
}
|
|
39
|
+
if (total.serious > t.serious) {
|
|
40
|
+
violations.push({ metric: 'serious', actual: total.serious, threshold: t.serious });
|
|
41
|
+
}
|
|
42
|
+
if (total.moderate > t.moderate) {
|
|
43
|
+
violations.push({ metric: 'moderate', actual: total.moderate, threshold: t.moderate });
|
|
44
|
+
}
|
|
45
|
+
return violations;
|
|
46
|
+
}
|
|
47
|
+
export function clearA11yReportCache() {
|
|
48
|
+
cache.clear();
|
|
49
|
+
}
|
|
@@ -4,6 +4,7 @@ export interface RuntimeManifestOptions {
|
|
|
4
4
|
components: ScannedComponent[];
|
|
5
5
|
libraryImportPath: string;
|
|
6
6
|
pages?: StyleguidePage[];
|
|
7
|
+
meta?: Record<string, unknown>;
|
|
7
8
|
}
|
|
8
9
|
export declare function generateRuntimeManifest(options: RuntimeManifestOptions): string;
|
|
9
10
|
//# sourceMappingURL=runtime-manifest.generator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-manifest.generator.d.ts","sourceRoot":"","sources":["../../../src/builder/manifest/runtime-manifest.generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAa,MAAM,8BAA8B,CAAC;AAChF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAIjE,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"runtime-manifest.generator.d.ts","sourceRoot":"","sources":["../../../src/builder/manifest/runtime-manifest.generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAa,MAAM,8BAA8B,CAAC;AAChF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAIjE,MAAM,WAAW,sBAAsB;IACrC,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;CAChC;AAyHD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,sBAAsB,GAAG,MAAM,CA8E/E"}
|
|
@@ -108,7 +108,7 @@ function groupComponentsByImportPath(components, fallbackImportPath) {
|
|
|
108
108
|
return groups;
|
|
109
109
|
}
|
|
110
110
|
export function generateRuntimeManifest(options) {
|
|
111
|
-
const { components, libraryImportPath, pages } = options;
|
|
111
|
+
const { components, libraryImportPath, pages, meta } = options;
|
|
112
112
|
const directives = components.filter((c) => c.componentMeta.isDirective);
|
|
113
113
|
const hasDirectives = directives.length > 0;
|
|
114
114
|
const lines = [
|
|
@@ -162,6 +162,13 @@ export function generateRuntimeManifest(options) {
|
|
|
162
162
|
if (pages && pages.length > 0) {
|
|
163
163
|
lines.push(` pages: ${JSON.stringify(pages, null, 2).split('\n').map((l, i) => i === 0 ? l : ' ' + l).join('\n')},`);
|
|
164
164
|
}
|
|
165
|
+
if (meta && Object.keys(meta).length > 0) {
|
|
166
|
+
const metaJson = JSON.stringify(meta, null, 2)
|
|
167
|
+
.split('\n')
|
|
168
|
+
.map((l, i) => (i === 0 ? l : ' ' + l))
|
|
169
|
+
.join('\n');
|
|
170
|
+
lines.push(` meta: ${metaJson},`);
|
|
171
|
+
}
|
|
165
172
|
lines.push('};');
|
|
166
173
|
lines.push('');
|
|
167
174
|
return lines.join('\n');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-runner.d.ts","sourceRoot":"","sources":["../../../src/builder/plugin-runner/plugin-runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAoB,MAAM,8BAA8B,CAAC;AAmBnG,wBAAsB,cAAc,CAClC,QAAQ,EAAE,aAAa,EACvB,OAAO,EAAE,aAAa,EAAE,GACvB,OAAO,CAAC,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"plugin-runner.d.ts","sourceRoot":"","sources":["../../../src/builder/plugin-runner/plugin-runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAoB,MAAM,8BAA8B,CAAC;AAmBnG,wBAAsB,cAAc,CAClC,QAAQ,EAAE,aAAa,EACvB,OAAO,EAAE,aAAa,EAAE,GACvB,OAAO,CAAC,aAAa,CAAC,CAyDxB"}
|
|
@@ -46,7 +46,9 @@ export async function runPluginHooks(manifest, plugins) {
|
|
|
46
46
|
}
|
|
47
47
|
pages[i] = current;
|
|
48
48
|
}
|
|
49
|
-
let result =
|
|
49
|
+
let result = manifest.meta
|
|
50
|
+
? { components, pages, meta: manifest.meta }
|
|
51
|
+
: { components, pages };
|
|
50
52
|
for (const plugin of plugins) {
|
|
51
53
|
if (plugin.onManifestReady) {
|
|
52
54
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prism-pipeline.d.ts","sourceRoot":"","sources":["../../../src/builder/shared/prism-pipeline.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"prism-pipeline.d.ts","sourceRoot":"","sources":["../../../src/builder/shared/prism-pipeline.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAYpE,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,mGAAmG;IACnG,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,oGAAoG;IACpG,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED,wBAAgB,mBAAmB,IAAI,kBAAkB,CAExD;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,oBAAoB,EAC7B,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,mBAAmB,CAAC,CA2E9B"}
|
|
@@ -6,6 +6,7 @@ import { discoverSecondaryEntryPoints } from '../scanner/entry-point-discovery.j
|
|
|
6
6
|
import { loadConfig } from '../config-loader/config-loader.js';
|
|
7
7
|
import { runPluginHooks } from '../plugin-runner/plugin-runner.js';
|
|
8
8
|
import { generateRuntimeManifest } from '../manifest/runtime-manifest.generator.js';
|
|
9
|
+
import { DEFAULT_A11Y_REPORT_PATH, checkA11yThresholds, readA11yMeta, } from '../a11y/a11y-report-reader.js';
|
|
9
10
|
export function createPipelineState() {
|
|
10
11
|
return { scanner: undefined, lastEntrySetKey: undefined };
|
|
11
12
|
}
|
|
@@ -20,12 +21,29 @@ export async function runPrismPipeline(options, context, state) {
|
|
|
20
21
|
const scanResult = scanEntryPoints(workspaceRoot, options, state);
|
|
21
22
|
const pages = config.pages ? [...config.pages] : [];
|
|
22
23
|
context.reportStatus('Running plugin hooks...');
|
|
23
|
-
|
|
24
|
+
let manifest = await runPluginHooks({ ...scanResult, pages }, config.plugins ?? []);
|
|
25
|
+
const a11yReportPath = config.a11y?.reportPath ?? DEFAULT_A11Y_REPORT_PATH;
|
|
26
|
+
const a11yMeta = readA11yMeta(join(workspaceRoot, a11yReportPath), config.a11y?.thresholds);
|
|
27
|
+
if (a11yMeta) {
|
|
28
|
+
const violations = checkA11yThresholds(a11yMeta);
|
|
29
|
+
if (violations.length > 0) {
|
|
30
|
+
const summary = violations
|
|
31
|
+
.map((v) => `${v.metric}: ${v.actual} (threshold ${v.threshold})`)
|
|
32
|
+
.join(', ');
|
|
33
|
+
throw new Error(`ng-prism: a11y thresholds violated — ${summary}. ` +
|
|
34
|
+
`Update components or relax thresholds via config.a11y.thresholds.`);
|
|
35
|
+
}
|
|
36
|
+
manifest = {
|
|
37
|
+
...manifest,
|
|
38
|
+
meta: { ...manifest.meta, a11y: a11yMeta },
|
|
39
|
+
};
|
|
40
|
+
}
|
|
24
41
|
context.reportStatus('Generating runtime manifest...');
|
|
25
42
|
const source = generateRuntimeManifest({
|
|
26
43
|
components: manifest.components,
|
|
27
44
|
libraryImportPath: options.libraryImportPath,
|
|
28
45
|
pages: manifest.pages,
|
|
46
|
+
meta: manifest.meta,
|
|
29
47
|
});
|
|
30
48
|
const projectMeta = await context.getProjectMetadata(options.prismProject);
|
|
31
49
|
const sourceRoot = projectMeta['sourceRoot'] ??
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { A11yReport, A11yScoreResult } from '../../app/panels/a11y/a11y.types.js';
|
|
2
|
+
export interface RawAuditResult {
|
|
3
|
+
className: string;
|
|
4
|
+
variantName: string;
|
|
5
|
+
variantIndex: number;
|
|
6
|
+
/** Result from `calculateScore(axeResults)` in the running app. */
|
|
7
|
+
score: A11yScoreResult;
|
|
8
|
+
}
|
|
9
|
+
export declare function aggregateAuditResults(results: RawAuditResult[]): A11yReport;
|
|
10
|
+
//# sourceMappingURL=aggregator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregator.d.ts","sourceRoot":"","sources":["../../../src/cli/audit-a11y/aggregator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EAChB,MAAM,qCAAqC,CAAC;AAE7C,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,KAAK,EAAE,eAAe,CAAC;CACxB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,UAAU,CAkD3E"}
|