@ng-forge/dynamic-forms 0.9.0-next.9 → 0.9.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 +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-array-field.component-us7mQtVQ.mjs → ng-forge-dynamic-forms-array-field.component-Tw49K5kz.mjs} +171 -73
- package/fesm2022/ng-forge-dynamic-forms-array-field.component-Tw49K5kz.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-container-field.component-BCIQ6_Mm.mjs → ng-forge-dynamic-forms-container-field.component-CrOIZEL_.mjs} +12 -8
- package/fesm2022/ng-forge-dynamic-forms-container-field.component-CrOIZEL_.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-container-utils-CzZlFNA0.mjs → ng-forge-dynamic-forms-container-utils-Bx1A5tg-.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-container-utils-CzZlFNA0.mjs.map → ng-forge-dynamic-forms-container-utils-Bx1A5tg-.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-css-wrapper.component-Dhlf6UxN.mjs → ng-forge-dynamic-forms-css-wrapper.component-Q2g56KUM.mjs} +5 -5
- package/fesm2022/ng-forge-dynamic-forms-css-wrapper.component-Q2g56KUM.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-emit-initialization-DqQ8BA4W.mjs → ng-forge-dynamic-forms-emit-initialization-9l5gPNQc.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-emit-initialization-DqQ8BA4W.mjs.map → ng-forge-dynamic-forms-emit-initialization-9l5gPNQc.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-group-field.component-DKcoco0G.mjs → ng-forge-dynamic-forms-group-field.component-DqnhddRH.mjs} +36 -12
- package/fesm2022/ng-forge-dynamic-forms-group-field.component-DqnhddRH.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs +936 -54
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs.map +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-ng-forge-dynamic-forms-CfbmSRM_.mjs → ng-forge-dynamic-forms-ng-forge-dynamic-forms-Be1Lk0qR.mjs} +2230 -445
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-Be1Lk0qR.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms-page-field.component-n4KTMOTm.mjs +114 -0
- package/fesm2022/ng-forge-dynamic-forms-page-field.component-n4KTMOTm.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms-row-wrapper.component-CFtnatYj.mjs +34 -0
- package/fesm2022/ng-forge-dynamic-forms-row-wrapper.component-CFtnatYj.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-text-field.component-8C1-oyU_.mjs → ng-forge-dynamic-forms-text-field.component-C14mlROS.mjs} +5 -5
- package/fesm2022/{ng-forge-dynamic-forms-text-field.component-8C1-oyU_.mjs.map → ng-forge-dynamic-forms-text-field.component-C14mlROS.mjs.map} +1 -1
- package/fesm2022/ng-forge-dynamic-forms.mjs +1 -1
- package/package.json +2 -2
- package/types/ng-forge-dynamic-forms-integration.d.ts +587 -11
- package/types/ng-forge-dynamic-forms.d.ts +3841 -2428
- package/fesm2022/ng-forge-dynamic-forms-array-field.component-us7mQtVQ.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-container-field.component-BCIQ6_Mm.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-css-wrapper.component-Dhlf6UxN.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-group-field.component-DKcoco0G.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-CfbmSRM_.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-page-field.component-DqWAcwhG.mjs +0 -110
- package/fesm2022/ng-forge-dynamic-forms-page-field.component-DqWAcwhG.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-row-wrapper.component-BIvEUoia.mjs +0 -34
- package/fesm2022/ng-forge-dynamic-forms-row-wrapper.component-BIvEUoia.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@ Core library for building type-safe, dynamic Angular forms with signal forms int
|
|
|
20
20
|
|
|
21
21
|
| @ng-forge/dynamic-forms | Angular |
|
|
22
22
|
| ----------------------- | ------------- |
|
|
23
|
+
| 0.9.x | >=21.2.0 |
|
|
23
24
|
| 0.8.x | >=21.2.0 |
|
|
24
25
|
| 0.7.x | >=21.2.0 |
|
|
25
26
|
| 0.6.x | >=21.1.0 |
|
|
@@ -1,10 +1,62 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { computed, runInInjectionContext, Injector, linkedSignal, inject, DestroyRef, EnvironmentInjector, input,
|
|
3
|
-
import {
|
|
2
|
+
import { signal, computed, runInInjectionContext, Injector, linkedSignal, inject, DestroyRef, EnvironmentInjector, input, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { O as RootFormRegistryService, ax as isEqual, aL as mapFieldToInputs, v as FIELD_SIGNAL_CONTEXT, e as ARRAY_CONTEXT, G as GROUP_CONTEXT, a5 as createHiddenSignal, a6 as createRenderReadySignal, s as DynamicFormLogger, ao as injectFieldRegistry, ap as injectFieldSignalContext, E as EventBus, g as ArrayItemRegistryService, ak as getNormalizedArrayMetadata, aj as getFieldValueHandling, ai as getFieldDefaultValue, aA as isGroupField, o as DfFieldOutlet } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms-Be1Lk0qR.mjs';
|
|
4
4
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
5
|
import { of, from, map, catchError, forkJoin, filter, firstValueFrom, tap } from 'rxjs';
|
|
6
6
|
import { explicitEffect } from 'ngxtension/explicit-effect';
|
|
7
|
-
import { e as emitComponentInitialized } from './ng-forge-dynamic-forms-emit-initialization-
|
|
7
|
+
import { e as emitComponentInitialized } from './ng-forge-dynamic-forms-emit-initialization-9l5gPNQc.mjs';
|
|
8
|
+
|
|
9
|
+
class ArrayFieldStateMachine {
|
|
10
|
+
_state = signal('idle', ...(ngDevMode ? [{ debugName: "_state" }] : /* istanbul ignore next */ []));
|
|
11
|
+
_runId = signal(0, ...(ngDevMode ? [{ debugName: "_runId" }] : /* istanbul ignore next */ []));
|
|
12
|
+
lastEmittedRunId = -1;
|
|
13
|
+
_hasEverEmitted = false;
|
|
14
|
+
state = this._state.asReadonly();
|
|
15
|
+
runId = this._runId.asReadonly();
|
|
16
|
+
/** True after the first `componentInitialized` pulse has fired for this component. */
|
|
17
|
+
get hasEverEmitted() {
|
|
18
|
+
return this._hasEverEmitted;
|
|
19
|
+
}
|
|
20
|
+
dispatch(op) {
|
|
21
|
+
const nextId = this._runId() + 1;
|
|
22
|
+
this._runId.set(nextId);
|
|
23
|
+
switch (op.kind) {
|
|
24
|
+
case 'clear':
|
|
25
|
+
case 'initial':
|
|
26
|
+
case 'recreate':
|
|
27
|
+
this._state.set('pending');
|
|
28
|
+
break;
|
|
29
|
+
case 'append':
|
|
30
|
+
// append doesn't reset state — mirrors today's behavior where
|
|
31
|
+
// appendItems leaves the init-cycle tracking alone.
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
id: nextId,
|
|
36
|
+
isStale: () => this._runId() !== nextId,
|
|
37
|
+
resolve: () => {
|
|
38
|
+
if (this._runId() === nextId && this._state() === 'pending') {
|
|
39
|
+
this._state.set('settled');
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Edge-trigger for the emit-effect. Returns true exactly once per `settled` run
|
|
46
|
+
* when `allReady` is true. Side-effect: records the run as emitted and transitions
|
|
47
|
+
* the state back to `idle`. Subsequent calls without a fresh dispatch return false.
|
|
48
|
+
*/
|
|
49
|
+
shouldEmit(allReady) {
|
|
50
|
+
if (this._state() !== 'settled' || !allReady)
|
|
51
|
+
return false;
|
|
52
|
+
if (this.lastEmittedRunId === this._runId())
|
|
53
|
+
return false;
|
|
54
|
+
this.lastEmittedRunId = this._runId();
|
|
55
|
+
this._hasEverEmitted = true;
|
|
56
|
+
this._state.set('idle');
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
8
60
|
|
|
9
61
|
/**
|
|
10
62
|
* Safely extracts an array value from a model object.
|
|
@@ -173,9 +225,22 @@ function createItemInjector(options) {
|
|
|
173
225
|
deps: [Injector],
|
|
174
226
|
},
|
|
175
227
|
{ provide: ARRAY_CONTEXT, useValue: arrayContext },
|
|
228
|
+
// Reset GROUP_CONTEXT at the array boundary: inner groups inside each
|
|
229
|
+
// item start their path fresh, matching how value-derivation and
|
|
230
|
+
// property-derivation collectors key entries
|
|
231
|
+
// (`{arrayKey}.$.{innerGroupPath}.{fieldKey}`). Without this, an outer
|
|
232
|
+
// group around the array would leak into descendants' DOM IDs and
|
|
233
|
+
// override-store keys, drifting from the collector.
|
|
234
|
+
{ provide: GROUP_CONTEXT, useValue: EMPTY_GROUP_CONTEXT },
|
|
176
235
|
],
|
|
177
236
|
});
|
|
178
237
|
}
|
|
238
|
+
/**
|
|
239
|
+
* Sentinel `GroupContext` provided at array item boundaries. Static `signal('')`
|
|
240
|
+
* means `applyGroupPrefix` no-ops (empty path) and any inner group composes its
|
|
241
|
+
* own path from this empty base.
|
|
242
|
+
*/
|
|
243
|
+
const EMPTY_GROUP_CONTEXT = { groupPath: signal('') };
|
|
179
244
|
|
|
180
245
|
/**
|
|
181
246
|
* Resolves a single array item with all its fields for declarative rendering.
|
|
@@ -185,12 +250,14 @@ function createItemInjector(options) {
|
|
|
185
250
|
* Supports multiple sibling templates (e.g., name + email without a wrapper).
|
|
186
251
|
*/
|
|
187
252
|
function resolveArrayItem(options) {
|
|
188
|
-
const { index, templates, arrayField, itemPositionMap, parentFieldSignalContext, parentInjector, registry, destroyRef, loadTypeComponent, generateItemId, primitiveFieldKey, } = options;
|
|
253
|
+
const { index, templates, arrayField, itemPositionMap, parentFieldSignalContext, parentInjector, registry, destroyRef, loadTypeComponent, generateItemId, existingItemId, primitiveFieldKey, } = options;
|
|
189
254
|
if (templates.length === 0) {
|
|
190
255
|
return of(undefined);
|
|
191
256
|
}
|
|
192
|
-
// Generate ONE id for this array item (shared by all fields for tracking)
|
|
193
|
-
|
|
257
|
+
// Generate ONE id for this array item (shared by all fields for tracking), unless
|
|
258
|
+
// the caller is rehydrating an existing item — in which case reuse its id so the
|
|
259
|
+
// form-scoped template registry continues to map cleanly.
|
|
260
|
+
const itemId = existingItemId ?? generateItemId();
|
|
194
261
|
// O(1) position lookup via Map instead of O(n) indexOf()
|
|
195
262
|
const indexSignal = linkedSignal(() => {
|
|
196
263
|
const positionMap = itemPositionMap();
|
|
@@ -225,6 +292,7 @@ function resolveArrayItem(options) {
|
|
|
225
292
|
injector,
|
|
226
293
|
inputs,
|
|
227
294
|
renderReady: createRenderReadySignal(inputs, registry.get(template.type)),
|
|
295
|
+
hidden: createHiddenSignal(inputs),
|
|
228
296
|
};
|
|
229
297
|
}), catchError((error) => {
|
|
230
298
|
if (!destroyRef.destroyed) {
|
|
@@ -319,13 +387,21 @@ class ArrayFieldComponent {
|
|
|
319
387
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
320
388
|
destroyRef = inject(DestroyRef);
|
|
321
389
|
fieldRegistry = injectFieldRegistry();
|
|
322
|
-
parentFieldSignalContext =
|
|
390
|
+
parentFieldSignalContext = injectFieldSignalContext();
|
|
323
391
|
parentInjector = inject(Injector);
|
|
324
392
|
environmentInjector = inject(EnvironmentInjector);
|
|
325
393
|
eventBus = inject(EventBus);
|
|
326
394
|
logger = inject(DynamicFormLogger);
|
|
327
|
-
|
|
328
|
-
|
|
395
|
+
arrayItemRegistry = inject(ArrayItemRegistryService);
|
|
396
|
+
// Form-scoped slot keyed by the array's path. Survives this component's lifecycle so that
|
|
397
|
+
// `@if`-gated arrays can be destroyed and recreated without losing dynamically-added items.
|
|
398
|
+
// NOTE: keyed by `field().key` for now — nested arrays with the same key in different scopes
|
|
399
|
+
// would currently collide. Today's per-component-provider model has the same constraint
|
|
400
|
+
// (no nested-array hide/show tests exist). Path-aware keying is a follow-up.
|
|
401
|
+
// `field()` is `input.required`, so the slot reference is resolved lazily.
|
|
402
|
+
slot = computed(() => this.arrayItemRegistry.slotFor(this.field().key), ...(ngDevMode ? [{ debugName: "slot" }] : /* istanbul ignore next */ []));
|
|
403
|
+
/** Bound id-generator reference threaded to `resolveArrayItem` so callsites stay terse. */
|
|
404
|
+
generateItemId = () => this.slot().nextId();
|
|
329
405
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
330
406
|
// Inputs
|
|
331
407
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -453,9 +529,9 @@ class ArrayFieldComponent {
|
|
|
453
529
|
// State Signals
|
|
454
530
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
455
531
|
resolvedItemsSignal = signal([], ...(ngDevMode ? [{ debugName: "resolvedItemsSignal" }] : /* istanbul ignore next */ []));
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
532
|
+
// Explicit state machine for async resolution + componentInitialized emission.
|
|
533
|
+
// Replaces the prior updateVersion + pendingInitializationCycle + settledInitializationCycle trio.
|
|
534
|
+
fsm = new ArrayFieldStateMachine();
|
|
459
535
|
/**
|
|
460
536
|
* Map of item IDs to their current positions. O(1) lookup vs O(n) indexOf().
|
|
461
537
|
* Used by child linkedSignals to reactively track their position in the array.
|
|
@@ -505,10 +581,9 @@ class ArrayFieldComponent {
|
|
|
505
581
|
explicitEffect([this.arrayFieldTrees], ([fieldTrees]) => {
|
|
506
582
|
this.performDifferentialUpdate(fieldTrees);
|
|
507
583
|
});
|
|
508
|
-
explicitEffect([this.
|
|
509
|
-
if (
|
|
584
|
+
explicitEffect([this.fsm.state, this.allResolvedFieldsRenderReady], ([, allReady]) => {
|
|
585
|
+
if (this.fsm.shouldEmit(allReady)) {
|
|
510
586
|
emitComponentInitialized(this.eventBus, 'array', this.field().key, this.parentInjector);
|
|
511
|
-
this.pendingInitializationCycle.set(null);
|
|
512
587
|
}
|
|
513
588
|
});
|
|
514
589
|
}
|
|
@@ -594,9 +669,9 @@ class ArrayFieldComponent {
|
|
|
594
669
|
}
|
|
595
670
|
}
|
|
596
671
|
}
|
|
597
|
-
//
|
|
598
|
-
|
|
599
|
-
const
|
|
672
|
+
// Dispatch an append run — bumps runId so any in-flight differential update
|
|
673
|
+
// becomes stale, but state stays in its current phase.
|
|
674
|
+
const run = this.fsm.dispatch({ kind: 'append' });
|
|
600
675
|
// Append auto-remove button to resolution templates (for rendering only)
|
|
601
676
|
const resolveTemplates = this.withAutoRemove(templates);
|
|
602
677
|
// Resolve the new item
|
|
@@ -616,11 +691,13 @@ class ArrayFieldComponent {
|
|
|
616
691
|
this.logger.error(`Failed to resolve array item at index ${insertIndex}:`, error);
|
|
617
692
|
return of(undefined);
|
|
618
693
|
})));
|
|
619
|
-
if (
|
|
694
|
+
if (run.isStale() || !resolvedItem) {
|
|
620
695
|
return;
|
|
621
696
|
}
|
|
622
697
|
// Store the template used for this item so it can be re-used during recreate operations
|
|
623
|
-
this.
|
|
698
|
+
this.slot().templates.set(resolvedItem.id, templates);
|
|
699
|
+
// Mirror the insert into slot.itemOrder so survival across hide/show stays consistent.
|
|
700
|
+
this.slot().itemOrder.splice(insertIndex, 0, resolvedItem.id);
|
|
624
701
|
// Insert resolved item at correct position
|
|
625
702
|
this.resolvedItemsSignal.update((current) => {
|
|
626
703
|
const newItems = [...current];
|
|
@@ -638,31 +715,43 @@ class ArrayFieldComponent {
|
|
|
638
715
|
performDifferentialUpdate(fieldTrees) {
|
|
639
716
|
const resolvedItems = this.resolvedItemsSignal();
|
|
640
717
|
const operation = determineDifferentialOperation(resolvedItems, fieldTrees.length);
|
|
641
|
-
//
|
|
642
|
-
//
|
|
718
|
+
// "none" operations (value-only changes) don't kick the state machine — they shouldn't
|
|
719
|
+
// interfere with in-flight async resolutions.
|
|
643
720
|
if (operation.type === 'none') {
|
|
644
721
|
return;
|
|
645
722
|
}
|
|
646
|
-
this.updateVersion.update((v) => v + 1);
|
|
647
|
-
const currentVersion = this.updateVersion();
|
|
648
723
|
switch (operation.type) {
|
|
649
|
-
case 'clear':
|
|
724
|
+
case 'clear': {
|
|
650
725
|
// Clean up template registry when all items are removed
|
|
651
|
-
this.
|
|
726
|
+
this.slot().templates.clear();
|
|
652
727
|
this.resolvedItemsSignal.set([]);
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
728
|
+
const run = this.fsm.dispatch({ kind: 'clear' });
|
|
729
|
+
// First-ever clear with no items: synthesize a resolve so the emit-effect fires
|
|
730
|
+
// the init pulse (matches the form-starts-empty case from the prior implementation).
|
|
731
|
+
if (resolvedItems.length === 0 && !this.fsm.hasEverEmitted) {
|
|
732
|
+
run.resolve();
|
|
656
733
|
}
|
|
657
734
|
break;
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
735
|
+
}
|
|
736
|
+
case 'initial': {
|
|
737
|
+
// If the slot has surviving state from a prior ArrayFieldComponent instance (same
|
|
738
|
+
// form, same array path, just a different render cycle — e.g. an `@if`-gated array
|
|
739
|
+
// that was hidden then re-shown), reuse the stored templates AND ids so dynamically-
|
|
740
|
+
// added items rebuild correctly. When the slot is empty this collapses to a normal
|
|
741
|
+
// initial resolve via Priority 2/3.
|
|
742
|
+
const slot = this.slot();
|
|
743
|
+
const useSurvival = slot.itemOrder.length === fieldTrees.length && fieldTrees.length > 0;
|
|
744
|
+
const positionalTemplates = useSurvival ? slot.itemOrder.map((id) => slot.templates.get(id)) : undefined;
|
|
745
|
+
const existingItemIds = useSurvival ? slot.itemOrder.slice() : undefined;
|
|
746
|
+
const run = this.fsm.dispatch({ kind: 'initial' });
|
|
747
|
+
void this.resolveAllItems(fieldTrees, run, positionalTemplates, existingItemIds);
|
|
662
748
|
break;
|
|
663
|
-
|
|
664
|
-
|
|
749
|
+
}
|
|
750
|
+
case 'append': {
|
|
751
|
+
const run = this.fsm.dispatch({ kind: 'append' });
|
|
752
|
+
void this.appendItems(fieldTrees, operation.startIndex, operation.endIndex, run);
|
|
665
753
|
break;
|
|
754
|
+
}
|
|
666
755
|
case 'recreate': {
|
|
667
756
|
// Capture templates by item ID so each item is recreated with its original template,
|
|
668
757
|
// even after move operations that change positions. Registry entries (from dynamic adds
|
|
@@ -670,49 +759,53 @@ class ArrayFieldComponent {
|
|
|
670
759
|
const positionalTemplates = resolvedItems.map((item) => {
|
|
671
760
|
// Registry entries (from dynamic adds or moves) take priority;
|
|
672
761
|
// unmoved initial items return undefined → falls through to itemTemplates[idx] during resolve.
|
|
673
|
-
return this.
|
|
762
|
+
return this.slot().templates.get(item.id);
|
|
674
763
|
});
|
|
675
764
|
this.resolvedItemsSignal.set([]);
|
|
676
|
-
this.
|
|
677
|
-
this.
|
|
678
|
-
void this.resolveAllItems(fieldTrees, currentVersion, positionalTemplates);
|
|
765
|
+
const run = this.fsm.dispatch({ kind: 'recreate' });
|
|
766
|
+
void this.resolveAllItems(fieldTrees, run, positionalTemplates);
|
|
679
767
|
break;
|
|
680
768
|
}
|
|
681
769
|
}
|
|
682
770
|
}
|
|
683
|
-
async resolveAllItems(fieldTrees,
|
|
771
|
+
async resolveAllItems(fieldTrees, run, positionalTemplates, existingItemIds) {
|
|
684
772
|
if (fieldTrees.length === 0) {
|
|
685
773
|
this.resolvedItemsSignal.set([]);
|
|
686
774
|
return;
|
|
687
775
|
}
|
|
688
776
|
// Wrap each item observable to catch individual errors
|
|
689
|
-
const safeItemObservables = fieldTrees.map((_, i) => this.createResolveItemObservable(i, positionalTemplates?.[i]).pipe(catchError((error) => {
|
|
777
|
+
const safeItemObservables = fieldTrees.map((_, i) => this.createResolveItemObservable(i, positionalTemplates?.[i], existingItemIds?.[i]).pipe(catchError((error) => {
|
|
690
778
|
this.logger.error(`Failed to resolve array item at index ${i}:`, error);
|
|
691
779
|
return of(undefined);
|
|
692
780
|
})));
|
|
693
781
|
try {
|
|
694
782
|
const items = await firstValueFrom(forkJoin(safeItemObservables).pipe(map((items) => items.filter((item) => item !== undefined))));
|
|
695
|
-
if (
|
|
783
|
+
if (!run.isStale()) {
|
|
696
784
|
// Update template registry with new item IDs for dynamically added items
|
|
697
785
|
if (positionalTemplates) {
|
|
698
786
|
// Clean up old entries and add new ones
|
|
699
787
|
const newItemIds = new Set(items.map((item) => item.id));
|
|
700
|
-
for (const existingId of this.
|
|
788
|
+
for (const existingId of this.slot().templates.keys()) {
|
|
701
789
|
if (!newItemIds.has(existingId)) {
|
|
702
|
-
this.
|
|
790
|
+
this.slot().templates.delete(existingId);
|
|
703
791
|
}
|
|
704
792
|
}
|
|
705
793
|
items.forEach((item, idx) => {
|
|
706
794
|
const template = positionalTemplates[idx];
|
|
707
795
|
if (template) {
|
|
708
|
-
this.
|
|
796
|
+
this.slot().templates.set(item.id, template);
|
|
709
797
|
}
|
|
710
798
|
});
|
|
711
799
|
}
|
|
800
|
+
// Mirror the resolved item ids into the slot's itemOrder so a future component
|
|
801
|
+
// recreate (e.g. after an @if hide cycle) can rehydrate via the survival path.
|
|
802
|
+
const slot = this.slot();
|
|
803
|
+
slot.itemOrder.length = 0;
|
|
804
|
+
for (const item of items)
|
|
805
|
+
slot.itemOrder.push(item.id);
|
|
712
806
|
this.resolvedItemsSignal.set(items);
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
}
|
|
807
|
+
// Mark this run settled so the emit-effect can fire componentInitialized once allReady is true.
|
|
808
|
+
run.resolve();
|
|
716
809
|
}
|
|
717
810
|
}
|
|
718
811
|
catch (err) {
|
|
@@ -720,7 +813,7 @@ class ArrayFieldComponent {
|
|
|
720
813
|
this.resolvedItemsSignal.set([]);
|
|
721
814
|
}
|
|
722
815
|
}
|
|
723
|
-
async appendItems(fieldTrees, startIndex, endIndex,
|
|
816
|
+
async appendItems(fieldTrees, startIndex, endIndex, run) {
|
|
724
817
|
const itemsToResolve = fieldTrees.slice(startIndex, endIndex);
|
|
725
818
|
if (itemsToResolve.length === 0)
|
|
726
819
|
return;
|
|
@@ -734,7 +827,10 @@ class ArrayFieldComponent {
|
|
|
734
827
|
});
|
|
735
828
|
try {
|
|
736
829
|
const newItems = await firstValueFrom(forkJoin(safeItemObservables).pipe(map((items) => items.filter((item) => item !== undefined))));
|
|
737
|
-
if (
|
|
830
|
+
if (!run.isStale()) {
|
|
831
|
+
const slot = this.slot();
|
|
832
|
+
for (const item of newItems)
|
|
833
|
+
slot.itemOrder.push(item.id);
|
|
738
834
|
this.resolvedItemsSignal.update((current) => [...current, ...newItems]);
|
|
739
835
|
}
|
|
740
836
|
}
|
|
@@ -755,7 +851,7 @@ class ArrayFieldComponent {
|
|
|
755
851
|
* Priority 1.
|
|
756
852
|
* 4. Return undefined (item cannot be resolved without a template)
|
|
757
853
|
*/
|
|
758
|
-
createResolveItemObservable(index, overrideTemplate) {
|
|
854
|
+
createResolveItemObservable(index, overrideTemplate, existingItemId) {
|
|
759
855
|
const itemTemplates = this.itemTemplates();
|
|
760
856
|
const primitiveKey = this.primitiveFieldKey();
|
|
761
857
|
// Priority 1: Use override template (from recreate with stored templates)
|
|
@@ -771,6 +867,7 @@ class ArrayFieldComponent {
|
|
|
771
867
|
destroyRef: this.destroyRef,
|
|
772
868
|
loadTypeComponent: (type) => this.fieldRegistry.loadTypeComponent(type),
|
|
773
869
|
generateItemId: this.generateItemId,
|
|
870
|
+
existingItemId,
|
|
774
871
|
primitiveFieldKey: primitiveKey,
|
|
775
872
|
});
|
|
776
873
|
}
|
|
@@ -788,6 +885,7 @@ class ArrayFieldComponent {
|
|
|
788
885
|
destroyRef: this.destroyRef,
|
|
789
886
|
loadTypeComponent: (type) => this.fieldRegistry.loadTypeComponent(type),
|
|
790
887
|
generateItemId: this.generateItemId,
|
|
888
|
+
existingItemId,
|
|
791
889
|
primitiveFieldKey: primitiveKey,
|
|
792
890
|
});
|
|
793
891
|
}
|
|
@@ -806,12 +904,13 @@ class ArrayFieldComponent {
|
|
|
806
904
|
destroyRef: this.destroyRef,
|
|
807
905
|
loadTypeComponent: (type) => this.fieldRegistry.loadTypeComponent(type),
|
|
808
906
|
generateItemId: this.generateItemId,
|
|
907
|
+
existingItemId,
|
|
809
908
|
primitiveFieldKey: primitiveKey,
|
|
810
909
|
}).pipe(tap((item) => {
|
|
811
910
|
// Register the fallback template against the generated item id so subsequent
|
|
812
911
|
// recreates hit Priority 1 instead of re-resolving via this branch.
|
|
813
912
|
if (item)
|
|
814
|
-
this.
|
|
913
|
+
this.slot().templates.set(item.id, fallback);
|
|
815
914
|
}));
|
|
816
915
|
}
|
|
817
916
|
// Priority 4: no template available. Full-API arrays are positional by design —
|
|
@@ -881,8 +980,8 @@ class ArrayFieldComponent {
|
|
|
881
980
|
const hi = Math.max(fromIndex, toIndex);
|
|
882
981
|
for (let i = lo; i <= hi; i++) {
|
|
883
982
|
const item = currentItems[i];
|
|
884
|
-
if (item && !this.
|
|
885
|
-
this.
|
|
983
|
+
if (item && !this.slot().templates.has(item.id) && i < rawTemplates.length) {
|
|
984
|
+
this.slot().templates.set(item.id, rawTemplates[i]);
|
|
886
985
|
}
|
|
887
986
|
}
|
|
888
987
|
// Reorder resolvedItems — splice preserves object identity (no destroy/recreate)
|
|
@@ -892,6 +991,8 @@ class ArrayFieldComponent {
|
|
|
892
991
|
newItems.splice(toIndex, 0, moved);
|
|
893
992
|
return newItems;
|
|
894
993
|
});
|
|
994
|
+
// Keep slot.itemOrder in sync so the post-recreate survival path sees the moved order.
|
|
995
|
+
this.slot().moveItem(fromIndex, toIndex);
|
|
895
996
|
// Reorder form value array the same way
|
|
896
997
|
const newArray = [...currentArray];
|
|
897
998
|
const [movedValue] = newArray.splice(fromIndex, 1);
|
|
@@ -935,8 +1036,11 @@ class ArrayFieldComponent {
|
|
|
935
1036
|
// no longer exists, params returns undefined, cancelling the pending validation automatically.
|
|
936
1037
|
const removedItem = this.resolvedItemsSignal()[removeIndex];
|
|
937
1038
|
if (removedItem) {
|
|
938
|
-
this.
|
|
1039
|
+
this.slot().templates.delete(removedItem.id);
|
|
939
1040
|
}
|
|
1041
|
+
// Keep slot.itemOrder in sync so the post-recreate survival path doesn't try to
|
|
1042
|
+
// restore an id that's no longer in the form value.
|
|
1043
|
+
this.slot().removeAt(removeIndex);
|
|
940
1044
|
this.resolvedItemsSignal.update((current) => {
|
|
941
1045
|
const newItems = [...current];
|
|
942
1046
|
newItems.splice(removeIndex, 1);
|
|
@@ -949,13 +1053,8 @@ class ArrayFieldComponent {
|
|
|
949
1053
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
950
1054
|
parentForm().value.set({ ...currentValue, [arrayKey]: newArray });
|
|
951
1055
|
}
|
|
952
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
953
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
954
|
-
// Each array gets its own template registry to track templates used for dynamically added items
|
|
955
|
-
{ provide: ARRAY_TEMPLATE_REGISTRY, useFactory: () => new Map() },
|
|
956
|
-
// Each array gets its own ID generator for SSR hydration compatibility
|
|
957
|
-
{ provide: ARRAY_ITEM_ID_GENERATOR, useFactory: createArrayItemIdGenerator },
|
|
958
|
-
], ngImport: i0, template: `
|
|
1056
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ArrayFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1057
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", 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 }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "class.df-container-hidden": "hidden()", "attr.aria-hidden": "hidden() || null", "id": "`${key()}`", "attr.data-testid": "key()" } }, ngImport: i0, template: `
|
|
959
1058
|
@for (item of resolvedItems(); track item.id; let i = $index) {
|
|
960
1059
|
<div
|
|
961
1060
|
class="df-array-item"
|
|
@@ -965,13 +1064,15 @@ class ArrayFieldComponent {
|
|
|
965
1064
|
[attr.data-array-item-index]="i"
|
|
966
1065
|
>
|
|
967
1066
|
@for (field of item.fields; track $index) {
|
|
968
|
-
|
|
1067
|
+
@if (!field.hidden()) {
|
|
1068
|
+
<ng-container *dfFieldOutlet="field; environmentInjector: environmentInjector" />
|
|
1069
|
+
}
|
|
969
1070
|
}
|
|
970
1071
|
</div>
|
|
971
1072
|
}
|
|
972
|
-
`, isInline: true, styles: ["
|
|
1073
|
+
`, isInline: true, styles: [".df-form{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap, .5rem);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, .5rem);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, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-sm, .5rem)}.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, 12),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, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-md, .5rem)}.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, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-lg, .5rem)}.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, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-xl, .5rem)}.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-array-item-gap, var(--df-grid-row-gap, .5rem));width:100%}:host>*{grid-column:1/-1}:host.df-container-hidden{display:none}.df-array-item{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap, .5rem);width:100%}.df-array-item>*{grid-column:1/-1}\n"], dependencies: [{ kind: "directive", type: DfFieldOutlet, selector: "[dfFieldOutlet]", inputs: ["dfFieldOutlet", "dfFieldOutletEnvironmentInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
973
1074
|
}
|
|
974
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1075
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ArrayFieldComponent, decorators: [{
|
|
975
1076
|
type: Component,
|
|
976
1077
|
args: [{ selector: 'array-field', imports: [DfFieldOutlet], template: `
|
|
977
1078
|
@for (item of resolvedItems(); track item.id; let i = $index) {
|
|
@@ -983,7 +1084,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
|
|
|
983
1084
|
[attr.data-array-item-index]="i"
|
|
984
1085
|
>
|
|
985
1086
|
@for (field of item.fields; track $index) {
|
|
986
|
-
|
|
1087
|
+
@if (!field.hidden()) {
|
|
1088
|
+
<ng-container *dfFieldOutlet="field; environmentInjector: environmentInjector" />
|
|
1089
|
+
}
|
|
987
1090
|
}
|
|
988
1091
|
</div>
|
|
989
1092
|
}
|
|
@@ -993,13 +1096,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
|
|
|
993
1096
|
'[attr.aria-hidden]': 'hidden() || null',
|
|
994
1097
|
'[id]': '`${key()}`',
|
|
995
1098
|
'[attr.data-testid]': 'key()',
|
|
996
|
-
},
|
|
997
|
-
// Each array gets its own template registry to track templates used for dynamically added items
|
|
998
|
-
{ provide: ARRAY_TEMPLATE_REGISTRY, useFactory: () => new Map() },
|
|
999
|
-
// Each array gets its own ID generator for SSR hydration compatibility
|
|
1000
|
-
{ provide: ARRAY_ITEM_ID_GENERATOR, useFactory: createArrayItemIdGenerator },
|
|
1001
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, 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-array-item-gap: var(--df-grid-row-gap);--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-array-item-gap, var(--df-grid-row-gap, .5rem));width:100%}:host>*{grid-column:1/-1}:host.df-container-hidden{display:none}.df-array-item{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap, .5rem);width:100%}.df-array-item>*{grid-column:1/-1}\n"] }]
|
|
1099
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".df-form{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap, .5rem);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, .5rem);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, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-sm, .5rem)}.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, 12),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, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-md, .5rem)}.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, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-lg, .5rem)}.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, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-xl, .5rem)}.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-array-item-gap, var(--df-grid-row-gap, .5rem));width:100%}:host>*{grid-column:1/-1}:host.df-container-hidden{display:none}.df-array-item{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap, .5rem);width:100%}.df-array-item>*{grid-column:1/-1}\n"] }]
|
|
1002
1100
|
}], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], hidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidden", required: false }] }] } });
|
|
1003
1101
|
|
|
1004
1102
|
export { ArrayFieldComponent, ArrayFieldComponent as default };
|
|
1005
|
-
//# sourceMappingURL=ng-forge-dynamic-forms-array-field.component-
|
|
1103
|
+
//# sourceMappingURL=ng-forge-dynamic-forms-array-field.component-Tw49K5kz.mjs.map
|