@ng-forge/dynamic-forms 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs +79 -6
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs.map +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-ng-forge-dynamic-forms-CZBdtTAU.mjs → ng-forge-dynamic-forms-ng-forge-dynamic-forms-CMSmISSp.mjs} +301 -72
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-CMSmISSp.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-page-field.component-BM32StxL.mjs → ng-forge-dynamic-forms-page-field.component-rdGD8A9d.mjs} +5 -5
- package/fesm2022/{ng-forge-dynamic-forms-page-field.component-BM32StxL.mjs.map → ng-forge-dynamic-forms-page-field.component-rdGD8A9d.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-testing-test-button.harness-CbctXjtc.mjs → ng-forge-dynamic-forms-testing-test-button.harness-0iXHLraC.mjs} +7 -7
- package/fesm2022/ng-forge-dynamic-forms-testing-test-button.harness-0iXHLraC.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms-testing.mjs +25 -25
- package/fesm2022/ng-forge-dynamic-forms-testing.mjs.map +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-text-field.component-C0I8jf9T.mjs → ng-forge-dynamic-forms-text-field.component-CDxka2KD.mjs} +5 -5
- package/fesm2022/{ng-forge-dynamic-forms-text-field.component-C0I8jf9T.mjs.map → ng-forge-dynamic-forms-text-field.component-CDxka2KD.mjs.map} +1 -1
- package/fesm2022/ng-forge-dynamic-forms.mjs +1 -1
- package/package.json +4 -4
- package/types/ng-forge-dynamic-forms-integration.d.ts +225 -9
- package/types/ng-forge-dynamic-forms-testing.d.ts +32 -1
- package/types/ng-forge-dynamic-forms.d.ts +202 -15
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-CZBdtTAU.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-testing-test-button.harness-CbctXjtc.mjs.map +0 -1
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { isSignal, computed, runInInjectionContext, InjectionToken, inject, signal, Injectable, untracked, input, linkedSignal, ChangeDetectionStrategy, Component, DestroyRef, Injector, model, afterNextRender, makeEnvironmentProviders, Pipe } from '@angular/core';
|
|
3
3
|
import { NgComponentOutlet } from '@angular/common';
|
|
4
|
-
import { submit, email, min, max, minLength, maxLength, pattern, required, validate, validateAsync, validateHttp, disabled, readonly, hidden, applyEach, applyWhenValue, applyWhen, apply, schema, validateTree, form } from '@angular/forms/signals';
|
|
4
|
+
import { submit, email, min, max, minLength, maxLength, pattern, required, validate, validateAsync, validateHttp, disabled, readonly, hidden, applyEach, applyWhenValue, applyWhen, apply, schema, validateTree, form, provideSignalFormsConfig } from '@angular/forms/signals';
|
|
5
5
|
import { toObservable, toSignal, takeUntilDestroyed, outputFromObservable } from '@angular/core/rxjs-interop';
|
|
6
6
|
import { defer, combineLatest, from, map, catchError, of, pipe, switchMap, forkJoin, scan, isObservable, firstValueFrom, EMPTY, Subject, filter } from 'rxjs';
|
|
7
7
|
import { scan as scan$1, map as map$1, filter as filter$1, take, switchMap as switchMap$1, shareReplay } from 'rxjs/operators';
|
|
8
8
|
import { explicitEffect } from 'ngxtension/explicit-effect';
|
|
9
|
+
import { NG_STATUS_CLASSES } from '@angular/forms/signals/compat';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Type guard to check if a value is an array of Signals.
|
|
@@ -93,7 +94,7 @@ function getGridClassString(fieldDef) {
|
|
|
93
94
|
* @returns Record of input names to values
|
|
94
95
|
*/
|
|
95
96
|
function buildBaseInputs(fieldDef) {
|
|
96
|
-
const { key, label, className, tabIndex, props } = fieldDef;
|
|
97
|
+
const { key, label, className, tabIndex, props, meta } = fieldDef;
|
|
97
98
|
const inputs = {};
|
|
98
99
|
// Always include key - required by components for accessibility and identification
|
|
99
100
|
inputs['key'] = key;
|
|
@@ -118,6 +119,9 @@ function buildBaseInputs(fieldDef) {
|
|
|
118
119
|
if (props !== undefined) {
|
|
119
120
|
inputs['props'] = props;
|
|
120
121
|
}
|
|
122
|
+
if (meta !== undefined) {
|
|
123
|
+
inputs['meta'] = meta;
|
|
124
|
+
}
|
|
121
125
|
return inputs;
|
|
122
126
|
}
|
|
123
127
|
/**
|
|
@@ -135,6 +139,43 @@ function baseFieldMapper(fieldDef) {
|
|
|
135
139
|
return computed(() => buildBaseInputs(fieldDef));
|
|
136
140
|
}
|
|
137
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Merges forwarded props into meta, with meta taking precedence.
|
|
144
|
+
*
|
|
145
|
+
* @param inputs The current inputs record
|
|
146
|
+
* @param propsToMeta Array of prop keys to forward to meta
|
|
147
|
+
* @returns Updated inputs record with merged meta
|
|
148
|
+
*/
|
|
149
|
+
function mergeForwardedPropsToMeta(inputs, propsToMeta) {
|
|
150
|
+
const props = inputs['props'];
|
|
151
|
+
if (!props || propsToMeta.length === 0) {
|
|
152
|
+
return inputs;
|
|
153
|
+
}
|
|
154
|
+
// Extract values to forward from props
|
|
155
|
+
// Values are typed as FieldMeta-compatible since they're forwarded attributes (type, rows, cols, etc.)
|
|
156
|
+
const forwardedValues = {};
|
|
157
|
+
for (const key of propsToMeta) {
|
|
158
|
+
const value = props[key];
|
|
159
|
+
if (value !== undefined && value !== null) {
|
|
160
|
+
// Props being forwarded are known HTML attributes (string, number, boolean)
|
|
161
|
+
forwardedValues[key] = value;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// If nothing to forward, return inputs unchanged
|
|
165
|
+
if (Object.keys(forwardedValues).length === 0) {
|
|
166
|
+
return inputs;
|
|
167
|
+
}
|
|
168
|
+
// Merge: forwarded props first, then meta (meta wins)
|
|
169
|
+
const existingMeta = inputs['meta'];
|
|
170
|
+
const mergedMeta = {
|
|
171
|
+
...forwardedValues,
|
|
172
|
+
...existingMeta,
|
|
173
|
+
};
|
|
174
|
+
return {
|
|
175
|
+
...inputs,
|
|
176
|
+
meta: mergedMeta,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
138
179
|
/**
|
|
139
180
|
* Main field mapper function that uses the field registry to get the appropriate mapper
|
|
140
181
|
* based on the field's type property.
|
|
@@ -142,30 +183,49 @@ function baseFieldMapper(fieldDef) {
|
|
|
142
183
|
* This function must be called within an injection context where FIELD_SIGNAL_CONTEXT
|
|
143
184
|
* is provided, as mappers inject the context to access form state.
|
|
144
185
|
*
|
|
186
|
+
* For componentless fields (no loadComponent and no mapper), returns undefined
|
|
187
|
+
* since there's no component to bind inputs to. Callers should check for undefined
|
|
188
|
+
* and skip rendering logic for such fields.
|
|
189
|
+
*
|
|
190
|
+
* If the field type definition specifies `propsToMeta`, the specified props
|
|
191
|
+
* will be merged into the meta object (with meta taking precedence).
|
|
192
|
+
*
|
|
145
193
|
* @param fieldDef The field definition to map
|
|
146
194
|
* @param fieldRegistry The registry of field type definitions
|
|
147
|
-
* @returns Signal containing Record of input names to values for
|
|
195
|
+
* @returns Signal containing Record of input names to values, or undefined for componentless fields
|
|
148
196
|
*/
|
|
149
197
|
function mapFieldToInputs(fieldDef, fieldRegistry) {
|
|
150
198
|
// Get the field type definition from registry
|
|
151
199
|
const fieldType = fieldRegistry.get(fieldDef.type);
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
200
|
+
// Componentless field (no mapper and no loadComponent) - nothing to map
|
|
201
|
+
if (fieldType && !fieldType.loadComponent && !fieldType.mapper) {
|
|
202
|
+
return undefined;
|
|
203
|
+
}
|
|
204
|
+
// Get the base mapper result
|
|
205
|
+
const mapperResult = fieldType?.mapper ? fieldType.mapper(fieldDef) : baseFieldMapper(fieldDef);
|
|
206
|
+
// If no props forwarding configured, return as-is
|
|
207
|
+
const propsToMeta = fieldType?.propsToMeta;
|
|
208
|
+
if (!propsToMeta || propsToMeta.length === 0) {
|
|
209
|
+
return mapperResult;
|
|
156
210
|
}
|
|
157
|
-
//
|
|
158
|
-
|
|
159
|
-
|
|
211
|
+
// Wrap in computed to merge forwarded props into meta
|
|
212
|
+
return computed(() => {
|
|
213
|
+
const inputs = mapperResult();
|
|
214
|
+
return mergeForwardedPropsToMeta(inputs, propsToMeta);
|
|
215
|
+
});
|
|
160
216
|
}
|
|
161
217
|
|
|
162
218
|
/**
|
|
163
219
|
* Resolves a single field definition to a ResolvedField using RxJS.
|
|
164
220
|
* Loads the component asynchronously and maps inputs in the injection context.
|
|
165
221
|
*
|
|
222
|
+
* For componentless fields (e.g., hidden fields), returns undefined since
|
|
223
|
+
* there's nothing to render. These fields still contribute to form values
|
|
224
|
+
* through the form schema.
|
|
225
|
+
*
|
|
166
226
|
* @param fieldDef - The field definition to resolve
|
|
167
227
|
* @param context - The context containing dependencies for resolution
|
|
168
|
-
* @returns Observable that emits ResolvedField or undefined on error
|
|
228
|
+
* @returns Observable that emits ResolvedField or undefined (for componentless fields or on error)
|
|
169
229
|
*/
|
|
170
230
|
function resolveField(fieldDef, context) {
|
|
171
231
|
return from(context.loadTypeComponent(fieldDef.type)).pipe(map((component) => {
|
|
@@ -173,8 +233,16 @@ function resolveField(fieldDef, context) {
|
|
|
173
233
|
if (context.destroyRef.destroyed) {
|
|
174
234
|
return undefined;
|
|
175
235
|
}
|
|
236
|
+
// Componentless fields (e.g., hidden) return undefined - nothing to render
|
|
237
|
+
if (!component) {
|
|
238
|
+
return undefined;
|
|
239
|
+
}
|
|
176
240
|
// Run mapper in injection context
|
|
177
241
|
const inputs = runInInjectionContext(context.injector, () => mapFieldToInputs(fieldDef, context.registry));
|
|
242
|
+
// Fields with components should always have inputs (componentless fields are handled above)
|
|
243
|
+
if (!inputs) {
|
|
244
|
+
return undefined;
|
|
245
|
+
}
|
|
178
246
|
return {
|
|
179
247
|
key: fieldDef.key,
|
|
180
248
|
component,
|
|
@@ -646,18 +714,20 @@ function injectFieldRegistry() {
|
|
|
646
714
|
* Handles both synchronous component references and asynchronous
|
|
647
715
|
* dynamic imports. Automatically extracts default exports from ES modules.
|
|
648
716
|
*
|
|
717
|
+
* Returns `undefined` for componentless field types (e.g., hidden fields)
|
|
718
|
+
* that only contribute to form values without rendering UI.
|
|
719
|
+
*
|
|
649
720
|
* @param name - The name of the field type to load
|
|
650
|
-
* @returns Promise resolving to the component constructor
|
|
721
|
+
* @returns Promise resolving to the component constructor, or undefined for componentless fields
|
|
651
722
|
* @throws {Error} When field type is not registered or loading fails
|
|
652
723
|
*
|
|
653
724
|
* @example
|
|
654
725
|
* ```typescript
|
|
655
|
-
*
|
|
656
|
-
*
|
|
657
|
-
* const componentRef = vcr.createComponent(
|
|
658
|
-
* } catch (error) {
|
|
659
|
-
* console.error('Failed to load component:', error);
|
|
726
|
+
* const component = await fieldRegistry.loadTypeComponent('input');
|
|
727
|
+
* if (component) {
|
|
728
|
+
* const componentRef = vcr.createComponent(component);
|
|
660
729
|
* }
|
|
730
|
+
* // For componentless fields like 'hidden', component will be undefined
|
|
661
731
|
* ```
|
|
662
732
|
*/
|
|
663
733
|
async loadTypeComponent(name) {
|
|
@@ -665,19 +735,20 @@ function injectFieldRegistry() {
|
|
|
665
735
|
if (!fieldType) {
|
|
666
736
|
throw new DynamicFormError(`Field type "${name}" is not registered`);
|
|
667
737
|
}
|
|
738
|
+
// Componentless field types (e.g., hidden) don't have loadComponent
|
|
739
|
+
if (!fieldType.loadComponent) {
|
|
740
|
+
return undefined;
|
|
741
|
+
}
|
|
668
742
|
// Handle async loading
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
throw new DynamicFormError(`Failed to load component for field type "${name}": ${error}`);
|
|
678
|
-
}
|
|
743
|
+
try {
|
|
744
|
+
const result = await fieldType.loadComponent();
|
|
745
|
+
// Handle ES module imports - extract default export if needed
|
|
746
|
+
const moduleResult = result;
|
|
747
|
+
return (typeof moduleResult === 'object' && 'default' in moduleResult && moduleResult.default) || result;
|
|
748
|
+
}
|
|
749
|
+
catch (error) {
|
|
750
|
+
throw new DynamicFormError(`Failed to load component for field type "${name}": ${error}`);
|
|
679
751
|
}
|
|
680
|
-
throw new DynamicFormError(`Field type "${name}" has no component or loadComponent function`);
|
|
681
752
|
},
|
|
682
753
|
/**
|
|
683
754
|
* Gets all registered field type definitions.
|
|
@@ -901,10 +972,10 @@ class RootFormRegistryService {
|
|
|
901
972
|
this._formValueSignals.set(new Map());
|
|
902
973
|
this.formContexts.clear();
|
|
903
974
|
}
|
|
904
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.
|
|
905
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.
|
|
975
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: RootFormRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
976
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: RootFormRegistryService });
|
|
906
977
|
}
|
|
907
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.
|
|
978
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: RootFormRegistryService, decorators: [{
|
|
908
979
|
type: Injectable
|
|
909
980
|
}] });
|
|
910
981
|
|
|
@@ -1028,10 +1099,10 @@ class FieldContextRegistryService {
|
|
|
1028
1099
|
logger: this.logger,
|
|
1029
1100
|
};
|
|
1030
1101
|
}
|
|
1031
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.
|
|
1032
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.
|
|
1102
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: FieldContextRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1103
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: FieldContextRegistryService });
|
|
1033
1104
|
}
|
|
1034
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.
|
|
1105
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: FieldContextRegistryService, decorators: [{
|
|
1035
1106
|
type: Injectable
|
|
1036
1107
|
}] });
|
|
1037
1108
|
|
|
@@ -1371,10 +1442,10 @@ class FunctionRegistryService {
|
|
|
1371
1442
|
this.clearAsyncValidators();
|
|
1372
1443
|
this.clearHttpValidators();
|
|
1373
1444
|
}
|
|
1374
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.
|
|
1375
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.
|
|
1445
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: FunctionRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1446
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: FunctionRegistryService });
|
|
1376
1447
|
}
|
|
1377
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.
|
|
1448
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: FunctionRegistryService, decorators: [{
|
|
1378
1449
|
type: Injectable
|
|
1379
1450
|
}] });
|
|
1380
1451
|
|
|
@@ -3059,10 +3130,10 @@ class SchemaRegistryService {
|
|
|
3059
3130
|
}
|
|
3060
3131
|
return schema;
|
|
3061
3132
|
}
|
|
3062
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.
|
|
3063
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.
|
|
3133
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SchemaRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3134
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SchemaRegistryService });
|
|
3064
3135
|
}
|
|
3065
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.
|
|
3136
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SchemaRegistryService, decorators: [{
|
|
3066
3137
|
type: Injectable
|
|
3067
3138
|
}] });
|
|
3068
3139
|
|
|
@@ -3183,6 +3254,16 @@ function isArrayField(field) {
|
|
|
3183
3254
|
return field.type === 'array' && 'fields' in field;
|
|
3184
3255
|
}
|
|
3185
3256
|
|
|
3257
|
+
/**
|
|
3258
|
+
* Type guard to check if a field is a hidden field.
|
|
3259
|
+
*
|
|
3260
|
+
* @param field - The field to check
|
|
3261
|
+
* @returns True if the field is a HiddenField
|
|
3262
|
+
*/
|
|
3263
|
+
function isHiddenField(field) {
|
|
3264
|
+
return field.type === 'hidden';
|
|
3265
|
+
}
|
|
3266
|
+
|
|
3186
3267
|
/**
|
|
3187
3268
|
* Type guard for RowField with proper type narrowing
|
|
3188
3269
|
*/
|
|
@@ -3190,6 +3271,36 @@ function isArrayField(field) {
|
|
|
3190
3271
|
function isRowField(field) {
|
|
3191
3272
|
return field.type === 'row' && 'fields' in field && Array.isArray(field.fields);
|
|
3192
3273
|
}
|
|
3274
|
+
/**
|
|
3275
|
+
* Validates that a row field doesn't contain hidden fields.
|
|
3276
|
+
* Hidden fields are not allowed in rows because rows are for horizontal layouts,
|
|
3277
|
+
* and hidden fields don't render anything.
|
|
3278
|
+
*
|
|
3279
|
+
* @param rowField The row field to validate
|
|
3280
|
+
* @returns true if valid (no hidden fields), false otherwise
|
|
3281
|
+
*/
|
|
3282
|
+
function validateRowNesting(rowField) {
|
|
3283
|
+
return !hasHiddenFields(rowField.fields);
|
|
3284
|
+
}
|
|
3285
|
+
/**
|
|
3286
|
+
* Recursively checks if fields contain any hidden fields
|
|
3287
|
+
* @param fields Array of field definitions to check
|
|
3288
|
+
* @returns true if hidden fields found, false otherwise
|
|
3289
|
+
*/
|
|
3290
|
+
function hasHiddenFields(fields) {
|
|
3291
|
+
for (const field of fields) {
|
|
3292
|
+
if (isHiddenField(field)) {
|
|
3293
|
+
return true;
|
|
3294
|
+
}
|
|
3295
|
+
// Check group fields for nested hidden fields
|
|
3296
|
+
if (isGroupField(field)) {
|
|
3297
|
+
if (hasHiddenFields(field.fields)) {
|
|
3298
|
+
return true;
|
|
3299
|
+
}
|
|
3300
|
+
}
|
|
3301
|
+
}
|
|
3302
|
+
return false;
|
|
3303
|
+
}
|
|
3193
3304
|
|
|
3194
3305
|
/**
|
|
3195
3306
|
* Type guard for PageField with proper type narrowing
|
|
@@ -3993,10 +4104,10 @@ class EventBus {
|
|
|
3993
4104
|
}
|
|
3994
4105
|
return this.pipeline$.pipe(filter((event) => event.type === eventType));
|
|
3995
4106
|
}
|
|
3996
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.
|
|
3997
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.
|
|
4107
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: EventBus, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
4108
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: EventBus });
|
|
3998
4109
|
}
|
|
3999
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.
|
|
4110
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: EventBus, decorators: [{
|
|
4000
4111
|
type: Injectable
|
|
4001
4112
|
}] });
|
|
4002
4113
|
|
|
@@ -4536,7 +4647,8 @@ function convertBuiltInToCustomValidator(config) {
|
|
|
4536
4647
|
* Comprehensive form configuration validator that checks:
|
|
4537
4648
|
* 1. Form mode consistency (paged vs non-paged)
|
|
4538
4649
|
* 2. Page nesting rules
|
|
4539
|
-
* 3.
|
|
4650
|
+
* 3. Row nesting rules (no hidden fields in rows)
|
|
4651
|
+
* 4. Field placement constraints
|
|
4540
4652
|
*/
|
|
4541
4653
|
class FormModeValidator {
|
|
4542
4654
|
/**
|
|
@@ -4603,6 +4715,47 @@ class FormModeValidator {
|
|
|
4603
4715
|
}
|
|
4604
4716
|
}
|
|
4605
4717
|
}
|
|
4718
|
+
// Warn about hidden fields in rows (they work but don't render, which may be confusing)
|
|
4719
|
+
const rowWarnings = this.collectRowHiddenFieldWarnings(fields);
|
|
4720
|
+
warnings.push(...rowWarnings);
|
|
4721
|
+
return warnings;
|
|
4722
|
+
}
|
|
4723
|
+
/**
|
|
4724
|
+
* Recursively collects warnings for hidden fields inside rows
|
|
4725
|
+
* @param fields The form field definitions to check
|
|
4726
|
+
* @param path Current path for warning messages
|
|
4727
|
+
* @returns Array of warning messages
|
|
4728
|
+
*/
|
|
4729
|
+
static collectRowHiddenFieldWarnings(fields, path = '') {
|
|
4730
|
+
if (!fields) {
|
|
4731
|
+
return [];
|
|
4732
|
+
}
|
|
4733
|
+
const warnings = [];
|
|
4734
|
+
for (let i = 0; i < fields.length; i++) {
|
|
4735
|
+
const field = fields[i];
|
|
4736
|
+
const fieldPath = path ? `${path}.fields[${i}]` : `fields[${i}]`;
|
|
4737
|
+
const fieldKey = field.key || 'unknown';
|
|
4738
|
+
if (isRowField(field)) {
|
|
4739
|
+
if (!validateRowNesting(field)) {
|
|
4740
|
+
warnings.push(`Row field at ${fieldPath} (key: "${fieldKey}") contains hidden fields. ` +
|
|
4741
|
+
`Hidden fields in rows don't render anything - consider placing them outside the row.`);
|
|
4742
|
+
}
|
|
4743
|
+
// Continue checking nested rows within the row's children
|
|
4744
|
+
warnings.push(...this.collectRowHiddenFieldWarnings(field.fields, fieldPath));
|
|
4745
|
+
}
|
|
4746
|
+
else if (isPageField(field)) {
|
|
4747
|
+
// Check rows within pages
|
|
4748
|
+
warnings.push(...this.collectRowHiddenFieldWarnings(field.fields, fieldPath));
|
|
4749
|
+
}
|
|
4750
|
+
else if (isGroupField(field)) {
|
|
4751
|
+
// Check rows within groups
|
|
4752
|
+
warnings.push(...this.collectRowHiddenFieldWarnings(field.fields, fieldPath));
|
|
4753
|
+
}
|
|
4754
|
+
else if (isArrayField(field)) {
|
|
4755
|
+
// Check rows within array templates
|
|
4756
|
+
warnings.push(...this.collectRowHiddenFieldWarnings(field.fields, fieldPath));
|
|
4757
|
+
}
|
|
4758
|
+
}
|
|
4606
4759
|
return warnings;
|
|
4607
4760
|
}
|
|
4608
4761
|
}
|
|
@@ -5074,8 +5227,8 @@ class PageOrchestratorComponent {
|
|
|
5074
5227
|
}
|
|
5075
5228
|
return false;
|
|
5076
5229
|
}
|
|
5077
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.
|
|
5078
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.
|
|
5230
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: PageOrchestratorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5231
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: PageOrchestratorComponent, isStandalone: true, selector: "div[page-orchestrator]", inputs: { pageFields: { classPropertyName: "pageFields", publicName: "pageFields", isSignal: true, isRequired: true, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null }, fieldSignalContext: { classPropertyName: "fieldSignalContext", publicName: "fieldSignalContext", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "attr.data-current-page": "state().currentPageIndex", "attr.data-total-pages": "state().totalPages" }, classAttribute: "df-page-orchestrator" }, providers: [
|
|
5079
5232
|
{
|
|
5080
5233
|
provide: FIELD_SIGNAL_CONTEXT,
|
|
5081
5234
|
useFactory: (orchestrator) => orchestrator.extendedFieldSignalContext(),
|
|
@@ -5105,9 +5258,9 @@ class PageOrchestratorComponent {
|
|
|
5105
5258
|
}
|
|
5106
5259
|
}
|
|
5107
5260
|
}
|
|
5108
|
-
`, isInline: true, styles: [":host{display:block;position:relative;width:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [import('./ng-forge-dynamic-forms-page-field.component-
|
|
5261
|
+
`, isInline: true, styles: [":host{display:block;position:relative;width:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [import('./ng-forge-dynamic-forms-page-field.component-rdGD8A9d.mjs').then(m => m.default)], () => [import('./ng-forge-dynamic-forms-page-field.component-rdGD8A9d.mjs').then(m => m.default)]] });
|
|
5109
5262
|
}
|
|
5110
|
-
i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "21.0.
|
|
5263
|
+
i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "21.0.8", ngImport: i0, type: PageOrchestratorComponent, resolveDeferredDeps: () => [import('./ng-forge-dynamic-forms-page-field.component-rdGD8A9d.mjs').then(m => m.default)], resolveMetadata: PageFieldComponent => ({ decorators: [{
|
|
5111
5264
|
type: Component,
|
|
5112
5265
|
args: [{ selector: 'div[page-orchestrator]', imports: [PageFieldComponent], template: `
|
|
5113
5266
|
@for (pageField of pageFields(); track pageField.key; let i = $index) {
|
|
@@ -5560,8 +5713,8 @@ class DynamicForm {
|
|
|
5560
5713
|
ngOnDestroy() {
|
|
5561
5714
|
this.rootFormRegistry.unregisterForm();
|
|
5562
5715
|
}
|
|
5563
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.
|
|
5564
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.
|
|
5716
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: DynamicForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5717
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: DynamicForm, isStandalone: true, selector: "form[dynamic-form]", inputs: { config: { classPropertyName: "config", publicName: "dynamic-form", isSignal: true, isRequired: true, transformFunction: null }, formOptions: { classPropertyName: "formOptions", publicName: "formOptions", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", validityChange: "validityChange", dirtyChange: "dirtyChange", submitted: "submitted", reset: "reset", cleared: "cleared", events: "events", initialized: "initialized", onPageChange: "onPageChange", onPageNavigationStateChange: "onPageNavigationStateChange" }, host: { attributes: { "novalidate": "" }, listeners: { "submit": "onNativeSubmit($event)" }, properties: { "class.disabled": "disabled()", "class.df-form-paged": "formModeDetection().mode === \"paged\"", "class.df-form-non-paged": "formModeDetection().mode === \"non-paged\"", "attr.data-form-mode": "formModeDetection().mode" }, classAttribute: "df-dynamic-form df-form" }, providers: [EventBus, SchemaRegistryService, FunctionRegistryService, RootFormRegistryService, FieldContextRegistryService], ngImport: i0, template: `
|
|
5565
5718
|
@if (formModeDetection().mode === 'paged') {
|
|
5566
5719
|
<div page-orchestrator [pageFields]="pageFieldDefinitions()" [form]="form()" [fieldSignalContext]="fieldSignalContext()"></div>
|
|
5567
5720
|
} @else {
|
|
@@ -5571,7 +5724,7 @@ class DynamicForm {
|
|
|
5571
5724
|
}
|
|
5572
5725
|
`, isInline: true, styles: [":host,.df-form{--df-grid-columns: 12;--df-grid-gap: .5rem;--df-grid-row-gap: .5rem;--df-breakpoint-sm: 576px;--df-breakpoint-md: 768px;--df-breakpoint-lg: 992px;--df-breakpoint-xl: 1200px;--df-grid-gap-sm: .5rem;--df-grid-gap-md: .5rem;--df-grid-gap-lg: .5rem;--df-grid-gap-xl: .5rem;--df-grid-row-gap-sm: .5rem;--df-grid-row-gap-md: .5rem;--df-grid-row-gap-lg: .5rem;--df-grid-row-gap-xl: .5rem;--df-group-gap: var(--df-grid-gap);--df-group-padding: var(--df-grid-gap)}.df-form{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap);width:100%}.df-form>*{grid-column:1/-1}.df-row{display:grid;grid-template-columns:repeat(var(--df-grid-columns, 12),1fr);gap:var(--df-grid-gap);align-items:start;width:100%}.df-row>*:not([class*=df-col-]){grid-column:1/-1}.df-col-1{grid-column:span 1}.df-col-2{grid-column:span 2}.df-col-3{grid-column:span 3}.df-col-4{grid-column:span 4}.df-col-5{grid-column:span 5}.df-col-6{grid-column:span 6}.df-col-7{grid-column:span 7}.df-col-8{grid-column:span 8}.df-col-9{grid-column:span 9}.df-col-10{grid-column:span 10}.df-col-11{grid-column:span 11}.df-col-12{grid-column:span 12}.df-col-auto{grid-column:span auto;width:auto}.df-col-full{grid-column:1/-1}.df-col-start-1{grid-column-start:1}.df-col-start-2{grid-column-start:2}.df-col-start-3{grid-column-start:3}.df-col-start-4{grid-column-start:4}.df-col-start-5{grid-column-start:5}.df-col-start-6{grid-column-start:6}.df-col-start-7{grid-column-start:7}.df-col-start-8{grid-column-start:8}.df-col-start-9{grid-column-start:9}.df-col-start-10{grid-column-start:10}.df-col-start-11{grid-column-start:11}.df-col-start-12{grid-column-start:12}.df-col-end-1{grid-column-end:1}.df-col-end-2{grid-column-end:2}.df-col-end-3{grid-column-end:3}.df-col-end-4{grid-column-end:4}.df-col-end-5{grid-column-end:5}.df-col-end-6{grid-column-end:6}.df-col-end-7{grid-column-end:7}.df-col-end-8{grid-column-end:8}.df-col-end-9{grid-column-end:9}.df-col-end-10{grid-column-end:10}.df-col-end-11{grid-column-end:11}.df-col-end-12{grid-column-end:12}.df-col-end-13{grid-column-end:13}@media(max-width:576px){.df-form{--df-grid-gap: var(--df-grid-gap-sm);--df-grid-row-gap: var(--df-grid-row-gap-sm)}.df-row{grid-template-columns:1fr}.df-row>*{grid-column:1/-1!important}.df-row.df-row-mobile-keep-cols{grid-template-columns:repeat(var(--df-grid-columns),1fr)}.df-row.df-row-mobile-keep-cols>*{grid-column:revert!important}}@media(min-width:577px)and (max-width:768px){.df-form{--df-grid-gap: var(--df-grid-gap-md);--df-grid-row-gap: var(--df-grid-row-gap-md)}.df-row{--df-grid-columns: 6}.df-col-sm-1{grid-column:span 1}.df-col-sm-2{grid-column:span 2}.df-col-sm-3{grid-column:span 3}.df-col-sm-4{grid-column:span 4}.df-col-sm-5{grid-column:span 5}.df-col-sm-6{grid-column:span 6}.df-col-sm-full{grid-column:1/-1}}@media(min-width:769px)and (max-width:992px){.df-form{--df-grid-gap: var(--df-grid-gap-lg);--df-grid-row-gap: var(--df-grid-row-gap-lg)}.df-col-md-1{grid-column:span 1}.df-col-md-2{grid-column:span 2}.df-col-md-3{grid-column:span 3}.df-col-md-4{grid-column:span 4}.df-col-md-5{grid-column:span 5}.df-col-md-6{grid-column:span 6}.df-col-md-7{grid-column:span 7}.df-col-md-8{grid-column:span 8}.df-col-md-9{grid-column:span 9}.df-col-md-10{grid-column:span 10}.df-col-md-11{grid-column:span 11}.df-col-md-12{grid-column:span 12}.df-col-md-full{grid-column:1/-1}}@media(min-width:993px){.df-form{--df-grid-gap: var(--df-grid-gap-xl);--df-grid-row-gap: var(--df-grid-row-gap-xl)}.df-col-lg-1{grid-column:span 1}.df-col-lg-2{grid-column:span 2}.df-col-lg-3{grid-column:span 3}.df-col-lg-4{grid-column:span 4}.df-col-lg-5{grid-column:span 5}.df-col-lg-6{grid-column:span 6}.df-col-lg-7{grid-column:span 7}.df-col-lg-8{grid-column:span 8}.df-col-lg-9{grid-column:span 9}.df-col-lg-10{grid-column:span 10}.df-col-lg-11{grid-column:span 11}.df-col-lg-12{grid-column:span 12}.df-col-lg-full{grid-column:1/-1}}.df-gap-none{--df-grid-gap: 0}.df-gap-xs{--df-grid-gap: .25rem}.df-gap-sm{--df-grid-gap: .5rem}.df-gap-md{--df-grid-gap: 1rem}.df-gap-lg{--df-grid-gap: 1.5rem}.df-gap-xl{--df-grid-gap: 2rem}.df-row-gap-none{--df-grid-row-gap: 0}.df-row-gap-xs{--df-grid-row-gap: .25rem}.df-row-gap-sm{--df-grid-row-gap: .5rem}.df-row-gap-md{--df-grid-row-gap: 1rem}.df-row-gap-lg{--df-grid-row-gap: 1.5rem}.df-row-gap-xl{--df-grid-row-gap: 2rem}.df-field{display:block;width:100%;min-width:0;overflow:hidden;margin:0}.df-group,.df-page{display:block;width:100%}.df-form.disabled,.df-row.disabled,.df-field.disabled{opacity:.6;pointer-events:none}.df-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-sr-only-focusable:focus,.df-sr-only-focusable:active{position:static;width:auto;height:auto;padding:inherit;margin:inherit;overflow:visible;clip:auto;white-space:normal}.df-live-region{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-form :focus-visible{outline:2px solid var(--df-focus-color, #005fcc);outline-offset:2px}.df-group:focus-within{outline:1px dashed var(--df-focus-color, #005fcc);outline-offset:4px}:host{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap);width:100%}:host>*{grid-column:1/-1}:host.df-form-spacing-custom{--df-grid-row-gap: var(--form-custom-spacing, 1.5rem)}:host.df-form-gap-none{--df-grid-row-gap: 0}:host.df-form-gap-xs{--df-grid-row-gap: .25rem}:host.df-form-gap-sm{--df-grid-row-gap: .5rem}:host.df-form-gap-md{--df-grid-row-gap: 1rem}:host.df-form-gap-lg{--df-grid-row-gap: 1.5rem}:host.df-form-gap-xl{--df-grid-row-gap: 2rem}:host.df-form-paged{--df-grid-row-gap: 0}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "component", type: PageOrchestratorComponent, selector: "div[page-orchestrator]", inputs: ["pageFields", "form", "fieldSignalContext"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
5573
5726
|
}
|
|
5574
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.
|
|
5727
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: DynamicForm, decorators: [{
|
|
5575
5728
|
type: Component,
|
|
5576
5729
|
args: [{ selector: 'form[dynamic-form]', imports: [NgComponentOutlet, PageOrchestratorComponent], template: `
|
|
5577
5730
|
@if (formModeDetection().mode === 'paged') {
|
|
@@ -5583,6 +5736,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
5583
5736
|
}
|
|
5584
5737
|
`, providers: [EventBus, SchemaRegistryService, FunctionRegistryService, RootFormRegistryService, FieldContextRegistryService], host: {
|
|
5585
5738
|
class: 'df-dynamic-form df-form',
|
|
5739
|
+
novalidate: '', // Disable browser validation - Angular Signal Forms handles validation
|
|
5586
5740
|
'[class.disabled]': 'disabled()',
|
|
5587
5741
|
'[class.df-form-paged]': 'formModeDetection().mode === "paged"',
|
|
5588
5742
|
'[class.df-form-non-paged]': 'formModeDetection().mode === "non-paged"',
|
|
@@ -5756,16 +5910,21 @@ const BUILT_IN_FIELDS = [
|
|
|
5756
5910
|
},
|
|
5757
5911
|
{
|
|
5758
5912
|
name: 'page',
|
|
5759
|
-
loadComponent: () => import('./ng-forge-dynamic-forms-page-field.component-
|
|
5913
|
+
loadComponent: () => import('./ng-forge-dynamic-forms-page-field.component-rdGD8A9d.mjs'),
|
|
5760
5914
|
mapper: pageFieldMapper,
|
|
5761
5915
|
valueHandling: 'flatten',
|
|
5762
5916
|
},
|
|
5763
5917
|
{
|
|
5764
5918
|
name: 'text',
|
|
5765
|
-
loadComponent: () => import('./ng-forge-dynamic-forms-text-field.component-
|
|
5919
|
+
loadComponent: () => import('./ng-forge-dynamic-forms-text-field.component-CDxka2KD.mjs'),
|
|
5766
5920
|
mapper: textFieldMapper,
|
|
5767
5921
|
valueHandling: 'exclude',
|
|
5768
5922
|
},
|
|
5923
|
+
{
|
|
5924
|
+
name: 'hidden',
|
|
5925
|
+
// Componentless field - no loadComponent or mapper needed
|
|
5926
|
+
valueHandling: 'include',
|
|
5927
|
+
},
|
|
5769
5928
|
];
|
|
5770
5929
|
|
|
5771
5930
|
/**
|
|
@@ -5879,6 +6038,8 @@ function provideDynamicForm(...items) {
|
|
|
5879
6038
|
const defaultLoggerProvider = hasLoggerFeature ? [] : [{ provide: DynamicFormLogger, useValue: new ConsoleLogger() }];
|
|
5880
6039
|
return makeEnvironmentProviders([
|
|
5881
6040
|
...defaultLoggerProvider,
|
|
6041
|
+
// Always provide default Signal Forms classes (ng-touched, ng-invalid, etc.)
|
|
6042
|
+
provideSignalFormsConfig({ classes: NG_STATUS_CLASSES }),
|
|
5882
6043
|
{
|
|
5883
6044
|
provide: FIELD_REGISTRY,
|
|
5884
6045
|
useFactory: () => {
|
|
@@ -6224,6 +6385,51 @@ function dynamicTextToObservable(value, injector) {
|
|
|
6224
6385
|
return of(String(value));
|
|
6225
6386
|
}
|
|
6226
6387
|
|
|
6388
|
+
/**
|
|
6389
|
+
* Applies meta attributes to a DOM element and tracks which attributes were applied.
|
|
6390
|
+
*
|
|
6391
|
+
* This utility handles:
|
|
6392
|
+
* - Removing previously applied attributes that are no longer in meta
|
|
6393
|
+
* - Setting new attributes from meta
|
|
6394
|
+
* - Converting all values to strings via String()
|
|
6395
|
+
*
|
|
6396
|
+
* @param element - The DOM element to apply attributes to
|
|
6397
|
+
* @param meta - The meta object containing attributes to apply
|
|
6398
|
+
* @param previouslyApplied - Set of attribute names that were previously applied
|
|
6399
|
+
* @returns A new Set containing the attribute names that were applied
|
|
6400
|
+
*
|
|
6401
|
+
* @example
|
|
6402
|
+
* ```typescript
|
|
6403
|
+
* private appliedAttrs = new Set<string>();
|
|
6404
|
+
*
|
|
6405
|
+
* explicitEffect([this.meta], ([meta]) => {
|
|
6406
|
+
* const input = this.el.nativeElement.querySelector('input');
|
|
6407
|
+
* if (input) {
|
|
6408
|
+
* this.appliedAttrs = applyMetaToElement(input, meta, this.appliedAttrs);
|
|
6409
|
+
* }
|
|
6410
|
+
* });
|
|
6411
|
+
* ```
|
|
6412
|
+
*/
|
|
6413
|
+
function applyMetaToElement(element, meta, previouslyApplied) {
|
|
6414
|
+
const newApplied = new Set();
|
|
6415
|
+
// Remove old attributes no longer in meta
|
|
6416
|
+
for (const attr of previouslyApplied) {
|
|
6417
|
+
if (!meta || !(attr in meta) || meta[attr] === undefined) {
|
|
6418
|
+
element.removeAttribute(attr);
|
|
6419
|
+
}
|
|
6420
|
+
}
|
|
6421
|
+
if (!meta)
|
|
6422
|
+
return newApplied;
|
|
6423
|
+
// Apply new attributes
|
|
6424
|
+
for (const [key, value] of Object.entries(meta)) {
|
|
6425
|
+
if (value === undefined || value === null)
|
|
6426
|
+
continue;
|
|
6427
|
+
element.setAttribute(key, String(value));
|
|
6428
|
+
newApplied.add(key);
|
|
6429
|
+
}
|
|
6430
|
+
return newApplied;
|
|
6431
|
+
}
|
|
6432
|
+
|
|
6227
6433
|
/**
|
|
6228
6434
|
* Pipe that handles dynamic text resolution with support for static strings,
|
|
6229
6435
|
* Observables, and Signals.
|
|
@@ -6264,10 +6470,10 @@ class DynamicTextPipe {
|
|
|
6264
6470
|
}
|
|
6265
6471
|
return of(value || '');
|
|
6266
6472
|
}
|
|
6267
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.
|
|
6268
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.
|
|
6473
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: DynamicTextPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
6474
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.8", ngImport: i0, type: DynamicTextPipe, isStandalone: true, name: "dynamicText" });
|
|
6269
6475
|
}
|
|
6270
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.
|
|
6476
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: DynamicTextPipe, decorators: [{
|
|
6271
6477
|
type: Pipe,
|
|
6272
6478
|
args: [{
|
|
6273
6479
|
name: 'dynamicText',
|
|
@@ -6370,14 +6576,14 @@ class RowFieldComponent {
|
|
|
6370
6576
|
}
|
|
6371
6577
|
});
|
|
6372
6578
|
}
|
|
6373
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.
|
|
6374
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.
|
|
6579
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: RowFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6580
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: RowFieldComponent, isStandalone: true, selector: "div[row-field]", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "class.disabled": "disabled()", "id": "`${key()}`", "attr.data-testid": "key()" }, classAttribute: "df-field df-row" }, ngImport: i0, template: `
|
|
6375
6581
|
@for (field of resolvedFields(); track field.key) {
|
|
6376
6582
|
<ng-container *ngComponentOutlet="field.component; injector: field.injector; inputs: field.inputs()" />
|
|
6377
6583
|
}
|
|
6378
6584
|
`, isInline: true, styles: [":host,.df-form{--df-grid-columns: 12;--df-grid-gap: .5rem;--df-grid-row-gap: .5rem;--df-breakpoint-sm: 576px;--df-breakpoint-md: 768px;--df-breakpoint-lg: 992px;--df-breakpoint-xl: 1200px;--df-grid-gap-sm: .5rem;--df-grid-gap-md: .5rem;--df-grid-gap-lg: .5rem;--df-grid-gap-xl: .5rem;--df-grid-row-gap-sm: .5rem;--df-grid-row-gap-md: .5rem;--df-grid-row-gap-lg: .5rem;--df-grid-row-gap-xl: .5rem;--df-group-gap: var(--df-grid-gap);--df-group-padding: var(--df-grid-gap)}.df-form{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap);width:100%}.df-form>*{grid-column:1/-1}.df-row{display:grid;grid-template-columns:repeat(var(--df-grid-columns, 12),1fr);gap:var(--df-grid-gap);align-items:start;width:100%}.df-row>*:not([class*=df-col-]){grid-column:1/-1}.df-col-1{grid-column:span 1}.df-col-2{grid-column:span 2}.df-col-3{grid-column:span 3}.df-col-4{grid-column:span 4}.df-col-5{grid-column:span 5}.df-col-6{grid-column:span 6}.df-col-7{grid-column:span 7}.df-col-8{grid-column:span 8}.df-col-9{grid-column:span 9}.df-col-10{grid-column:span 10}.df-col-11{grid-column:span 11}.df-col-12{grid-column:span 12}.df-col-auto{grid-column:span auto;width:auto}.df-col-full{grid-column:1/-1}.df-col-start-1{grid-column-start:1}.df-col-start-2{grid-column-start:2}.df-col-start-3{grid-column-start:3}.df-col-start-4{grid-column-start:4}.df-col-start-5{grid-column-start:5}.df-col-start-6{grid-column-start:6}.df-col-start-7{grid-column-start:7}.df-col-start-8{grid-column-start:8}.df-col-start-9{grid-column-start:9}.df-col-start-10{grid-column-start:10}.df-col-start-11{grid-column-start:11}.df-col-start-12{grid-column-start:12}.df-col-end-1{grid-column-end:1}.df-col-end-2{grid-column-end:2}.df-col-end-3{grid-column-end:3}.df-col-end-4{grid-column-end:4}.df-col-end-5{grid-column-end:5}.df-col-end-6{grid-column-end:6}.df-col-end-7{grid-column-end:7}.df-col-end-8{grid-column-end:8}.df-col-end-9{grid-column-end:9}.df-col-end-10{grid-column-end:10}.df-col-end-11{grid-column-end:11}.df-col-end-12{grid-column-end:12}.df-col-end-13{grid-column-end:13}@media(max-width:576px){.df-form{--df-grid-gap: var(--df-grid-gap-sm);--df-grid-row-gap: var(--df-grid-row-gap-sm)}.df-row{grid-template-columns:1fr}.df-row>*{grid-column:1/-1!important}.df-row.df-row-mobile-keep-cols{grid-template-columns:repeat(var(--df-grid-columns),1fr)}.df-row.df-row-mobile-keep-cols>*{grid-column:revert!important}}@media(min-width:577px)and (max-width:768px){.df-form{--df-grid-gap: var(--df-grid-gap-md);--df-grid-row-gap: var(--df-grid-row-gap-md)}.df-row{--df-grid-columns: 6}.df-col-sm-1{grid-column:span 1}.df-col-sm-2{grid-column:span 2}.df-col-sm-3{grid-column:span 3}.df-col-sm-4{grid-column:span 4}.df-col-sm-5{grid-column:span 5}.df-col-sm-6{grid-column:span 6}.df-col-sm-full{grid-column:1/-1}}@media(min-width:769px)and (max-width:992px){.df-form{--df-grid-gap: var(--df-grid-gap-lg);--df-grid-row-gap: var(--df-grid-row-gap-lg)}.df-col-md-1{grid-column:span 1}.df-col-md-2{grid-column:span 2}.df-col-md-3{grid-column:span 3}.df-col-md-4{grid-column:span 4}.df-col-md-5{grid-column:span 5}.df-col-md-6{grid-column:span 6}.df-col-md-7{grid-column:span 7}.df-col-md-8{grid-column:span 8}.df-col-md-9{grid-column:span 9}.df-col-md-10{grid-column:span 10}.df-col-md-11{grid-column:span 11}.df-col-md-12{grid-column:span 12}.df-col-md-full{grid-column:1/-1}}@media(min-width:993px){.df-form{--df-grid-gap: var(--df-grid-gap-xl);--df-grid-row-gap: var(--df-grid-row-gap-xl)}.df-col-lg-1{grid-column:span 1}.df-col-lg-2{grid-column:span 2}.df-col-lg-3{grid-column:span 3}.df-col-lg-4{grid-column:span 4}.df-col-lg-5{grid-column:span 5}.df-col-lg-6{grid-column:span 6}.df-col-lg-7{grid-column:span 7}.df-col-lg-8{grid-column:span 8}.df-col-lg-9{grid-column:span 9}.df-col-lg-10{grid-column:span 10}.df-col-lg-11{grid-column:span 11}.df-col-lg-12{grid-column:span 12}.df-col-lg-full{grid-column:1/-1}}.df-gap-none{--df-grid-gap: 0}.df-gap-xs{--df-grid-gap: .25rem}.df-gap-sm{--df-grid-gap: .5rem}.df-gap-md{--df-grid-gap: 1rem}.df-gap-lg{--df-grid-gap: 1.5rem}.df-gap-xl{--df-grid-gap: 2rem}.df-row-gap-none{--df-grid-row-gap: 0}.df-row-gap-xs{--df-grid-row-gap: .25rem}.df-row-gap-sm{--df-grid-row-gap: .5rem}.df-row-gap-md{--df-grid-row-gap: 1rem}.df-row-gap-lg{--df-grid-row-gap: 1.5rem}.df-row-gap-xl{--df-grid-row-gap: 2rem}.df-field{display:block;width:100%;min-width:0;overflow:hidden;margin:0}.df-group,.df-page{display:block;width:100%}.df-form.disabled,.df-row.disabled,.df-field.disabled{opacity:.6;pointer-events:none}.df-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-sr-only-focusable:focus,.df-sr-only-focusable:active{position:static;width:auto;height:auto;padding:inherit;margin:inherit;overflow:visible;clip:auto;white-space:normal}.df-live-region{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-form :focus-visible{outline:2px solid var(--df-focus-color, #005fcc);outline-offset:2px}.df-group:focus-within{outline:1px dashed var(--df-focus-color, #005fcc);outline-offset:4px}:host{display:flex;flex-wrap:wrap;gap:var(--df-grid-gap);align-items:flex-start;width:100%}:host ::ng-deep>*:not([class*=df-col-]){flex:0 0 auto}:host ::ng-deep>.df-col-1{flex:0 0 calc(8.3333333333% - var(--df-grid-gap) * .9166666667);max-width:calc(8.3333333333% - var(--df-grid-gap) * .9166666667)}:host ::ng-deep>.df-col-2{flex:0 0 calc(16.6666666667% - var(--df-grid-gap) * .8333333333);max-width:calc(16.6666666667% - var(--df-grid-gap) * .8333333333)}:host ::ng-deep>.df-col-3{flex:0 0 calc(25% - var(--df-grid-gap) * .75);max-width:calc(25% - var(--df-grid-gap) * .75)}:host ::ng-deep>.df-col-4{flex:0 0 calc(33.3333333333% - var(--df-grid-gap) * .6666666667);max-width:calc(33.3333333333% - var(--df-grid-gap) * .6666666667)}:host ::ng-deep>.df-col-5{flex:0 0 calc(41.6666666667% - var(--df-grid-gap) * .5833333333);max-width:calc(41.6666666667% - var(--df-grid-gap) * .5833333333)}:host ::ng-deep>.df-col-6{flex:0 0 calc(50% - var(--df-grid-gap) * .5);max-width:calc(50% - var(--df-grid-gap) * .5)}:host ::ng-deep>.df-col-7{flex:0 0 calc(58.3333333333% - var(--df-grid-gap) * .4166666667);max-width:calc(58.3333333333% - var(--df-grid-gap) * .4166666667)}:host ::ng-deep>.df-col-8{flex:0 0 calc(66.6666666667% - var(--df-grid-gap) * .3333333333);max-width:calc(66.6666666667% - var(--df-grid-gap) * .3333333333)}:host ::ng-deep>.df-col-9{flex:0 0 calc(75% - var(--df-grid-gap) * .25);max-width:calc(75% - var(--df-grid-gap) * .25)}:host ::ng-deep>.df-col-10{flex:0 0 calc(83.3333333333% - var(--df-grid-gap) * .1666666667);max-width:calc(83.3333333333% - var(--df-grid-gap) * .1666666667)}:host ::ng-deep>.df-col-11{flex:0 0 calc(91.6666666667% - var(--df-grid-gap) * .0833333333);max-width:calc(91.6666666667% - var(--df-grid-gap) * .0833333333)}:host ::ng-deep>.df-col-12{flex:0 0 calc(100% - var(--df-grid-gap) * 0);max-width:calc(100% - var(--df-grid-gap) * 0)}:host.df-gap-custom{--df-grid-gap: var(--row-custom-gap, 1rem)}@media(max-width:576px){:host.df-row-mobile-stack{flex-direction:column}:host.df-row-mobile-stack ::ng-deep>*{flex:0 0 100%!important;max-width:100%!important}}@media(min-width:577px)and (max-width:768px){:host.df-row-tablet-2col ::ng-deep>*{flex:0 0 calc(50% - var(--df-grid-gap) / 2);max-width:calc(50% - var(--df-grid-gap) / 2)}}@media(max-width:576px){:host{flex-direction:column}:host ::ng-deep>*{flex:0 0 100%!important;max-width:100%!important}:host.df-row-mobile-keep-cols{flex-direction:row}:host.df-row-mobile-keep-cols ::ng-deep>*:not([class*=df-col-]){flex:0 0 auto!important;max-width:none!important}}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6379
6585
|
}
|
|
6380
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.
|
|
6586
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: RowFieldComponent, decorators: [{
|
|
6381
6587
|
type: Component,
|
|
6382
6588
|
args: [{ selector: 'div[row-field]', imports: [NgComponentOutlet], template: `
|
|
6383
6589
|
@for (field of resolvedFields(); track field.key) {
|
|
@@ -6547,14 +6753,14 @@ class GroupFieldComponent {
|
|
|
6547
6753
|
}
|
|
6548
6754
|
});
|
|
6549
6755
|
}
|
|
6550
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.
|
|
6551
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.
|
|
6756
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: GroupFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6757
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: GroupFieldComponent, isStandalone: true, selector: "fieldset[group-field]", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { validityChange: "validityChange", dirtyChange: "dirtyChange", submitted: "submitted" }, host: { attributes: { "role": "group" }, properties: { "class.disabled": "disabled()", "id": "`${key()}`", "attr.data-testid": "key()" }, classAttribute: "df-field df-group" }, ngImport: i0, template: `
|
|
6552
6758
|
@for (field of resolvedFields(); track field.key) {
|
|
6553
6759
|
<ng-container *ngComponentOutlet="field.component; injector: field.injector; inputs: field.inputs()" />
|
|
6554
6760
|
}
|
|
6555
6761
|
`, isInline: true, styles: [":host,.df-form{--df-grid-columns: 12;--df-grid-gap: .5rem;--df-grid-row-gap: .5rem;--df-breakpoint-sm: 576px;--df-breakpoint-md: 768px;--df-breakpoint-lg: 992px;--df-breakpoint-xl: 1200px;--df-grid-gap-sm: .5rem;--df-grid-gap-md: .5rem;--df-grid-gap-lg: .5rem;--df-grid-gap-xl: .5rem;--df-grid-row-gap-sm: .5rem;--df-grid-row-gap-md: .5rem;--df-grid-row-gap-lg: .5rem;--df-grid-row-gap-xl: .5rem;--df-group-gap: var(--df-grid-gap);--df-group-padding: var(--df-grid-gap)}.df-form{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap);width:100%}.df-form>*{grid-column:1/-1}.df-row{display:grid;grid-template-columns:repeat(var(--df-grid-columns, 12),1fr);gap:var(--df-grid-gap);align-items:start;width:100%}.df-row>*:not([class*=df-col-]){grid-column:1/-1}.df-col-1{grid-column:span 1}.df-col-2{grid-column:span 2}.df-col-3{grid-column:span 3}.df-col-4{grid-column:span 4}.df-col-5{grid-column:span 5}.df-col-6{grid-column:span 6}.df-col-7{grid-column:span 7}.df-col-8{grid-column:span 8}.df-col-9{grid-column:span 9}.df-col-10{grid-column:span 10}.df-col-11{grid-column:span 11}.df-col-12{grid-column:span 12}.df-col-auto{grid-column:span auto;width:auto}.df-col-full{grid-column:1/-1}.df-col-start-1{grid-column-start:1}.df-col-start-2{grid-column-start:2}.df-col-start-3{grid-column-start:3}.df-col-start-4{grid-column-start:4}.df-col-start-5{grid-column-start:5}.df-col-start-6{grid-column-start:6}.df-col-start-7{grid-column-start:7}.df-col-start-8{grid-column-start:8}.df-col-start-9{grid-column-start:9}.df-col-start-10{grid-column-start:10}.df-col-start-11{grid-column-start:11}.df-col-start-12{grid-column-start:12}.df-col-end-1{grid-column-end:1}.df-col-end-2{grid-column-end:2}.df-col-end-3{grid-column-end:3}.df-col-end-4{grid-column-end:4}.df-col-end-5{grid-column-end:5}.df-col-end-6{grid-column-end:6}.df-col-end-7{grid-column-end:7}.df-col-end-8{grid-column-end:8}.df-col-end-9{grid-column-end:9}.df-col-end-10{grid-column-end:10}.df-col-end-11{grid-column-end:11}.df-col-end-12{grid-column-end:12}.df-col-end-13{grid-column-end:13}@media(max-width:576px){.df-form{--df-grid-gap: var(--df-grid-gap-sm);--df-grid-row-gap: var(--df-grid-row-gap-sm)}.df-row{grid-template-columns:1fr}.df-row>*{grid-column:1/-1!important}.df-row.df-row-mobile-keep-cols{grid-template-columns:repeat(var(--df-grid-columns),1fr)}.df-row.df-row-mobile-keep-cols>*{grid-column:revert!important}}@media(min-width:577px)and (max-width:768px){.df-form{--df-grid-gap: var(--df-grid-gap-md);--df-grid-row-gap: var(--df-grid-row-gap-md)}.df-row{--df-grid-columns: 6}.df-col-sm-1{grid-column:span 1}.df-col-sm-2{grid-column:span 2}.df-col-sm-3{grid-column:span 3}.df-col-sm-4{grid-column:span 4}.df-col-sm-5{grid-column:span 5}.df-col-sm-6{grid-column:span 6}.df-col-sm-full{grid-column:1/-1}}@media(min-width:769px)and (max-width:992px){.df-form{--df-grid-gap: var(--df-grid-gap-lg);--df-grid-row-gap: var(--df-grid-row-gap-lg)}.df-col-md-1{grid-column:span 1}.df-col-md-2{grid-column:span 2}.df-col-md-3{grid-column:span 3}.df-col-md-4{grid-column:span 4}.df-col-md-5{grid-column:span 5}.df-col-md-6{grid-column:span 6}.df-col-md-7{grid-column:span 7}.df-col-md-8{grid-column:span 8}.df-col-md-9{grid-column:span 9}.df-col-md-10{grid-column:span 10}.df-col-md-11{grid-column:span 11}.df-col-md-12{grid-column:span 12}.df-col-md-full{grid-column:1/-1}}@media(min-width:993px){.df-form{--df-grid-gap: var(--df-grid-gap-xl);--df-grid-row-gap: var(--df-grid-row-gap-xl)}.df-col-lg-1{grid-column:span 1}.df-col-lg-2{grid-column:span 2}.df-col-lg-3{grid-column:span 3}.df-col-lg-4{grid-column:span 4}.df-col-lg-5{grid-column:span 5}.df-col-lg-6{grid-column:span 6}.df-col-lg-7{grid-column:span 7}.df-col-lg-8{grid-column:span 8}.df-col-lg-9{grid-column:span 9}.df-col-lg-10{grid-column:span 10}.df-col-lg-11{grid-column:span 11}.df-col-lg-12{grid-column:span 12}.df-col-lg-full{grid-column:1/-1}}.df-gap-none{--df-grid-gap: 0}.df-gap-xs{--df-grid-gap: .25rem}.df-gap-sm{--df-grid-gap: .5rem}.df-gap-md{--df-grid-gap: 1rem}.df-gap-lg{--df-grid-gap: 1.5rem}.df-gap-xl{--df-grid-gap: 2rem}.df-row-gap-none{--df-grid-row-gap: 0}.df-row-gap-xs{--df-grid-row-gap: .25rem}.df-row-gap-sm{--df-grid-row-gap: .5rem}.df-row-gap-md{--df-grid-row-gap: 1rem}.df-row-gap-lg{--df-grid-row-gap: 1.5rem}.df-row-gap-xl{--df-grid-row-gap: 2rem}.df-field{display:block;width:100%;min-width:0;overflow:hidden;margin:0}.df-group,.df-page{display:block;width:100%}.df-form.disabled,.df-row.disabled,.df-field.disabled{opacity:.6;pointer-events:none}.df-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-sr-only-focusable:focus,.df-sr-only-focusable:active{position:static;width:auto;height:auto;padding:inherit;margin:inherit;overflow:visible;clip:auto;white-space:normal}.df-live-region{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-form :focus-visible{outline:2px solid var(--df-focus-color, #005fcc);outline-offset:2px}.df-group:focus-within{outline:1px dashed var(--df-focus-color, #005fcc);outline-offset:4px}:host{border:none;margin:0;padding:0;min-width:0;display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap, .5rem);width:100%}:host>*{grid-column:1/-1}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6556
6762
|
}
|
|
6557
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.
|
|
6763
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: GroupFieldComponent, decorators: [{
|
|
6558
6764
|
type: Component,
|
|
6559
6765
|
args: [{ selector: 'fieldset[group-field]', imports: [NgComponentOutlet], template: `
|
|
6560
6766
|
@for (field of resolvedFields(); track field.key) {
|
|
@@ -6756,6 +6962,10 @@ function resolveArrayItem(options) {
|
|
|
6756
6962
|
if (destroyRef.destroyed) {
|
|
6757
6963
|
return undefined;
|
|
6758
6964
|
}
|
|
6965
|
+
// Componentless fields (e.g., hidden) return undefined - nothing to render
|
|
6966
|
+
if (!component) {
|
|
6967
|
+
return undefined;
|
|
6968
|
+
}
|
|
6759
6969
|
const itemId = generateArrayItemId();
|
|
6760
6970
|
const indexSignal = linkedSignal(() => {
|
|
6761
6971
|
const order = itemOrderSignal();
|
|
@@ -6771,9 +6981,13 @@ function resolveArrayItem(options) {
|
|
|
6771
6981
|
registry,
|
|
6772
6982
|
arrayField,
|
|
6773
6983
|
});
|
|
6984
|
+
// Array item templates should always have inputs (componentless fields are handled above)
|
|
6985
|
+
if (!inputs) {
|
|
6986
|
+
return undefined;
|
|
6987
|
+
}
|
|
6774
6988
|
return {
|
|
6775
6989
|
id: itemId,
|
|
6776
|
-
component
|
|
6990
|
+
component,
|
|
6777
6991
|
injector,
|
|
6778
6992
|
inputs,
|
|
6779
6993
|
};
|
|
@@ -6979,14 +7193,14 @@ class ArrayFieldComponent {
|
|
|
6979
7193
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6980
7194
|
parentForm().value.set({ ...currentValue, [arrayKey]: newArray });
|
|
6981
7195
|
}
|
|
6982
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.
|
|
6983
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.
|
|
7196
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: ArrayFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7197
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: ArrayFieldComponent, isStandalone: true, selector: "array-field", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()" }, classAttribute: "df-field df-array" }, ngImport: i0, template: `
|
|
6984
7198
|
@for (item of resolvedItems(); track item.id) {
|
|
6985
7199
|
<ng-container *ngComponentOutlet="item.component; injector: item.injector; inputs: item.inputs()" />
|
|
6986
7200
|
}
|
|
6987
7201
|
`, isInline: true, styles: [":host,.df-form{--df-grid-columns: 12;--df-grid-gap: .5rem;--df-grid-row-gap: .5rem;--df-breakpoint-sm: 576px;--df-breakpoint-md: 768px;--df-breakpoint-lg: 992px;--df-breakpoint-xl: 1200px;--df-grid-gap-sm: .5rem;--df-grid-gap-md: .5rem;--df-grid-gap-lg: .5rem;--df-grid-gap-xl: .5rem;--df-grid-row-gap-sm: .5rem;--df-grid-row-gap-md: .5rem;--df-grid-row-gap-lg: .5rem;--df-grid-row-gap-xl: .5rem;--df-group-gap: var(--df-grid-gap);--df-group-padding: var(--df-grid-gap)}.df-form{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap);width:100%}.df-form>*{grid-column:1/-1}.df-row{display:grid;grid-template-columns:repeat(var(--df-grid-columns, 12),1fr);gap:var(--df-grid-gap);align-items:start;width:100%}.df-row>*:not([class*=df-col-]){grid-column:1/-1}.df-col-1{grid-column:span 1}.df-col-2{grid-column:span 2}.df-col-3{grid-column:span 3}.df-col-4{grid-column:span 4}.df-col-5{grid-column:span 5}.df-col-6{grid-column:span 6}.df-col-7{grid-column:span 7}.df-col-8{grid-column:span 8}.df-col-9{grid-column:span 9}.df-col-10{grid-column:span 10}.df-col-11{grid-column:span 11}.df-col-12{grid-column:span 12}.df-col-auto{grid-column:span auto;width:auto}.df-col-full{grid-column:1/-1}.df-col-start-1{grid-column-start:1}.df-col-start-2{grid-column-start:2}.df-col-start-3{grid-column-start:3}.df-col-start-4{grid-column-start:4}.df-col-start-5{grid-column-start:5}.df-col-start-6{grid-column-start:6}.df-col-start-7{grid-column-start:7}.df-col-start-8{grid-column-start:8}.df-col-start-9{grid-column-start:9}.df-col-start-10{grid-column-start:10}.df-col-start-11{grid-column-start:11}.df-col-start-12{grid-column-start:12}.df-col-end-1{grid-column-end:1}.df-col-end-2{grid-column-end:2}.df-col-end-3{grid-column-end:3}.df-col-end-4{grid-column-end:4}.df-col-end-5{grid-column-end:5}.df-col-end-6{grid-column-end:6}.df-col-end-7{grid-column-end:7}.df-col-end-8{grid-column-end:8}.df-col-end-9{grid-column-end:9}.df-col-end-10{grid-column-end:10}.df-col-end-11{grid-column-end:11}.df-col-end-12{grid-column-end:12}.df-col-end-13{grid-column-end:13}@media(max-width:576px){.df-form{--df-grid-gap: var(--df-grid-gap-sm);--df-grid-row-gap: var(--df-grid-row-gap-sm)}.df-row{grid-template-columns:1fr}.df-row>*{grid-column:1/-1!important}.df-row.df-row-mobile-keep-cols{grid-template-columns:repeat(var(--df-grid-columns),1fr)}.df-row.df-row-mobile-keep-cols>*{grid-column:revert!important}}@media(min-width:577px)and (max-width:768px){.df-form{--df-grid-gap: var(--df-grid-gap-md);--df-grid-row-gap: var(--df-grid-row-gap-md)}.df-row{--df-grid-columns: 6}.df-col-sm-1{grid-column:span 1}.df-col-sm-2{grid-column:span 2}.df-col-sm-3{grid-column:span 3}.df-col-sm-4{grid-column:span 4}.df-col-sm-5{grid-column:span 5}.df-col-sm-6{grid-column:span 6}.df-col-sm-full{grid-column:1/-1}}@media(min-width:769px)and (max-width:992px){.df-form{--df-grid-gap: var(--df-grid-gap-lg);--df-grid-row-gap: var(--df-grid-row-gap-lg)}.df-col-md-1{grid-column:span 1}.df-col-md-2{grid-column:span 2}.df-col-md-3{grid-column:span 3}.df-col-md-4{grid-column:span 4}.df-col-md-5{grid-column:span 5}.df-col-md-6{grid-column:span 6}.df-col-md-7{grid-column:span 7}.df-col-md-8{grid-column:span 8}.df-col-md-9{grid-column:span 9}.df-col-md-10{grid-column:span 10}.df-col-md-11{grid-column:span 11}.df-col-md-12{grid-column:span 12}.df-col-md-full{grid-column:1/-1}}@media(min-width:993px){.df-form{--df-grid-gap: var(--df-grid-gap-xl);--df-grid-row-gap: var(--df-grid-row-gap-xl)}.df-col-lg-1{grid-column:span 1}.df-col-lg-2{grid-column:span 2}.df-col-lg-3{grid-column:span 3}.df-col-lg-4{grid-column:span 4}.df-col-lg-5{grid-column:span 5}.df-col-lg-6{grid-column:span 6}.df-col-lg-7{grid-column:span 7}.df-col-lg-8{grid-column:span 8}.df-col-lg-9{grid-column:span 9}.df-col-lg-10{grid-column:span 10}.df-col-lg-11{grid-column:span 11}.df-col-lg-12{grid-column:span 12}.df-col-lg-full{grid-column:1/-1}}.df-gap-none{--df-grid-gap: 0}.df-gap-xs{--df-grid-gap: .25rem}.df-gap-sm{--df-grid-gap: .5rem}.df-gap-md{--df-grid-gap: 1rem}.df-gap-lg{--df-grid-gap: 1.5rem}.df-gap-xl{--df-grid-gap: 2rem}.df-row-gap-none{--df-grid-row-gap: 0}.df-row-gap-xs{--df-grid-row-gap: .25rem}.df-row-gap-sm{--df-grid-row-gap: .5rem}.df-row-gap-md{--df-grid-row-gap: 1rem}.df-row-gap-lg{--df-grid-row-gap: 1.5rem}.df-row-gap-xl{--df-grid-row-gap: 2rem}.df-field{display:block;width:100%;min-width:0;overflow:hidden;margin:0}.df-group,.df-page{display:block;width:100%}.df-form.disabled,.df-row.disabled,.df-field.disabled{opacity:.6;pointer-events:none}.df-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-sr-only-focusable:focus,.df-sr-only-focusable:active{position:static;width:auto;height:auto;padding:inherit;margin:inherit;overflow:visible;clip:auto;white-space:normal}.df-live-region{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-form :focus-visible{outline:2px solid var(--df-focus-color, #005fcc);outline-offset:2px}.df-group:focus-within{outline:1px dashed var(--df-focus-color, #005fcc);outline-offset:4px}:host{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap, .5rem);width:100%}:host>*{grid-column:1/-1}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6988
7202
|
}
|
|
6989
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.
|
|
7203
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: ArrayFieldComponent, decorators: [{
|
|
6990
7204
|
type: Component,
|
|
6991
7205
|
args: [{ selector: 'array-field', imports: [NgComponentOutlet], template: `
|
|
6992
7206
|
@for (item of resolvedItems(); track item.id) {
|
|
@@ -7082,16 +7296,31 @@ function extractErrorParams(error) {
|
|
|
7082
7296
|
params.min = error.min;
|
|
7083
7297
|
if ('max' in error)
|
|
7084
7298
|
params.max = error.max;
|
|
7085
|
-
if ('requiredLength' in error)
|
|
7086
|
-
params.requiredLength = error.requiredLength;
|
|
7087
|
-
if ('actualLength' in error)
|
|
7088
|
-
params.actualLength = error.actualLength;
|
|
7089
7299
|
if ('pattern' in error)
|
|
7090
7300
|
params.pattern = error.pattern;
|
|
7091
7301
|
if ('actual' in error)
|
|
7092
7302
|
params.actual = error.actual;
|
|
7093
7303
|
if ('expected' in error)
|
|
7094
7304
|
params.expected = error.expected;
|
|
7305
|
+
// Handle length validation parameters
|
|
7306
|
+
// Angular Signal Forms uses 'minLength'/'maxLength' properties
|
|
7307
|
+
// Angular Classic Forms uses 'requiredLength'/'actualLength' properties
|
|
7308
|
+
// We support both formats and normalize to 'requiredLength' for message templates
|
|
7309
|
+
if ('requiredLength' in error) {
|
|
7310
|
+
params.requiredLength = error.requiredLength;
|
|
7311
|
+
}
|
|
7312
|
+
else if ('minLength' in error) {
|
|
7313
|
+
// Angular Signal Forms: minLength property maps to requiredLength for templates
|
|
7314
|
+
params.requiredLength = error.minLength;
|
|
7315
|
+
params.minLength = error.minLength;
|
|
7316
|
+
}
|
|
7317
|
+
else if ('maxLength' in error) {
|
|
7318
|
+
// Angular Signal Forms: maxLength property maps to requiredLength for templates
|
|
7319
|
+
params.requiredLength = error.maxLength;
|
|
7320
|
+
params.maxLength = error.maxLength;
|
|
7321
|
+
}
|
|
7322
|
+
if ('actualLength' in error)
|
|
7323
|
+
params.actualLength = error.actualLength;
|
|
7095
7324
|
// Include all custom properties from error object (for custom validators)
|
|
7096
7325
|
// Skip 'kind' as it's the error type identifier, not a parameter
|
|
7097
7326
|
Object.keys(error).forEach((key) => {
|
|
@@ -7133,5 +7362,5 @@ function extractErrorParams(error) {
|
|
|
7133
7362
|
* Generated bundle index. Do not edit.
|
|
7134
7363
|
*/
|
|
7135
7364
|
|
|
7136
|
-
export { BUILT_IN_FIELDS as $, AddArrayItemEvent as A, baseFieldMapper as B, ConsoleLogger as C, DynamicFormLogger as D, EventBus as E, FormClearEvent as F, buildBaseInputs as G, arrayFieldMapper as H, groupFieldMapper as I, pageFieldMapper as J, rowFieldMapper as K, textFieldMapper as L, FIELD_REGISTRY as M, NoopLogger as N, ARRAY_CONTEXT as O, PageChangeEvent as P, FIELD_SIGNAL_CONTEXT as Q, RemoveArrayItemEvent as R, SubmitEvent as S, dynamicTextToObservable as T, ArrayFieldComponent as U, GroupFieldComponent as V, RowFieldComponent as W, applyValidator as X, applyValidators as Y, getArrayLength as Z, resolveTokens as _, DynamicTextPipe as a, omit as a0, interpolateParams as a1, DynamicForm as b, createFieldResolutionPipe as c, derivedFromDeferred as d, emitComponentInitialized as e, isFormStateCondition as f, resolveNextButtonDisabled as g, isCheckedField as h, injectFieldRegistry as i, isValueField as j, isRowField as k, isArrayField as l, isContainerField as m, isDisplayOnlyField as n, isGroupField as o, provideDynamicForm as p, isLeafField as q, resolveSubmitButtonDisabled as r, isPageField as s, isValueBearingField as t, FormResetEvent as u, validatePageNesting as v, withLoggerConfig as w, NextPageEvent as x, PreviousPageEvent as y, DynamicFormError as z };
|
|
7137
|
-
//# sourceMappingURL=ng-forge-dynamic-forms-ng-forge-dynamic-forms-
|
|
7365
|
+
export { BUILT_IN_FIELDS as $, AddArrayItemEvent as A, baseFieldMapper as B, ConsoleLogger as C, DynamicFormLogger as D, EventBus as E, FormClearEvent as F, buildBaseInputs as G, arrayFieldMapper as H, groupFieldMapper as I, pageFieldMapper as J, rowFieldMapper as K, textFieldMapper as L, FIELD_REGISTRY as M, NoopLogger as N, ARRAY_CONTEXT as O, PageChangeEvent as P, FIELD_SIGNAL_CONTEXT as Q, RemoveArrayItemEvent as R, SubmitEvent as S, dynamicTextToObservable as T, ArrayFieldComponent as U, GroupFieldComponent as V, RowFieldComponent as W, applyValidator as X, applyValidators as Y, getArrayLength as Z, resolveTokens as _, DynamicTextPipe as a, omit as a0, interpolateParams as a1, applyMetaToElement as a2, DynamicForm as b, createFieldResolutionPipe as c, derivedFromDeferred as d, emitComponentInitialized as e, isFormStateCondition as f, resolveNextButtonDisabled as g, isCheckedField as h, injectFieldRegistry as i, isValueField as j, isRowField as k, isArrayField as l, isContainerField as m, isDisplayOnlyField as n, isGroupField as o, provideDynamicForm as p, isLeafField as q, resolveSubmitButtonDisabled as r, isPageField as s, isValueBearingField as t, FormResetEvent as u, validatePageNesting as v, withLoggerConfig as w, NextPageEvent as x, PreviousPageEvent as y, DynamicFormError as z };
|
|
7366
|
+
//# sourceMappingURL=ng-forge-dynamic-forms-ng-forge-dynamic-forms-CMSmISSp.mjs.map
|