ngx-json-render 0.9.0 → 0.9.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/README.md +67 -7
- package/fesm2022/ngx-json-render-devtools.mjs +3 -3
- package/fesm2022/ngx-json-render-router.mjs +71 -0
- package/fesm2022/ngx-json-render-router.mjs.map +1 -0
- package/fesm2022/ngx-json-render-testing.mjs +6 -6
- package/fesm2022/ngx-json-render.mjs +172 -47
- package/fesm2022/ngx-json-render.mjs.map +1 -1
- package/package.json +14 -4
- package/schematics/ng-add/index.cjs +1 -1
- package/types/ngx-json-render-router.d.ts +39 -0
- package/types/ngx-json-render.d.ts +75 -7
|
@@ -47,10 +47,10 @@ class JsonRenderRootContext {
|
|
|
47
47
|
return undefined;
|
|
48
48
|
return typeof raw === 'function' ? { component: raw } : raw;
|
|
49
49
|
}
|
|
50
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
51
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
50
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JsonRenderRootContext, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
51
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JsonRenderRootContext });
|
|
52
52
|
}
|
|
53
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
53
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JsonRenderRootContext, decorators: [{
|
|
54
54
|
type: Injectable
|
|
55
55
|
}] });
|
|
56
56
|
|
|
@@ -284,10 +284,10 @@ class JsonRenderStateService {
|
|
|
284
284
|
listener(changes);
|
|
285
285
|
}
|
|
286
286
|
}
|
|
287
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
288
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
287
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JsonRenderStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
288
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JsonRenderStateService });
|
|
289
289
|
}
|
|
290
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
290
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JsonRenderStateService, decorators: [{
|
|
291
291
|
type: Injectable
|
|
292
292
|
}], ctorParameters: () => [] });
|
|
293
293
|
/**
|
|
@@ -538,10 +538,10 @@ class JsonRenderValidationService {
|
|
|
538
538
|
}
|
|
539
539
|
return allValid;
|
|
540
540
|
}
|
|
541
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
542
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
541
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JsonRenderValidationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
542
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JsonRenderValidationService });
|
|
543
543
|
}
|
|
544
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
544
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JsonRenderValidationService, decorators: [{
|
|
545
545
|
type: Injectable
|
|
546
546
|
}] });
|
|
547
547
|
/** Inject the validation service of the nearest `<json-render>` renderer. */
|
|
@@ -904,10 +904,10 @@ class JsonRenderActionsService {
|
|
|
904
904
|
this._loadingActions.set(next);
|
|
905
905
|
}
|
|
906
906
|
}
|
|
907
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
908
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
907
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JsonRenderActionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
908
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JsonRenderActionsService });
|
|
909
909
|
}
|
|
910
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
910
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JsonRenderActionsService, decorators: [{
|
|
911
911
|
type: Injectable
|
|
912
912
|
}] });
|
|
913
913
|
/** Inject the actions service of the nearest `<json-render>` renderer. */
|
|
@@ -1031,8 +1031,8 @@ class JrConfirmDialog {
|
|
|
1031
1031
|
cancel.focus();
|
|
1032
1032
|
}
|
|
1033
1033
|
}
|
|
1034
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1035
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.
|
|
1034
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JrConfirmDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1035
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.25", type: JrConfirmDialog, isStandalone: true, selector: "jr-confirm-dialog", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { confirmed: "confirmed", cancelled: "cancelled" }, host: { listeners: { "keydown.escape": "cancelled.emit()" } }, viewQueries: [{ propertyName: "cancelButton", first: true, predicate: ["cancel"], descendants: true, isSignal: true }, { propertyName: "confirmButton", first: true, predicate: ["confirm"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
1036
1036
|
<div class="jr-confirm-scrim" (click)="cancelled.emit()">
|
|
1037
1037
|
<div
|
|
1038
1038
|
class="jr-confirm-panel"
|
|
@@ -1063,7 +1063,7 @@ class JrConfirmDialog {
|
|
|
1063
1063
|
</div>
|
|
1064
1064
|
`, isInline: true, styles: [":host{--jr-confirm-scrim-default: rgba(0, 0, 0, .5);--jr-confirm-surface-default: #ffffff;--jr-confirm-ink-default: #111827;--jr-confirm-muted-default: #6b7280;--jr-confirm-border-default: #d1d5db;--jr-confirm-accent-default: #3b82f6;--jr-confirm-danger-default: #dc2626;--jr-confirm-on-accent-default: #ffffff}@media(prefers-color-scheme:dark){:host{--jr-confirm-scrim-default: rgba(0, 0, 0, .65);--jr-confirm-surface-default: #1f2937;--jr-confirm-ink-default: #f3f4f6;--jr-confirm-muted-default: #9ca3af;--jr-confirm-border-default: #4b5563;--jr-confirm-accent-default: #60a5fa;--jr-confirm-danger-default: #f87171;--jr-confirm-on-accent-default: #111827}}.jr-confirm-scrim{position:fixed;inset:0;z-index:50;display:flex;align-items:center;justify-content:center;background-color:var(--jr-confirm-scrim, var(--jr-confirm-scrim-default))}.jr-confirm-panel{width:100%;max-width:400px;padding:24px;border-radius:var(--jr-confirm-radius, 8px);background-color:var(--jr-confirm-surface, var(--jr-confirm-surface-default));color:var(--jr-confirm-ink, var(--jr-confirm-ink-default));box-shadow:0 20px 25px -5px #00000040}.jr-confirm-title{margin:0 0 8px;font-size:18px;font-weight:600}.jr-confirm-message{margin:0 0 24px;color:var(--jr-confirm-muted, var(--jr-confirm-muted-default))}.jr-confirm-actions{display:flex;gap:12px;justify-content:flex-end}.jr-confirm-actions button{padding:8px 16px;border-radius:6px;font:inherit;cursor:pointer}.jr-confirm-cancel{border:1px solid var(--jr-confirm-border, var(--jr-confirm-border-default));background-color:transparent;color:inherit}.jr-confirm-confirm{border:none;background-color:var(--jr-confirm-accent, var(--jr-confirm-accent-default));color:var(--jr-confirm-on-accent, var(--jr-confirm-on-accent-default))}.jr-confirm-confirm.jr-confirm-danger{background-color:var(--jr-confirm-danger, var(--jr-confirm-danger-default))}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1065
1065
|
}
|
|
1066
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1066
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JrConfirmDialog, decorators: [{
|
|
1067
1067
|
type: Component,
|
|
1068
1068
|
args: [{ selector: 'jr-confirm-dialog', changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
1069
1069
|
'(keydown.escape)': 'cancelled.emit()',
|
|
@@ -2349,8 +2349,8 @@ class JrElement {
|
|
|
2349
2349
|
bound: true,
|
|
2350
2350
|
};
|
|
2351
2351
|
}
|
|
2352
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
2353
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
2352
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JrElement, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2353
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: JrElement, isStandalone: true, selector: "jr-element", inputs: { elementKey: { classPropertyName: "elementKey", publicName: "elementKey", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
|
|
2354
2354
|
@if (!refusal() && rawElement() && visible() && component()) {
|
|
2355
2355
|
@if (devtoolsKey(); as dk) {
|
|
2356
2356
|
<span [attr.data-jr-key]="dk" style="display: contents">
|
|
@@ -2362,7 +2362,7 @@ class JrElement {
|
|
|
2362
2362
|
}
|
|
2363
2363
|
`, isInline: true, styles: [":host{display:contents}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2364
2364
|
}
|
|
2365
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
2365
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JrElement, decorators: [{
|
|
2366
2366
|
type: Component,
|
|
2367
2367
|
args: [{ selector: 'jr-element', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgComponentOutlet], template: `
|
|
2368
2368
|
@if (!refusal() && rawElement() && visible() && component()) {
|
|
@@ -2377,6 +2377,92 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
|
|
|
2377
2377
|
`, styles: [":host{display:contents}\n"] }]
|
|
2378
2378
|
}], ctorParameters: () => [], propDecorators: { elementKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "elementKey", required: true }] }] } });
|
|
2379
2379
|
|
|
2380
|
+
/**
|
|
2381
|
+
* The defaults the nearest {@link provideJsonRender} supplies, already merged
|
|
2382
|
+
* with any provider above it.
|
|
2383
|
+
*/
|
|
2384
|
+
const JSON_RENDER_CONFIG = new InjectionToken('JSON_RENDER_CONFIG');
|
|
2385
|
+
/**
|
|
2386
|
+
* Set renderer defaults once instead of on every `<json-render>`:
|
|
2387
|
+
*
|
|
2388
|
+
* ```ts
|
|
2389
|
+
* bootstrapApplication(App, { providers: [provideJsonRender({ registry })] });
|
|
2390
|
+
* ```
|
|
2391
|
+
*
|
|
2392
|
+
* ```html
|
|
2393
|
+
* <json-render [spec]="m.spec" />
|
|
2394
|
+
* ```
|
|
2395
|
+
*
|
|
2396
|
+
* Pass a function to build the defaults with `inject()`, for handlers that
|
|
2397
|
+
* call your services:
|
|
2398
|
+
*
|
|
2399
|
+
* ```ts
|
|
2400
|
+
* provideJsonRender(() => {
|
|
2401
|
+
* const orders = inject(OrderService);
|
|
2402
|
+
* return { registry, handlers: { cancelOrder: (p) => orders.cancel(p['id']) } };
|
|
2403
|
+
* });
|
|
2404
|
+
* ```
|
|
2405
|
+
*
|
|
2406
|
+
* Works in application, route and component `providers`. A provider below
|
|
2407
|
+
* another extends it with the same rules an element input does: its own
|
|
2408
|
+
* values replace, its named vocabularies merge.
|
|
2409
|
+
*/
|
|
2410
|
+
function provideJsonRender(config) {
|
|
2411
|
+
return [
|
|
2412
|
+
{
|
|
2413
|
+
provide: JSON_RENDER_CONFIG,
|
|
2414
|
+
useFactory: () => {
|
|
2415
|
+
const outer = inject(JSON_RENDER_CONFIG, {
|
|
2416
|
+
optional: true,
|
|
2417
|
+
skipSelf: true,
|
|
2418
|
+
});
|
|
2419
|
+
const own = typeof config === 'function' ? config() : config;
|
|
2420
|
+
return outer ? mergeJsonRenderConfig(outer, own) : own;
|
|
2421
|
+
},
|
|
2422
|
+
},
|
|
2423
|
+
];
|
|
2424
|
+
}
|
|
2425
|
+
/** `inner` over `outer`, by the rules {@link JsonRenderConfig} describes. */
|
|
2426
|
+
function mergeJsonRenderConfig(outer, inner) {
|
|
2427
|
+
const merged = { ...outer };
|
|
2428
|
+
for (const [key, value] of Object.entries(inner)) {
|
|
2429
|
+
if (value !== undefined && value !== null) {
|
|
2430
|
+
merged[key] = value;
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
merged.handlers = mergeByName(outer.handlers, inner.handlers);
|
|
2434
|
+
merged.functions = mergeByName(outer.functions, inner.functions);
|
|
2435
|
+
merged.validationFunctions = mergeByName(outer.validationFunctions, inner.validationFunctions);
|
|
2436
|
+
merged.directives = mergeDirectives(outer.directives, inner.directives);
|
|
2437
|
+
return merged;
|
|
2438
|
+
}
|
|
2439
|
+
/**
|
|
2440
|
+
* Two name → value maps as one, `inner` winning a name both define. Returns
|
|
2441
|
+
* whichever is given when only one is, so an unmerged map keeps its identity.
|
|
2442
|
+
*
|
|
2443
|
+
* @internal
|
|
2444
|
+
*/
|
|
2445
|
+
function mergeByName(outer, inner) {
|
|
2446
|
+
if (!outer)
|
|
2447
|
+
return inner ?? undefined;
|
|
2448
|
+
if (!inner)
|
|
2449
|
+
return outer;
|
|
2450
|
+
return { ...outer, ...inner };
|
|
2451
|
+
}
|
|
2452
|
+
/**
|
|
2453
|
+
* Two directive lists as one, `inner` winning a name both define — the
|
|
2454
|
+
* directive registry keeps the last definition of a name.
|
|
2455
|
+
*
|
|
2456
|
+
* @internal
|
|
2457
|
+
*/
|
|
2458
|
+
function mergeDirectives(outer, inner) {
|
|
2459
|
+
if (!outer)
|
|
2460
|
+
return inner ?? undefined;
|
|
2461
|
+
if (!inner)
|
|
2462
|
+
return outer;
|
|
2463
|
+
return [...outer, ...inner];
|
|
2464
|
+
}
|
|
2465
|
+
|
|
2380
2466
|
const CLEAN = {
|
|
2381
2467
|
spec: null,
|
|
2382
2468
|
issues: [],
|
|
@@ -2526,8 +2612,11 @@ function reportSpecCheck(check, mode) {
|
|
|
2526
2612
|
class JsonRenderer {
|
|
2527
2613
|
/** The UI spec to render (may be partial while streaming). */
|
|
2528
2614
|
spec = input.required(...(ngDevMode ? [{ debugName: "spec" }] : /* istanbul ignore next */ []));
|
|
2529
|
-
/**
|
|
2530
|
-
|
|
2615
|
+
/**
|
|
2616
|
+
* Component registry mapping catalog type names to Angular components.
|
|
2617
|
+
* Required unless a {@link provideJsonRender} above supplies one.
|
|
2618
|
+
*/
|
|
2619
|
+
registry = input(undefined, ...(ngDevMode ? [{ debugName: "registry" }] : /* istanbul ignore next */ []));
|
|
2531
2620
|
/** Whether the spec is currently loading/streaming. */
|
|
2532
2621
|
loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
2533
2622
|
/** Fallback component for unknown types. */
|
|
@@ -2544,7 +2633,7 @@ class JsonRenderer {
|
|
|
2544
2633
|
* The check is skipped while `loading` is true: a spec that is still
|
|
2545
2634
|
* arriving is expected to reference children that have not streamed in yet.
|
|
2546
2635
|
*/
|
|
2547
|
-
validate = input(
|
|
2636
|
+
validate = input(undefined, ...(ngDevMode ? [{ debugName: "validate" }] : /* istanbul ignore next */ []));
|
|
2548
2637
|
/**
|
|
2549
2638
|
* Caps on what the spec may cost the browser: `maxElements`, `maxDepth` and
|
|
2550
2639
|
* `maxRepeatItems`. Unset by default, and each field is independently
|
|
@@ -2601,34 +2690,52 @@ class JsonRenderer {
|
|
|
2601
2690
|
stateStore;
|
|
2602
2691
|
/** The action dispatcher of this renderer. */
|
|
2603
2692
|
actions;
|
|
2693
|
+
/**
|
|
2694
|
+
* The nearest {@link provideJsonRender}'s defaults. Every option input
|
|
2695
|
+
* falls through to these when left `null` or `undefined`; see
|
|
2696
|
+
* {@link JsonRenderConfig} for the merge rules.
|
|
2697
|
+
*/
|
|
2698
|
+
config = inject(JSON_RENDER_CONFIG, { optional: true }) ?? {};
|
|
2699
|
+
mode = computed(() => this.validate() ?? this.config.validate ?? 'off', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
|
|
2700
|
+
limits = computed(() => this.renderLimits() ?? this.config.renderLimits ?? null, ...(ngDevMode ? [{ debugName: "limits" }] : /* istanbul ignore next */ []));
|
|
2701
|
+
specCatalog = computed(() => this.catalog() ?? this.config.catalog ?? null, ...(ngDevMode ? [{ debugName: "specCatalog" }] : /* istanbul ignore next */ []));
|
|
2604
2702
|
/**
|
|
2605
2703
|
* The spec as checked, and what the check found. While `loading`, the mode
|
|
2606
2704
|
* is forced off: the spec is still arriving, and the missing children it
|
|
2607
2705
|
* refers to are the normal state of a stream, not a defect.
|
|
2608
2706
|
*/
|
|
2609
|
-
checked = computed(() => checkSpec(this.spec(), this.loading() ? 'off' : this.
|
|
2610
|
-
limits: this.
|
|
2611
|
-
catalog: this.
|
|
2707
|
+
checked = computed(() => checkSpec(this.spec(), this.loading() ? 'off' : this.mode(), {
|
|
2708
|
+
limits: this.limits(),
|
|
2709
|
+
catalog: this.specCatalog(),
|
|
2612
2710
|
}), ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
|
|
2613
2711
|
constructor() {
|
|
2614
2712
|
const root = inject(JsonRenderRootContext);
|
|
2615
2713
|
// The fixed spec, not the input: a `visible` the check moved out of
|
|
2616
2714
|
// `props` has to be the one the tree renders, or the fix is cosmetic.
|
|
2617
2715
|
root.spec = computed(() => this.checked().spec, ...(ngDevMode ? [{ debugName: "spec" }] : /* istanbul ignore next */ []));
|
|
2618
|
-
|
|
2716
|
+
const config = this.config;
|
|
2717
|
+
// Read only once an element needs a component, like a required input:
|
|
2718
|
+
// a renderer with no spec yet has no use for one.
|
|
2719
|
+
root.registry = computed(() => {
|
|
2720
|
+
const registry = this.registry() ?? config.registry;
|
|
2721
|
+
if (!registry) {
|
|
2722
|
+
throw new Error('[ngx-json-render] <json-render> has no registry. Bind [registry], or supply one for the whole app with provideJsonRender({ registry }).');
|
|
2723
|
+
}
|
|
2724
|
+
return registry;
|
|
2725
|
+
}, ...(ngDevMode ? [{ debugName: "registry" }] : /* istanbul ignore next */ []));
|
|
2619
2726
|
root.loading = this.loading;
|
|
2620
|
-
root.fallback = this.fallback;
|
|
2621
|
-
root.limits = this.
|
|
2622
|
-
root.catalog = this.
|
|
2727
|
+
root.fallback = computed(() => this.fallback() ?? config.fallback ?? null, ...(ngDevMode ? [{ debugName: "fallback" }] : /* istanbul ignore next */ []));
|
|
2728
|
+
root.limits = this.limits;
|
|
2729
|
+
root.catalog = this.specCatalog;
|
|
2623
2730
|
root.store = this.store;
|
|
2624
2731
|
root.initialState = computed(() => this.state() ?? this.spec()?.state ?? {}, ...(ngDevMode ? [{ debugName: "initialState" }] : /* istanbul ignore next */ []));
|
|
2625
|
-
root.handlers = this.handlers;
|
|
2626
|
-
root.onAction = this.onAction;
|
|
2627
|
-
root.navigate = this.navigate;
|
|
2628
|
-
root.validationFunctions = this.validationFunctions;
|
|
2629
|
-
root.functions = this.functions;
|
|
2732
|
+
root.handlers = computed(() => mergeByName(config.handlers, this.handlers()), ...(ngDevMode ? [{ debugName: "handlers" }] : /* istanbul ignore next */ []));
|
|
2733
|
+
root.onAction = computed(() => this.onAction() ?? config.onAction ?? null, ...(ngDevMode ? [{ debugName: "onAction" }] : /* istanbul ignore next */ []));
|
|
2734
|
+
root.navigate = computed(() => this.navigate() ?? config.navigate ?? null, ...(ngDevMode ? [{ debugName: "navigate" }] : /* istanbul ignore next */ []));
|
|
2735
|
+
root.validationFunctions = computed(() => mergeByName(config.validationFunctions, this.validationFunctions()), ...(ngDevMode ? [{ debugName: "validationFunctions" }] : /* istanbul ignore next */ []));
|
|
2736
|
+
root.functions = computed(() => mergeByName(config.functions, this.functions()), ...(ngDevMode ? [{ debugName: "functions" }] : /* istanbul ignore next */ []));
|
|
2630
2737
|
root.directiveRegistry = computed(() => {
|
|
2631
|
-
const definitions = this.directives();
|
|
2738
|
+
const definitions = mergeDirectives(config.directives, this.directives());
|
|
2632
2739
|
return definitions ? createDirectiveRegistry(definitions) : undefined;
|
|
2633
2740
|
}, ...(ngDevMode ? [{ debugName: "directiveRegistry" }] : /* istanbul ignore next */ []));
|
|
2634
2741
|
root.emitStateChange = (changes) => this.stateChange.emit(changes);
|
|
@@ -2644,7 +2751,25 @@ class JsonRenderer {
|
|
|
2644
2751
|
effect(() => {
|
|
2645
2752
|
if (this.loading())
|
|
2646
2753
|
return;
|
|
2647
|
-
reportSpecCheck(this.checked(), this.
|
|
2754
|
+
reportSpecCheck(this.checked(), this.mode());
|
|
2755
|
+
});
|
|
2756
|
+
// With validation off, a `root` that names no element renders nothing and
|
|
2757
|
+
// nothing says why — the first mistake a hand-written spec tends to have.
|
|
2758
|
+
// Skipped while loading (a stream sends `/root` before its element) and
|
|
2759
|
+
// under `warn`/`strict`, where the check already reports `root_not_found`.
|
|
2760
|
+
// Once per root key, not once per change detection run.
|
|
2761
|
+
const warnedRoots = new Set();
|
|
2762
|
+
effect(() => {
|
|
2763
|
+
if (this.loading() || this.mode() !== 'off')
|
|
2764
|
+
return;
|
|
2765
|
+
const spec = this.checked().spec;
|
|
2766
|
+
if (!spec?.root)
|
|
2767
|
+
return;
|
|
2768
|
+
const root = spec.root;
|
|
2769
|
+
if (spec.elements?.[root] || warnedRoots.has(root))
|
|
2770
|
+
return;
|
|
2771
|
+
warnedRoots.add(root);
|
|
2772
|
+
console.warn(`[ngx-json-render] root "${root}" is not in elements; nothing is rendered.`);
|
|
2648
2773
|
});
|
|
2649
2774
|
}
|
|
2650
2775
|
rootKey = computed(() => {
|
|
@@ -2657,7 +2782,7 @@ class JsonRenderer {
|
|
|
2657
2782
|
// A spec whose errors survived the fixes does not render under `strict`.
|
|
2658
2783
|
// Reporting it and drawing half of it anyway is the behaviour the mode
|
|
2659
2784
|
// exists to refuse.
|
|
2660
|
-
if (this.
|
|
2785
|
+
if (this.mode() === 'strict' && checked.hasErrors)
|
|
2661
2786
|
return null;
|
|
2662
2787
|
const spec = checked.spec;
|
|
2663
2788
|
return spec?.root && spec.elements?.[spec.root] ? spec.root : null;
|
|
@@ -2695,8 +2820,8 @@ class JsonRenderer {
|
|
|
2695
2820
|
parent: this.injector,
|
|
2696
2821
|
});
|
|
2697
2822
|
}, ...(ngDevMode ? [{ debugName: "confirmInjector" }] : /* istanbul ignore next */ []));
|
|
2698
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
2699
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
2823
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JsonRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2824
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: JsonRenderer, isStandalone: true, selector: "json-render", inputs: { spec: { classPropertyName: "spec", publicName: "spec", isSignal: true, isRequired: true, transformFunction: null }, registry: { classPropertyName: "registry", publicName: "registry", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, fallback: { classPropertyName: "fallback", publicName: "fallback", isSignal: true, isRequired: false, transformFunction: null }, validate: { classPropertyName: "validate", publicName: "validate", isSignal: true, isRequired: false, transformFunction: null }, renderLimits: { classPropertyName: "renderLimits", publicName: "renderLimits", isSignal: true, isRequired: false, transformFunction: null }, catalog: { classPropertyName: "catalog", publicName: "catalog", isSignal: true, isRequired: false, transformFunction: null }, state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null }, store: { classPropertyName: "store", publicName: "store", isSignal: true, isRequired: false, transformFunction: null }, handlers: { classPropertyName: "handlers", publicName: "handlers", isSignal: true, isRequired: false, transformFunction: null }, onAction: { classPropertyName: "onAction", publicName: "onAction", isSignal: true, isRequired: false, transformFunction: null }, navigate: { classPropertyName: "navigate", publicName: "navigate", isSignal: true, isRequired: false, transformFunction: null }, validationFunctions: { classPropertyName: "validationFunctions", publicName: "validationFunctions", isSignal: true, isRequired: false, transformFunction: null }, functions: { classPropertyName: "functions", publicName: "functions", isSignal: true, isRequired: false, transformFunction: null }, directives: { classPropertyName: "directives", publicName: "directives", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { stateChange: "stateChange" }, providers: [
|
|
2700
2825
|
JsonRenderRootContext,
|
|
2701
2826
|
JsonRenderStateService,
|
|
2702
2827
|
JsonRenderValidationService,
|
|
@@ -2720,7 +2845,7 @@ class JsonRenderer {
|
|
|
2720
2845
|
}
|
|
2721
2846
|
`, isInline: true, styles: [":host{display:contents}\n"], dependencies: [{ kind: "component", type: JrElement, selector: "jr-element", inputs: ["elementKey"] }, { kind: "component", type: JrConfirmDialog, selector: "jr-confirm-dialog", inputs: ["config"], outputs: ["confirmed", "cancelled"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2722
2847
|
}
|
|
2723
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
2848
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JsonRenderer, decorators: [{
|
|
2724
2849
|
type: Component,
|
|
2725
2850
|
args: [{ selector: 'json-render', changeDetection: ChangeDetectionStrategy.OnPush, imports: [JrElement, JrConfirmDialog, NgComponentOutlet], providers: [
|
|
2726
2851
|
JsonRenderRootContext,
|
|
@@ -2745,7 +2870,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
|
|
|
2745
2870
|
}
|
|
2746
2871
|
}
|
|
2747
2872
|
`, styles: [":host{display:contents}\n"] }]
|
|
2748
|
-
}], ctorParameters: () => [], propDecorators: { spec: [{ type: i0.Input, args: [{ isSignal: true, alias: "spec", required: true }] }], registry: [{ type: i0.Input, args: [{ isSignal: true, alias: "registry", required:
|
|
2873
|
+
}], ctorParameters: () => [], propDecorators: { spec: [{ type: i0.Input, args: [{ isSignal: true, alias: "spec", required: true }] }], registry: [{ type: i0.Input, args: [{ isSignal: true, alias: "registry", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], fallback: [{ type: i0.Input, args: [{ isSignal: true, alias: "fallback", required: false }] }], validate: [{ type: i0.Input, args: [{ isSignal: true, alias: "validate", required: false }] }], renderLimits: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderLimits", required: false }] }], catalog: [{ type: i0.Input, args: [{ isSignal: true, alias: "catalog", required: false }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], store: [{ type: i0.Input, args: [{ isSignal: true, alias: "store", required: false }] }], handlers: [{ type: i0.Input, args: [{ isSignal: true, alias: "handlers", required: false }] }], onAction: [{ type: i0.Input, args: [{ isSignal: true, alias: "onAction", required: false }] }], navigate: [{ type: i0.Input, args: [{ isSignal: true, alias: "navigate", required: false }] }], validationFunctions: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationFunctions", required: false }] }], functions: [{ type: i0.Input, args: [{ isSignal: true, alias: "functions", required: false }] }], directives: [{ type: i0.Input, args: [{ isSignal: true, alias: "directives", required: false }] }], stateChange: [{ type: i0.Output, args: ["stateChange"] }] } });
|
|
2749
2874
|
|
|
2750
2875
|
/**
|
|
2751
2876
|
* Provides the repeat scope (item, index, absolute base path) to the elements
|
|
@@ -2757,12 +2882,12 @@ class JrRepeatScope {
|
|
|
2757
2882
|
item = input.required(...(ngDevMode ? [{ debugName: "item" }] : /* istanbul ignore next */ []));
|
|
2758
2883
|
index = input.required(...(ngDevMode ? [{ debugName: "index" }] : /* istanbul ignore next */ []));
|
|
2759
2884
|
basePath = input.required(...(ngDevMode ? [{ debugName: "basePath" }] : /* istanbul ignore next */ []));
|
|
2760
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
2761
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.
|
|
2885
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JrRepeatScope, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2886
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.25", type: JrRepeatScope, isStandalone: true, selector: "jr-repeat-scope", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, index: { classPropertyName: "index", publicName: "index", isSignal: true, isRequired: true, transformFunction: null }, basePath: { classPropertyName: "basePath", publicName: "basePath", isSignal: true, isRequired: true, transformFunction: null } }, providers: [
|
|
2762
2887
|
{ provide: REPEAT_SCOPE, useExisting: forwardRef(() => JrRepeatScope) },
|
|
2763
2888
|
], ngImport: i0, template: '<ng-content />', isInline: true, styles: [":host{display:contents}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2764
2889
|
}
|
|
2765
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
2890
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JrRepeatScope, decorators: [{
|
|
2766
2891
|
type: Component,
|
|
2767
2892
|
args: [{ selector: 'jr-repeat-scope', changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
2768
2893
|
{ provide: REPEAT_SCOPE, useExisting: forwardRef(() => JrRepeatScope) },
|
|
@@ -2883,8 +3008,8 @@ class JrChildren {
|
|
|
2883
3008
|
}
|
|
2884
3009
|
return index;
|
|
2885
3010
|
}
|
|
2886
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
2887
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
3011
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JrChildren, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3012
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: JrChildren, isStandalone: true, selector: "jr-children", inputs: { slot: { classPropertyName: "slot", publicName: "slot", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
2888
3013
|
@if (repeat()) {
|
|
2889
3014
|
@for (item of repeatItems(); track trackItem($index, item)) {
|
|
2890
3015
|
<jr-repeat-scope
|
|
@@ -2904,7 +3029,7 @@ class JrChildren {
|
|
|
2904
3029
|
}
|
|
2905
3030
|
`, isInline: true, styles: [":host{display:contents}\n"], dependencies: [{ kind: "component", type: JrElement, selector: "jr-element", inputs: ["elementKey"] }, { kind: "component", type: JrRepeatScope, selector: "jr-repeat-scope", inputs: ["item", "index", "basePath"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2906
3031
|
}
|
|
2907
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
3032
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: JrChildren, decorators: [{
|
|
2908
3033
|
type: Component,
|
|
2909
3034
|
args: [{ selector: 'jr-children', changeDetection: ChangeDetectionStrategy.OnPush, imports: [JrElement, JrRepeatScope], template: `
|
|
2910
3035
|
@if (repeat()) {
|
|
@@ -3886,5 +4011,5 @@ function injectChatUI(options) {
|
|
|
3886
4011
|
* Generated bundle index. Do not edit.
|
|
3887
4012
|
*/
|
|
3888
4013
|
|
|
3889
|
-
export { CONFIRM_CONTEXT, ELEMENT_KEY, JR_CONFIRM_DIALOG, JR_CONFIRM_LABELS, JrChildren, JrConfirmDialog, JrElement, JrRepeatScope, JsonRenderActionsService, JsonRenderRootContext, JsonRenderStateService, JsonRenderValidationService, JsonRenderer, RENDER_CONTEXT, REPEAT_SCOPE, applyPatch, buildSpecFromParts, checkSpec, createStoreSetState, defineRegistry, flatToTree, formatSpecCheckIssues, getTextFromParts, injectAction, injectActions, injectBoundProp, injectChatUI, injectConfirmContext, injectDevtoolsActive, injectElementKey, injectFieldValidation, injectRenderContext, injectRepeatScope, injectStateBinding, injectStateStore, injectStateValue, injectUIStream, injectValidation, isActionCancelled, jsonRenderMessage, ɵregisterStreamObserver };
|
|
4014
|
+
export { CONFIRM_CONTEXT, ELEMENT_KEY, JR_CONFIRM_DIALOG, JR_CONFIRM_LABELS, JSON_RENDER_CONFIG, JrChildren, JrConfirmDialog, JrElement, JrRepeatScope, JsonRenderActionsService, JsonRenderRootContext, JsonRenderStateService, JsonRenderValidationService, JsonRenderer, RENDER_CONTEXT, REPEAT_SCOPE, applyPatch, buildSpecFromParts, checkSpec, createStoreSetState, defineRegistry, flatToTree, formatSpecCheckIssues, getTextFromParts, injectAction, injectActions, injectBoundProp, injectChatUI, injectConfirmContext, injectDevtoolsActive, injectElementKey, injectFieldValidation, injectRenderContext, injectRepeatScope, injectStateBinding, injectStateStore, injectStateValue, injectUIStream, injectValidation, isActionCancelled, jsonRenderMessage, provideJsonRender, ɵregisterStreamObserver };
|
|
3890
4015
|
//# sourceMappingURL=ngx-json-render.mjs.map
|