@ng-forge/dynamic-forms 1.0.0-rc.1 → 1.0.0-rc.3
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 +16 -0
- package/fesm2022/{ng-forge-dynamic-forms-array-field.component-By12r5Cj.mjs → ng-forge-dynamic-forms-array-field.component-D5qCzJsL.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-array-field.component-By12r5Cj.mjs.map → ng-forge-dynamic-forms-array-field.component-D5qCzJsL.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-QJzwEYSj.mjs → ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-D6ntLtW9.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-QJzwEYSj.mjs.map → ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-D6ntLtW9.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-container-field.component-BGFguOa9.mjs → ng-forge-dynamic-forms-container-field.component-nB6KFqVs.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-container-field.component-BGFguOa9.mjs.map → ng-forge-dynamic-forms-container-field.component-nB6KFqVs.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-group-field.component-Bz4GD8Hy.mjs → ng-forge-dynamic-forms-group-field.component-Bq6Sgd6Z.mjs} +2 -2
- package/fesm2022/ng-forge-dynamic-forms-group-field.component-Bq6Sgd6Z.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs +6 -6
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs.map +1 -1
- package/fesm2022/ng-forge-dynamic-forms-internal.mjs +281 -42
- package/fesm2022/ng-forge-dynamic-forms-internal.mjs.map +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-ng-forge-dynamic-forms-DTkMZcnb.mjs → ng-forge-dynamic-forms-ng-forge-dynamic-forms-C59pvc26.mjs} +86 -407
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-C59pvc26.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-page-field.component-CjCd5Byo.mjs → ng-forge-dynamic-forms-page-field.component-DRaxbiqA.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-page-field.component-CjCd5Byo.mjs.map → ng-forge-dynamic-forms-page-field.component-DRaxbiqA.mjs.map} +1 -1
- package/fesm2022/ng-forge-dynamic-forms.mjs +2 -2
- package/package.json +3 -3
- package/types/ng-forge-dynamic-forms-integration.d.ts +6 -10
- package/types/ng-forge-dynamic-forms-internal.d.ts +1951 -1750
- package/types/ng-forge-dynamic-forms.d.ts +61 -270
- package/fesm2022/ng-forge-dynamic-forms-group-field.component-Bz4GD8Hy.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-DTkMZcnb.mjs.map +0 -1
|
@@ -1,11 +1,274 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { InjectionToken, computed, isSignal, inject, Injector, input, signal, ChangeDetectionStrategy, Component, untracked, Injectable, linkedSignal, resourceFromSnapshots, Pipe } from '@angular/core';
|
|
3
|
+
import { NgComponentOutlet } from '@angular/common';
|
|
4
|
+
import { explicitEffect } from 'ngxtension/explicit-effect';
|
|
5
|
+
import { toSignal, toObservable, rxResource } from '@angular/core/rxjs-interop';
|
|
6
|
+
import { isObservable, defer, combineLatest, pipe, debounceTime, distinctUntilChanged, of, from, map, catchError, tap, startWith, Subject, filter, TimeoutError, throwError } from 'rxjs';
|
|
5
7
|
import { HttpClient } from '@angular/common/http';
|
|
6
8
|
import { email, min, max, minLength, maxLength, pattern, required, validate, validateAsync, validateHttp } from '@angular/forms/signals';
|
|
7
9
|
import { scan, map as map$1, filter as filter$1, take, switchMap, timeout, catchError as catchError$1, shareReplay } from 'rxjs/operators';
|
|
8
10
|
|
|
11
|
+
const ADDON_TYPE_DEFINITIONS = new InjectionToken('ADDON_TYPE_DEFINITIONS');
|
|
12
|
+
|
|
13
|
+
const DynamicFormLogger = new InjectionToken('DynamicFormLogger');
|
|
14
|
+
|
|
15
|
+
function resolveDynamicValue(value, fallback, injector) {
|
|
16
|
+
if (value === undefined) {
|
|
17
|
+
return computed(() => fallback);
|
|
18
|
+
}
|
|
19
|
+
if (isSignal(value)) {
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
if (isObservable(value)) {
|
|
23
|
+
return toSignal(value, { initialValue: fallback, injector });
|
|
24
|
+
}
|
|
25
|
+
return computed(() => value);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
class DynamicFormError extends Error {
|
|
29
|
+
static PREFIX = '[Dynamic Forms]';
|
|
30
|
+
constructor(message) {
|
|
31
|
+
super(`${DynamicFormError.PREFIX} ${message}`);
|
|
32
|
+
this.name = 'DynamicFormError';
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const ADDON_TYPE_REGISTRY = new InjectionToken('ADDON_TYPE_REGISTRY', {
|
|
37
|
+
providedIn: 'root',
|
|
38
|
+
factory: () => new Map(),
|
|
39
|
+
});
|
|
40
|
+
const ADDON_TYPE_COMPONENT_CACHE = new InjectionToken('ADDON_TYPE_COMPONENT_CACHE');
|
|
41
|
+
|
|
42
|
+
function resolveDefaultExport(result) {
|
|
43
|
+
return typeof result === 'object' && result !== null && 'default' in result ? result.default : result;
|
|
44
|
+
}
|
|
45
|
+
function injectAddonTypeRegistry() {
|
|
46
|
+
const registry = inject(ADDON_TYPE_REGISTRY);
|
|
47
|
+
const componentCache = inject(ADDON_TYPE_COMPONENT_CACHE);
|
|
48
|
+
return {
|
|
49
|
+
getType(type) {
|
|
50
|
+
return registry.get(type);
|
|
51
|
+
},
|
|
52
|
+
hasType(type) {
|
|
53
|
+
return registry.has(type);
|
|
54
|
+
},
|
|
55
|
+
getTypeNames() {
|
|
56
|
+
return Array.from(registry.keys());
|
|
57
|
+
},
|
|
58
|
+
async loadTypeComponent(type) {
|
|
59
|
+
const definition = registry.get(type);
|
|
60
|
+
if (!definition) {
|
|
61
|
+
const known = Array.from(registry.keys()).join(', ') || '(none)';
|
|
62
|
+
throw new DynamicFormError(`Addon type '${type}' is not registered. Currently registered types: ${known}.`);
|
|
63
|
+
}
|
|
64
|
+
const cached = componentCache.get(type);
|
|
65
|
+
if (cached) {
|
|
66
|
+
return cached;
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const component = resolveDefaultExport(await definition.loadComponent());
|
|
70
|
+
if (component) {
|
|
71
|
+
componentCache.set(type, component);
|
|
72
|
+
return component;
|
|
73
|
+
}
|
|
74
|
+
throw new DynamicFormError(`Addon type '${type}' loadComponent resolved to null.`);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
if (error instanceof DynamicFormError)
|
|
78
|
+
throw error;
|
|
79
|
+
throw new DynamicFormError(`Failed to load component for addon type '${type}': ${error instanceof Error ? error.message : String(error)}`);
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
getLoadedTypeComponent(type) {
|
|
83
|
+
if (!registry.has(type))
|
|
84
|
+
return undefined;
|
|
85
|
+
return componentCache.get(type);
|
|
86
|
+
},
|
|
87
|
+
get raw() {
|
|
88
|
+
return registry;
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
class DfAddonSlot {
|
|
94
|
+
registry = injectAddonTypeRegistry();
|
|
95
|
+
logger = inject(DynamicFormLogger);
|
|
96
|
+
hostInjector = inject(Injector);
|
|
97
|
+
addon = input.required(/* @ts-ignore */
|
|
98
|
+
...(ngDevMode ? [{ debugName: "addon" }] : /* istanbul ignore next */ []));
|
|
99
|
+
fieldInputs = input(/* @ts-ignore */
|
|
100
|
+
...(ngDevMode ? [undefined, { debugName: "fieldInputs" }] : /* istanbul ignore next */ []));
|
|
101
|
+
hidden = input(undefined, /* @ts-ignore */
|
|
102
|
+
...(ngDevMode ? [{ debugName: "hidden" }] : /* istanbul ignore next */ []));
|
|
103
|
+
slotAttr = computed(() => this.addon().slot, /* @ts-ignore */
|
|
104
|
+
...(ngDevMode ? [{ debugName: "slotAttr" }] : /* istanbul ignore next */ []));
|
|
105
|
+
className = computed(() => this.addon().className ?? null, /* @ts-ignore */
|
|
106
|
+
...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
|
|
107
|
+
_hiddenByValue = new WeakMap();
|
|
108
|
+
_resolvedHidden = signal(undefined, /* @ts-ignore */
|
|
109
|
+
...(ngDevMode ? [{ debugName: "_resolvedHidden" }] : /* istanbul ignore next */ []));
|
|
110
|
+
isHidden = computed(() => {
|
|
111
|
+
const pre = this.hidden();
|
|
112
|
+
if (pre)
|
|
113
|
+
return pre();
|
|
114
|
+
const local = this._resolvedHidden();
|
|
115
|
+
return local ? local() : false;
|
|
116
|
+
}, /* @ts-ignore */
|
|
117
|
+
...(ngDevMode ? [{ debugName: "isHidden" }] : /* istanbul ignore next */ []));
|
|
118
|
+
asyncLoaded = signal(undefined, /* @ts-ignore */
|
|
119
|
+
...(ngDevMode ? [{ debugName: "asyncLoaded" }] : /* istanbul ignore next */ []));
|
|
120
|
+
resolvedComponent = computed(() => {
|
|
121
|
+
const type = this.addon().type;
|
|
122
|
+
const cached = this.registry.getLoadedTypeComponent(type);
|
|
123
|
+
if (cached)
|
|
124
|
+
return cached;
|
|
125
|
+
const loaded = this.asyncLoaded();
|
|
126
|
+
return loaded?.type === type ? loaded.component : undefined;
|
|
127
|
+
}, /* @ts-ignore */
|
|
128
|
+
...(ngDevMode ? [{ debugName: "resolvedComponent" }] : /* istanbul ignore next */ []));
|
|
129
|
+
typeInputs = computed(() => ({
|
|
130
|
+
addon: this.addon(),
|
|
131
|
+
fieldInputs: this.fieldInputs(),
|
|
132
|
+
}), /* @ts-ignore */
|
|
133
|
+
...(ngDevMode ? [{ debugName: "typeInputs" }] : /* istanbul ignore next */ []));
|
|
134
|
+
constructor() {
|
|
135
|
+
explicitEffect([this.addon], ([addon]) => {
|
|
136
|
+
const h = addon.hidden;
|
|
137
|
+
const valueKey = typeof h === 'object' && h !== null ? h : null;
|
|
138
|
+
let resolved = valueKey ? this._hiddenByValue.get(valueKey) : undefined;
|
|
139
|
+
if (!resolved) {
|
|
140
|
+
resolved = resolveDynamicValue(addon.hidden, false, this.hostInjector);
|
|
141
|
+
if (valueKey)
|
|
142
|
+
this._hiddenByValue.set(valueKey, resolved);
|
|
143
|
+
}
|
|
144
|
+
this._resolvedHidden.set(resolved);
|
|
145
|
+
});
|
|
146
|
+
explicitEffect([this.addon], ([addon]) => {
|
|
147
|
+
const type = addon.type;
|
|
148
|
+
if (this.registry.getLoadedTypeComponent(type))
|
|
149
|
+
return; this.registry
|
|
150
|
+
.loadTypeComponent(type)
|
|
151
|
+
.then((component) => this.asyncLoaded.set({ type, component }))
|
|
152
|
+
.catch((error) => {
|
|
153
|
+
this.logger.warn(`Failed to load addon type '${type}': ${error instanceof Error ? error.message : String(error)}. ` +
|
|
154
|
+
`Registered types: ${this.registry.getTypeNames().join(', ') || '(none)'}.`);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: DfAddonSlot, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
159
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: DfAddonSlot, isStandalone: true, selector: "df-addon-slot", inputs: { addon: { classPropertyName: "addon", publicName: "addon", isSignal: true, isRequired: true, transformFunction: null }, fieldInputs: { classPropertyName: "fieldInputs", publicName: "fieldInputs", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.slot": "slotAttr()", "class": "className()", "style.display": "isHidden() ? \"none\" : null" } }, ngImport: i0, template: `
|
|
160
|
+
@if (resolvedComponent(); as cmp) {
|
|
161
|
+
<ng-container *ngComponentOutlet="cmp; inputs: typeInputs()" />
|
|
162
|
+
}
|
|
163
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
164
|
+
}
|
|
165
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: DfAddonSlot, decorators: [{
|
|
166
|
+
type: Component,
|
|
167
|
+
args: [{
|
|
168
|
+
selector: 'df-addon-slot',
|
|
169
|
+
imports: [NgComponentOutlet],
|
|
170
|
+
template: `
|
|
171
|
+
@if (resolvedComponent(); as cmp) {
|
|
172
|
+
<ng-container *ngComponentOutlet="cmp; inputs: typeInputs()" />
|
|
173
|
+
}
|
|
174
|
+
`,
|
|
175
|
+
host: {
|
|
176
|
+
'[attr.slot]': 'slotAttr()',
|
|
177
|
+
'[class]': 'className()',
|
|
178
|
+
'[style.display]': 'isHidden() ? "none" : null',
|
|
179
|
+
},
|
|
180
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
181
|
+
}]
|
|
182
|
+
}], ctorParameters: () => [], propDecorators: { addon: [{ type: i0.Input, args: [{ isSignal: true, alias: "addon", required: true }] }], fieldInputs: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldInputs", required: false }] }], hidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidden", required: false }] }] } });
|
|
183
|
+
|
|
184
|
+
const FIELD_REGISTRY = new InjectionToken('FIELD_REGISTRY', {
|
|
185
|
+
providedIn: 'root',
|
|
186
|
+
factory: () => new Map(),
|
|
187
|
+
});
|
|
188
|
+
function getFieldValueHandling(fieldType, registry) {
|
|
189
|
+
const definition = registry.get(fieldType);
|
|
190
|
+
return definition?.valueHandling ?? 'include';
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function injectFieldsSupportingAddons() {
|
|
194
|
+
const registry = inject(FIELD_REGISTRY);
|
|
195
|
+
const entries = [];
|
|
196
|
+
for (const [name, def] of registry.entries()) {
|
|
197
|
+
if (def.addons === undefined)
|
|
198
|
+
continue;
|
|
199
|
+
entries.push({ name, slots: def.addons.slots, allowedTypes: def.addons.allowedTypes });
|
|
200
|
+
}
|
|
201
|
+
return entries;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async function runPresetAction(preset, ctx, collaborators, adapterLabel, fieldLabel) {
|
|
205
|
+
if (ctx.form === null && preset !== 'copy' && preset !== 'paste') {
|
|
206
|
+
collaborators.logger.warn(`preset '${String(preset)}' fired without a host field context — ignoring.`);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
if (ctx.form !== null && (preset === 'clear' || preset === 'reset' || preset === 'paste') && ctx.form.disabled()) {
|
|
210
|
+
collaborators.logger.warn(`preset '${String(preset)}' skipped — host '${fieldLabel}' is disabled.`);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
switch (preset) {
|
|
214
|
+
case 'clear': {
|
|
215
|
+
const next = typeof ctx.value === 'string' ? '' : undefined;
|
|
216
|
+
collaborators.fieldValueSetter?.(next);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
case 'reset': {
|
|
220
|
+
const defaultValue = collaborators.fieldDefaultValueGetter?.();
|
|
221
|
+
collaborators.fieldValueSetter?.(defaultValue !== undefined ? defaultValue : typeof ctx.value === 'string' ? '' : undefined);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
case 'paste': {
|
|
225
|
+
if (typeof navigator === 'undefined' || !navigator.clipboard) {
|
|
226
|
+
collaborators.logger.warn(`preset 'paste' requires a browser clipboard API (not available in this environment).`);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
try {
|
|
230
|
+
const text = await navigator.clipboard.readText();
|
|
231
|
+
collaborators.fieldValueSetter?.(text);
|
|
232
|
+
}
|
|
233
|
+
catch (error) {
|
|
234
|
+
collaborators.logger.warn(`preset 'paste' clipboard read failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
235
|
+
}
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
case 'copy': {
|
|
239
|
+
if (typeof navigator === 'undefined' || !navigator.clipboard) {
|
|
240
|
+
collaborators.logger.warn(`preset 'copy' requires a browser clipboard API (not available in this environment).`);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
try {
|
|
244
|
+
const v = ctx.value;
|
|
245
|
+
await navigator.clipboard.writeText(v == null ? '' : String(v));
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
collaborators.logger.warn(`preset 'copy' clipboard write failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
249
|
+
}
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
case 'toggle-password-visibility': {
|
|
253
|
+
const override = collaborators.typeOverride;
|
|
254
|
+
if (!override) {
|
|
255
|
+
collaborators.logger.warn(`preset 'toggle-password-visibility' has no effect outside a '${fieldLabel}' field.`);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
const baseline = collaborators.baselineType?.();
|
|
259
|
+
if (baseline !== undefined && baseline !== 'password') {
|
|
260
|
+
collaborators.logger.warn(`preset 'toggle-password-visibility' refused: host '${fieldLabel}' has type '${baseline}', not 'password'.`);
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
const current = override();
|
|
264
|
+
override.set(current === 'text' ? 'password' : 'text');
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
default:
|
|
268
|
+
collaborators.logger.warn(`preset '${String(preset)}' is not implemented in the ${adapterLabel} adapter.`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
9
272
|
function createDefaultDerivationLogConfig() {
|
|
10
273
|
return {
|
|
11
274
|
level: 'none',
|
|
@@ -228,14 +491,6 @@ function stableStringify(value) {
|
|
|
228
491
|
return '{' + pairs.join(',') + '}';
|
|
229
492
|
}
|
|
230
493
|
|
|
231
|
-
class DynamicFormError extends Error {
|
|
232
|
-
static PREFIX = '[Dynamic Forms]';
|
|
233
|
-
constructor(message) {
|
|
234
|
-
super(`${DynamicFormError.PREFIX} ${message}`);
|
|
235
|
-
this.name = 'DynamicFormError';
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
494
|
const DEFAULT_WRAPPERS = new InjectionToken('DEFAULT_WRAPPERS');
|
|
240
495
|
const FIELD_SIGNAL_CONTEXT = new InjectionToken('FIELD_SIGNAL_CONTEXT');
|
|
241
496
|
function injectFieldSignalContext() {
|
|
@@ -262,8 +517,6 @@ class RootFormRegistryService {
|
|
|
262
517
|
}
|
|
263
518
|
}
|
|
264
519
|
|
|
265
|
-
const DynamicFormLogger = new InjectionToken('DynamicFormLogger');
|
|
266
|
-
|
|
267
520
|
const DEPRECATION_WARNING_TRACKER = new InjectionToken('DeprecationWarningTracker');
|
|
268
521
|
|
|
269
522
|
function compareValues(actual, expected, operator) {
|
|
@@ -2549,7 +2802,7 @@ function isSimplifiedArrayField(field) {
|
|
|
2549
2802
|
return field.type === 'array' && 'template' in field;
|
|
2550
2803
|
}
|
|
2551
2804
|
|
|
2552
|
-
function
|
|
2805
|
+
function isGenericContainerField(field) {
|
|
2553
2806
|
return (field.type === 'container' &&
|
|
2554
2807
|
'wrappers' in field &&
|
|
2555
2808
|
'fields' in field &&
|
|
@@ -2576,7 +2829,7 @@ function validatePageNesting(pageField) {
|
|
|
2576
2829
|
return !hasNestedPages(pageField.fields);
|
|
2577
2830
|
}
|
|
2578
2831
|
function isContainerWithFields$1(field) {
|
|
2579
|
-
return ((isRowField(field) || isGroupField(field) ||
|
|
2832
|
+
return ((isRowField(field) || isGroupField(field) || isGenericContainerField(field)) &&
|
|
2580
2833
|
'fields' in field &&
|
|
2581
2834
|
Array.isArray(field.fields));
|
|
2582
2835
|
}
|
|
@@ -2873,22 +3126,21 @@ function isFieldBoundContext(ctx) {
|
|
|
2873
3126
|
return ctx.form !== null;
|
|
2874
3127
|
}
|
|
2875
3128
|
|
|
2876
|
-
const
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
});
|
|
3129
|
+
const ADDON_ACTION_HANDLERS = new InjectionToken('ADDON_ACTION_HANDLERS');
|
|
3130
|
+
const ADDON_ACTION_REGISTRY = new InjectionToken('ADDON_ACTION_REGISTRY');
|
|
3131
|
+
function createAddonActionRegistry() {
|
|
3132
|
+
const sources = inject(ADDON_ACTION_HANDLERS, { optional: true }) ?? [];
|
|
3133
|
+
const map = new Map();
|
|
3134
|
+
for (const handlers of sources) {
|
|
3135
|
+
for (const [name, fn] of Object.entries(handlers)) {
|
|
3136
|
+
map.set(name, fn);
|
|
3137
|
+
}
|
|
3138
|
+
}
|
|
3139
|
+
return map;
|
|
3140
|
+
}
|
|
2880
3141
|
|
|
2881
3142
|
const DF_FIELD_TEMPLATES = new InjectionToken('DF_FIELD_TEMPLATES');
|
|
2882
3143
|
|
|
2883
|
-
const FIELD_REGISTRY = new InjectionToken('FIELD_REGISTRY', {
|
|
2884
|
-
providedIn: 'root',
|
|
2885
|
-
factory: () => new Map(),
|
|
2886
|
-
});
|
|
2887
|
-
function getFieldValueHandling(fieldType, registry) {
|
|
2888
|
-
const definition = registry.get(fieldType);
|
|
2889
|
-
return definition?.valueHandling ?? 'include';
|
|
2890
|
-
}
|
|
2891
|
-
|
|
2892
3144
|
function isWrapperTypeDefinition(value) {
|
|
2893
3145
|
return typeof value === 'object' && value !== null && 'wrapperName' in value;
|
|
2894
3146
|
}
|
|
@@ -3065,19 +3317,6 @@ function dynamicTextToObservable(value, injector) {
|
|
|
3065
3317
|
return of(String(value));
|
|
3066
3318
|
}
|
|
3067
3319
|
|
|
3068
|
-
function resolveDynamicValue(value, fallback, injector) {
|
|
3069
|
-
if (value === undefined) {
|
|
3070
|
-
return computed(() => fallback);
|
|
3071
|
-
}
|
|
3072
|
-
if (isSignal(value)) {
|
|
3073
|
-
return value;
|
|
3074
|
-
}
|
|
3075
|
-
if (isObservable(value)) {
|
|
3076
|
-
return toSignal(value, { initialValue: fallback, injector });
|
|
3077
|
-
}
|
|
3078
|
-
return computed(() => value);
|
|
3079
|
-
}
|
|
3080
|
-
|
|
3081
3320
|
const INITIALIZATION_TIMEOUT_MS = new InjectionToken('INITIALIZATION_TIMEOUT_MS', {
|
|
3082
3321
|
providedIn: 'root',
|
|
3083
3322
|
factory: () => 10_000,
|
|
@@ -3370,5 +3609,5 @@ function createWarningTracker() {
|
|
|
3370
3609
|
|
|
3371
3610
|
|
|
3372
3611
|
|
|
3373
|
-
export {
|
|
3612
|
+
export { ADDON_ACTION_HANDLERS, ADDON_ACTION_REGISTRY, ADDON_TYPE_COMPONENT_CACHE, ADDON_TYPE_DEFINITIONS, ADDON_TYPE_REGISTRY, ARRAY_CONTEXT, AsyncConditionFunctionCacheService, ComponentInitializedEvent, DEFAULT_PROPS, DEFAULT_VALIDATION_MESSAGES, DEFAULT_WRAPPERS, DEPRECATION_WARNING_TRACKER, DF_FIELD_TEMPLATES, DfAddonSlot, DynamicFormError, DynamicFormLogger, DynamicTextPipe, DynamicValueFunctionCacheService, EMIT_FORM_VALUE_ON_EVENTS, EXTERNAL_DATA, Evaluator, EventBus, ExpressionParser, ExpressionParserError, FIELD_REGISTRY, FIELD_SIGNAL_CONTEXT, FORM_ID_PREFIX, FORM_OPTIONS, FieldContextRegistryService, FunctionRegistryService, GROUP_CONTEXT, HTTP_CONDITION_CACHE, HttpConditionCache, HttpConditionFunctionCacheService, INITIALIZATION_TIMEOUT_MS, LogicFunctionCacheService, NoopLogger, Parser, READONLY_FIELD_TREE_CACHE, RootFormRegistryService, TokenType, Tokenizer, WRAPPER_AUTO_ASSOCIATIONS, WRAPPER_COMPONENT_CACHE, WRAPPER_REGISTRY, applyHiddenLogic, applyMetaToElement, applyValidator, applyValidators, arrayFieldMapper, assertNever, baseFieldMapper, buildBaseInputs, buildClassName, compareValues, containerFieldMapper, createAddonActionRegistry, createAsyncConditionLogicFunction, createDebouncedLogicFunction, createDebouncedResourceLogicFn, createDefaultDerivationLogConfig, createDynamicValueFunction, createFormFieldStateMap, createHttpConditionLogicFunction, createInitializationTracker, createLogicFunction, createWarningTracker, deepMergeDefaults, derivedFromDeferred, detectFormMode, dynamicTextToObservable, evaluateCondition, evaluateHttpValidationResponse, evaluateNonFieldDisabled, evaluateNonFieldHidden, extractExpressionDependencies, extractStringDependencies, getArrayLength, getChangedKeys, getFieldValueHandling, getGridClassString, getNestedValue, groupFieldMapper, hasChildFields, hasCrossFieldWhenCondition, hasFormValue, hasNestedProperty, hasTargetProperty, injectAddonTypeRegistry, injectFieldSignalContext, injectFieldsSupportingAddons, interpolateParams, isArrayField, isCheckedField, isContainerField, isCrossFieldBuiltInValidator, isCrossFieldExpression, isCrossFieldSchema, isCrossFieldStateLogic, isCrossFieldValidator, isDerivationLogicConfig, isDisplayOnlyField, isEqual, isFieldBoundContext, isFormStateCondition, isFunctionHttpValidator, isGenericContainerField, isGroupField, isHiddenField, isLeafField, isNonPagedForm, isPageField, isPagedForm, isResourceBasedValidator, isRowField, isSimplifiedArrayField, isStateLogicConfig, isValidNonPagedForm, isValidPagedForm, isValueBearingField, isValueField, isWrapperTypeDefinition, keyBy, mapValues, memoize, normalizeFieldsArray, omit, pageFieldMapper, readFieldStateInfo, resolveDynamicValue, resolveHttpRequest, resolveNextButtonDisabled, resolveNonFieldDisabled, resolveNonFieldHidden, resolveSubmitButtonDisabled, resolveTokens, rowFieldMapper, runPresetAction, safeReadPathKeys, setupInitializationTracking, shouldLog, stableStringify, textFieldMapper, toReadonlyFieldTree, toReadonlyFieldTreeCached, validatePageNesting, withPreviousValue, writeToFieldValue };
|
|
3374
3613
|
//# sourceMappingURL=ng-forge-dynamic-forms-internal.mjs.map
|