@ng-forge/dynamic-forms 0.6.1 → 0.7.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.
@@ -1,9 +1,9 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, Injectable, isSignal, untracked, isDevMode, isWritableSignal, Injector, DestroyRef, computed, input, linkedSignal, ChangeDetectionStrategy, Component, signal, runInInjectionContext, afterNextRender, model, makeEnvironmentProviders, Pipe } from '@angular/core';
2
+ import { InjectionToken, inject, Injectable, isSignal, untracked, isWritableSignal, isDevMode, Injector, DestroyRef, computed, input, linkedSignal, ChangeDetectionStrategy, Component, resourceFromSnapshots, signal, runInInjectionContext, afterNextRender, model, EnvironmentInjector, makeEnvironmentProviders, Pipe } from '@angular/core';
3
3
  import { NgComponentOutlet } from '@angular/common';
4
- import { toObservable, toSignal, takeUntilDestroyed, outputFromObservable } from '@angular/core/rxjs-interop';
4
+ import { toObservable, toSignal, takeUntilDestroyed, rxResource, outputFromObservable } from '@angular/core/rxjs-interop';
5
5
  import { submit, email, min, max, minLength, maxLength, pattern, required, validate, validateAsync, validateHttp, disabled, readonly, hidden, applyEach, applyWhenValue, applyWhen, apply, schema, validateStandardSchema, validateTree, form, provideSignalFormsConfig } from '@angular/forms/signals';
6
- import { isObservable, firstValueFrom, exhaustMap, EMPTY, from, catchError, Subject, filter, TimeoutError, of, throwError, debounceTime, distinctUntilChanged, tap, take as take$1, startWith, pairwise, map as map$1, switchMap as switchMap$1, Observable, takeUntil, combineLatestWith, auditTime, scheduled, queueScheduler, merge, timer, concat, defer, combineLatest, pipe, forkJoin, scan as scan$1, concatMap } from 'rxjs';
6
+ import { isObservable, firstValueFrom, exhaustMap, EMPTY, from, catchError, Subject, filter, TimeoutError, of, throwError, debounceTime, distinctUntilChanged, tap, take as take$1, startWith, pairwise, map as map$1, switchMap as switchMap$1, Observable, takeUntil, combineLatestWith, auditTime, scheduled, queueScheduler, merge, timer, defer, combineLatest, pipe, forkJoin, scan as scan$1, concatMap } from 'rxjs';
7
7
  import { scan, map, filter as filter$1, take, switchMap, timeout, catchError as catchError$1, shareReplay } from 'rxjs/operators';
8
8
  import { explicitEffect } from 'ngxtension/explicit-effect';
9
9
  import { HttpClient } from '@angular/common/http';
@@ -532,10 +532,10 @@ class EventBus {
532
532
  }
533
533
  return this.pipeline$.pipe(filter((event) => event.type === eventType));
534
534
  }
535
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: EventBus, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
536
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: EventBus });
535
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EventBus, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
536
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EventBus });
537
537
  }
538
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: EventBus, decorators: [{
538
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EventBus, decorators: [{
539
539
  type: Injectable
540
540
  }] });
541
541
 
@@ -1240,12 +1240,12 @@ function assertNever(value) {
1240
1240
  * - Example: `noSpaces: (ctx) => ctx.value().includes(' ') ? { kind: 'noSpaces' } : null`
1241
1241
  *
1242
1242
  * 3. **Async Validators** - For asynchronous validation (debouncing, database lookups, etc.)
1243
- * - Used in: validators array on fields with type 'customAsync'
1243
+ * - Used in: validators array on fields with type 'async'
1244
1244
  * - Return type: Observable<ValidationError | ValidationError[] | null>
1245
1245
  * - Example: `checkUsername: (ctx) => userService.checkAvailability(ctx.value())`
1246
1246
  *
1247
1247
  * 4. **HTTP Validators** - For HTTP-based validation with automatic request cancellation
1248
- * - Used in: validators array on fields with type 'customHttp'
1248
+ * - Used in: validators array on fields with type 'http'
1249
1249
  * - Configuration object with url, method, mapResponse, etc.
1250
1250
  * - Example: `{ url: '/api/check', method: 'GET', mapResponse: ... }`
1251
1251
  *
@@ -1292,8 +1292,6 @@ class FunctionRegistryService {
1292
1292
  customFunctions = new Map();
1293
1293
  customFunctionScopes = new Map();
1294
1294
  derivationFunctions = new Map();
1295
- // TODO(@ng-forge): remove deprecated code in next minor
1296
- propertyDerivationFunctions = new Map();
1297
1295
  asyncDerivationFunctions = new Map();
1298
1296
  asyncConditionFunctions = new Map();
1299
1297
  validators = new Map();
@@ -1405,58 +1403,6 @@ class FunctionRegistryService {
1405
1403
  this.derivationFunctions.clear();
1406
1404
  }
1407
1405
  // ─────────────────────────────────────────────────────────────────────────────
1408
- // Property Derivation Functions
1409
- // TODO(@ng-forge): remove deprecated code in next minor
1410
- // ─────────────────────────────────────────────────────────────────────────────
1411
- /**
1412
- * Register a property derivation function.
1413
- *
1414
- * Property derivation functions compute derived values for field properties
1415
- * (like `minDate`, `options`, `label`) and are called when a
1416
- * `PropertyDerivationLogicConfig` references them by `functionName`.
1417
- *
1418
- * @param name - Unique identifier for the function
1419
- * @param fn - Function that receives EvaluationContext and returns the derived property value
1420
- */
1421
- registerPropertyDerivationFunction(name, fn) {
1422
- this.propertyDerivationFunctions.set(name, fn);
1423
- }
1424
- /**
1425
- * Get a property derivation function by name
1426
- */
1427
- getPropertyDerivationFunction(name) {
1428
- return this.propertyDerivationFunctions.get(name) ?? this.derivationFunctions.get(name);
1429
- }
1430
- /**
1431
- * Get all property derivation functions as an object.
1432
- *
1433
- * Merges both `derivationFunctions` and `propertyDerivationFunctions` maps,
1434
- * with `propertyDerivationFunctions` taking precedence. This allows users
1435
- * to migrate functions from `propertyDerivations` to `derivations` without
1436
- * breaking property derivation lookups.
1437
- */
1438
- getPropertyDerivationFunctions() {
1439
- return {
1440
- ...Object.fromEntries(this.derivationFunctions),
1441
- ...Object.fromEntries(this.propertyDerivationFunctions),
1442
- };
1443
- }
1444
- /**
1445
- * Set property derivation functions from a config object.
1446
- * Only updates functions if their references have changed.
1447
- *
1448
- * @param functions - Object mapping function names to property derivation functions
1449
- */
1450
- setPropertyDerivationFunctions(functions) {
1451
- this.setRegistryIfChanged(this.propertyDerivationFunctions, functions);
1452
- }
1453
- /**
1454
- * Clear all property derivation functions
1455
- */
1456
- clearPropertyDerivationFunctions() {
1457
- this.propertyDerivationFunctions.clear();
1458
- }
1459
- // ─────────────────────────────────────────────────────────────────────────────
1460
1406
  // Async Derivation Functions
1461
1407
  // ─────────────────────────────────────────────────────────────────────────────
1462
1408
  /**
@@ -1757,17 +1703,16 @@ class FunctionRegistryService {
1757
1703
  clearAll() {
1758
1704
  this.clearCustomFunctions();
1759
1705
  this.clearDerivationFunctions();
1760
- this.clearPropertyDerivationFunctions();
1761
1706
  this.clearAsyncDerivationFunctions();
1762
1707
  this.clearAsyncConditionFunctions();
1763
1708
  this.clearValidators();
1764
1709
  this.clearAsyncValidators();
1765
1710
  this.clearHttpValidators();
1766
1711
  }
1767
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FunctionRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1768
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FunctionRegistryService });
1712
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FunctionRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1713
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FunctionRegistryService });
1769
1714
  }
1770
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FunctionRegistryService, decorators: [{
1715
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FunctionRegistryService, decorators: [{
1771
1716
  type: Injectable
1772
1717
  }] });
1773
1718
 
@@ -1806,10 +1751,10 @@ class SchemaRegistryService {
1806
1751
  }
1807
1752
  return schema;
1808
1753
  }
1809
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SchemaRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1810
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SchemaRegistryService });
1754
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: SchemaRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1755
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: SchemaRegistryService });
1811
1756
  }
1812
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SchemaRegistryService, decorators: [{
1757
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: SchemaRegistryService, decorators: [{
1813
1758
  type: Injectable
1814
1759
  }] });
1815
1760
 
@@ -2390,10 +2335,10 @@ class FieldContextRegistryService {
2390
2335
  },
2391
2336
  };
2392
2337
  }
2393
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FieldContextRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2394
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FieldContextRegistryService });
2338
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FieldContextRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2339
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FieldContextRegistryService });
2395
2340
  }
2396
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FieldContextRegistryService, decorators: [{
2341
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FieldContextRegistryService, decorators: [{
2397
2342
  type: Injectable
2398
2343
  }] });
2399
2344
 
@@ -2721,24 +2666,6 @@ function countArrayPlaceholders(path) {
2721
2666
  return path.split('.').filter((part) => part === '$').length;
2722
2667
  }
2723
2668
 
2724
- /**
2725
- * Emits a deprecation warning once per unique key in dev mode only.
2726
- * Subsequent calls with the same `id` are silently ignored.
2727
- *
2728
- * @param logger - The DynamicFormLogger instance for output
2729
- * @param tracker - DI-scoped tracker to deduplicate warnings
2730
- * @param id - Unique identifier for this deprecation (e.g., 'type:propertyDerivation')
2731
- * @param message - Human-readable deprecation message
2732
- *
2733
- * @public
2734
- */
2735
- function warnDeprecated(logger, tracker, id, message) {
2736
- if (isDevMode() && !tracker.warnedKeys.has(id)) {
2737
- tracker.warnedKeys.add(id);
2738
- logger.warn(`[Dynamic Forms] DEPRECATED: ${message}`);
2739
- }
2740
- }
2741
-
2742
2669
  /**
2743
2670
  * Token types for expression parsing
2744
2671
  */
@@ -3595,16 +3522,22 @@ function evaluateCondition(expression, context) {
3595
3522
  switch (expression.type) {
3596
3523
  case 'fieldValue':
3597
3524
  return evaluateFieldValueCondition(expression, context);
3598
- case 'formValue':
3599
- // TODO(@ng-forge): remove deprecated code in next minor
3600
- if (context.deprecationTracker) {
3601
- warnDeprecated(context.logger, context.deprecationTracker, 'condition:formValue', "Condition type 'formValue' is deprecated. Use 'fieldValue' with a specific fieldPath, or 'javascript' for complex form-level comparisons.");
3602
- }
3603
- return evaluateFormValueCondition(expression, context);
3604
3525
  case 'javascript':
3605
3526
  return evaluateJavaScriptExpression(expression, context);
3606
- case 'custom':
3607
- return evaluateCustomFunction(expression, context);
3527
+ case 'custom': {
3528
+ const customFn = context.customFunctions?.[expression.functionName];
3529
+ if (!customFn) {
3530
+ context.logger.error('Custom function not found:', expression.functionName);
3531
+ return false;
3532
+ }
3533
+ try {
3534
+ return !!customFn(context);
3535
+ }
3536
+ catch (error) {
3537
+ context.logger.error('Error executing custom function:', expression.functionName, error);
3538
+ return false;
3539
+ }
3540
+ }
3608
3541
  case 'and':
3609
3542
  return evaluateAndCondition(expression, context);
3610
3543
  case 'or':
@@ -3637,12 +3570,9 @@ function evaluateFieldValueCondition(expression, context) {
3637
3570
  : undefined;
3638
3571
  return compareValues(fieldValue, expression.value, expression.operator);
3639
3572
  }
3640
- function evaluateFormValueCondition(expression, context) {
3641
- return compareValues(context.formValue, expression.value, expression.operator);
3642
- }
3643
3573
  function evaluateJavaScriptExpression(expression, context) {
3644
3574
  try {
3645
- // Use secure AST-based expression parser instead of new Function()
3575
+ // Use secure AST-based expression parser instead of dynamic code execution
3646
3576
  const result = ExpressionParser.evaluate(expression.expression, context);
3647
3577
  return !!result;
3648
3578
  }
@@ -3651,25 +3581,6 @@ function evaluateJavaScriptExpression(expression, context) {
3651
3581
  return false;
3652
3582
  }
3653
3583
  }
3654
- function evaluateCustomFunction(expression, context) {
3655
- const fnName = 'functionName' in expression ? expression.functionName : expression.expression;
3656
- // TODO(@ng-forge): remove deprecated code in next minor
3657
- if (!('functionName' in expression) && context.deprecationTracker) {
3658
- warnDeprecated(context.logger, context.deprecationTracker, 'condition:custom:expression', "CustomCondition 'expression' field is deprecated. Use 'functionName' instead.");
3659
- }
3660
- const customFn = context.customFunctions?.[fnName];
3661
- if (!customFn) {
3662
- context.logger.error('Custom function not found:', fnName);
3663
- return false;
3664
- }
3665
- try {
3666
- return !!customFn(context);
3667
- }
3668
- catch (error) {
3669
- context.logger.error('Error executing custom function:', fnName, error);
3670
- return false;
3671
- }
3672
- }
3673
3584
  function evaluateAndCondition(expression, context) {
3674
3585
  if (expression.conditions.length === 0)
3675
3586
  return false;
@@ -4578,21 +4489,6 @@ function isStateLogicConfig(config) {
4578
4489
  function isDerivationLogicConfig(config) {
4579
4490
  return config.type === 'derivation';
4580
4491
  }
4581
- // TODO(@ng-forge): remove deprecated code in next minor
4582
- /**
4583
- * Type guard to check if a logic config is a PropertyDerivationLogicConfig.
4584
- *
4585
- * @deprecated Use `isDerivationLogicConfig(config) && hasTargetProperty(config)` instead.
4586
- * Will be removed in a future minor version.
4587
- *
4588
- * @param config - The logic config to check
4589
- * @returns true if the config is for property derivation
4590
- *
4591
- * @public
4592
- */
4593
- function isPropertyDerivationLogicConfig(config) {
4594
- return config.type === 'propertyDerivation';
4595
- }
4596
4492
  /**
4597
4493
  * Type guard to check if a derivation config targets a property rather than the field value.
4598
4494
  *
@@ -4651,18 +4547,13 @@ function isCrossFieldExpression(expr, context) {
4651
4547
  case 'fieldValue':
4652
4548
  // fieldPath means it references another field's value
4653
4549
  return !!expr.fieldPath;
4654
- case 'formValue':
4655
- // formValue type always accesses the form state
4656
- return true;
4657
4550
  case 'javascript':
4658
4551
  // Check for formValue.* patterns in the expression string
4659
4552
  return FORM_VALUE_ACCESS_PATTERN.test(expr.expression || '');
4660
4553
  case 'custom': {
4661
4554
  // For custom functions, determine scope from registry or default to cross-field.
4662
- // Support both new API (functionName) and deprecated API (expression).
4663
- //
4664
4555
  // Look up function scope from registry if context is provided
4665
- const functionName = 'functionName' in expr ? expr.functionName : expr.expression;
4556
+ const functionName = expr.functionName;
4666
4557
  if (context?.getFunctionScope && functionName) {
4667
4558
  const scope = context.getFunctionScope(functionName);
4668
4559
  if (scope === 'field') {
@@ -4708,10 +4599,6 @@ function extractExpressionDependencies(expr) {
4708
4599
  deps.add(expr.fieldPath.split('.')[0]);
4709
4600
  }
4710
4601
  break;
4711
- case 'formValue':
4712
- // Full form access - depends on everything
4713
- deps.add('*');
4714
- break;
4715
4602
  case 'javascript':
4716
4603
  // Extract from formValue.* patterns in expression
4717
4604
  extractFromExpressionString(expr.expression || '', deps);
@@ -4826,7 +4713,7 @@ function isCrossFieldBuiltInValidator(config) {
4826
4713
  * because they require field-level registration.
4827
4714
  */
4828
4715
  function isResourceBasedValidator(config) {
4829
- return config.type === 'customAsync' || config.type === 'customHttp' || config.type === 'http';
4716
+ return config.type === 'async' || config.type === 'http';
4830
4717
  }
4831
4718
  /**
4832
4719
  * Detects if a validator's `when` condition is cross-field.
@@ -4857,23 +4744,6 @@ function hasCrossFieldWhenCondition(config, context) {
4857
4744
  function isCrossFieldStateLogic(config, context) {
4858
4745
  return isCrossFieldExpression(config.condition, context);
4859
4746
  }
4860
- /**
4861
- * Detects if a LogicConfig has a cross-field condition.
4862
- *
4863
- * @param config The logic configuration to check
4864
- * @param context Optional context providing function scope lookup
4865
- * @returns true if the logic condition references other fields
4866
- *
4867
- * @deprecated Use `isCrossFieldStateLogic` for state logic configs.
4868
- * Derivation logic is handled by the derivation system.
4869
- */
4870
- function isCrossFieldLogic(config, context) {
4871
- // Only check state logic configs
4872
- if (!isStateLogicConfig(config)) {
4873
- return false;
4874
- }
4875
- return isCrossFieldExpression(config.condition, context);
4876
- }
4877
4747
  // ============================================================================
4878
4748
  // Schema Detection
4879
4749
  // ============================================================================
@@ -6083,7 +5953,7 @@ class DerivationOrchestrator {
6083
5953
  this.warnAboutWildcardDependencies(collection.entries, fields.length);
6084
5954
  this.warnAboutMisconfiguredReEngagement(collection.entries);
6085
5955
  return collection;
6086
- }, ...(ngDevMode ? [{ debugName: "derivationCollection" }] : []));
5956
+ }, ...(ngDevMode ? [{ debugName: "derivationCollection" }] : /* istanbul ignore next */ []));
6087
5957
  this.setupOnChangeStream();
6088
5958
  this.setupDebouncedStream();
6089
5959
  this.setupHttpStreams();
@@ -6658,9 +6528,9 @@ function computePropertyValue(entry, evalContext, applicatorContext) {
6658
6528
  }
6659
6529
  // Custom function
6660
6530
  if (entry.functionName) {
6661
- const fn = applicatorContext.propertyDerivationFunctions?.[entry.functionName];
6531
+ const fn = applicatorContext.derivationFunctions?.[entry.functionName];
6662
6532
  if (!fn) {
6663
- throw new DynamicFormError(`Property derivation function '${entry.functionName}' not found in customFnConfig.derivations or customFnConfig.propertyDerivations`);
6533
+ throw new DynamicFormError(`Property derivation function '${entry.functionName}' not found in customFnConfig.derivations`);
6664
6534
  }
6665
6535
  return fn(evalContext);
6666
6536
  }
@@ -6707,7 +6577,7 @@ function buildPropertyOverrideKey(arrayKey, index, fieldKey) {
6707
6577
  /**
6708
6578
  * Collects all property derivation entries from field definitions.
6709
6579
  *
6710
- * Traverses the field definition tree and extracts `type: 'propertyDerivation'`
6580
+ * Traverses the field definition tree and extracts `type: 'derivation'` with `targetProperty`
6711
6581
  * entries from each field's `logic` array.
6712
6582
  *
6713
6583
  * No topological sort is needed because property derivations don't chain —
@@ -6767,46 +6637,13 @@ function collectFromField$1(field, entries, context) {
6767
6637
  const validationField = field;
6768
6638
  if (validationField.logic) {
6769
6639
  for (const logicConfig of validationField.logic) {
6770
- if (isPropertyDerivationLogicConfig(logicConfig)) {
6771
- // TODO(@ng-forge): remove deprecated code in next minor
6772
- // Deprecated path — emit warning, then process normally
6773
- warnDeprecated(context.logger, context.tracker, 'type:propertyDerivation', "Logic type 'propertyDerivation' is deprecated. Use type: 'derivation' with targetProperty instead.");
6774
- const entry = createPropertyDerivationEntry(fieldKey, logicConfig, context);
6775
- entries.push(entry);
6776
- }
6777
- else if (isDerivationLogicConfig(logicConfig) && hasTargetProperty(logicConfig)) {
6778
- // New unified path: type: 'derivation' + targetProperty → property derivation pipeline
6640
+ if (isDerivationLogicConfig(logicConfig) && hasTargetProperty(logicConfig)) {
6779
6641
  const entry = createPropertyDerivationEntryFromDerivation(fieldKey, logicConfig, context);
6780
6642
  entries.push(entry);
6781
6643
  }
6782
6644
  }
6783
6645
  }
6784
6646
  }
6785
- /**
6786
- * Creates a property derivation entry from a `PropertyDerivationLogicConfig`.
6787
- *
6788
- * @internal
6789
- */
6790
- function createPropertyDerivationEntry(fieldKey, config, context) {
6791
- const effectiveFieldKey = buildPropertyOverrideKey(context.arrayPath, context.arrayPath ? PLACEHOLDER_INDEX : undefined, fieldKey);
6792
- const dependsOn = extractDependencies(config);
6793
- const condition = config.condition ?? true;
6794
- const trigger = config.trigger ?? 'onChange';
6795
- const debounceMs = trigger === 'debounced' ? config.debounceMs : undefined;
6796
- return {
6797
- fieldKey: effectiveFieldKey,
6798
- targetProperty: config.targetProperty,
6799
- dependsOn,
6800
- condition,
6801
- value: config.value,
6802
- expression: config.expression,
6803
- functionName: config.functionName,
6804
- trigger,
6805
- debounceMs,
6806
- debugName: config.debugName,
6807
- originalConfig: config,
6808
- };
6809
- }
6810
6647
  /**
6811
6648
  * Creates a property derivation entry from a `DerivationLogicConfig` that has `targetProperty`.
6812
6649
  *
@@ -6899,7 +6736,7 @@ class PropertyDerivationOrchestrator {
6899
6736
  return null;
6900
6737
  }
6901
6738
  return collection;
6902
- }, ...(ngDevMode ? [{ debugName: "propertyDerivationCollection" }] : []));
6739
+ }, ...(ngDevMode ? [{ debugName: "propertyDerivationCollection" }] : /* istanbul ignore next */ []));
6903
6740
  // Side effects react to collection changes: clear the store, register fields, warn.
6904
6741
  // schemaFields is included in the dependency array to ensure the field count is always
6905
6742
  // in sync with the collection (avoids reading a stale value via untracked).
@@ -6959,7 +6796,7 @@ class PropertyDerivationOrchestrator {
6959
6796
  const applicatorContext = {
6960
6797
  formValue: this.config.formValue,
6961
6798
  store: this.config.store,
6962
- propertyDerivationFunctions: this.functionRegistry.getPropertyDerivationFunctions(),
6799
+ derivationFunctions: this.functionRegistry.getDerivationFunctions(),
6963
6800
  customFunctions: this.functionRegistry.getCustomFunctions(),
6964
6801
  externalData: this.resolveExternalData(),
6965
6802
  logger: this.logger,
@@ -6975,7 +6812,7 @@ class PropertyDerivationOrchestrator {
6975
6812
  const applicatorContext = {
6976
6813
  formValue: this.config.formValue,
6977
6814
  store: this.config.store,
6978
- propertyDerivationFunctions: this.functionRegistry.getPropertyDerivationFunctions(),
6815
+ derivationFunctions: this.functionRegistry.getDerivationFunctions(),
6979
6816
  customFunctions: this.functionRegistry.getCustomFunctions(),
6980
6817
  externalData: this.resolveExternalData(),
6981
6818
  logger: this.logger,
@@ -7369,17 +7206,17 @@ class PageOrchestratorComponent {
7369
7206
  /**
7370
7207
  * Array of page field definitions to render
7371
7208
  */
7372
- pageFields = input.required(...(ngDevMode ? [{ debugName: "pageFields" }] : []));
7209
+ pageFields = input.required(...(ngDevMode ? [{ debugName: "pageFields" }] : /* istanbul ignore next */ []));
7373
7210
  /**
7374
7211
  * Root form instance from parent DynamicForm.
7375
7212
  * Uses FieldTree<unknown> to accept any form type.
7376
7213
  */
7377
- form = input.required(...(ngDevMode ? [{ debugName: "form" }] : []));
7214
+ form = input.required(...(ngDevMode ? [{ debugName: "form" }] : /* istanbul ignore next */ []));
7378
7215
  /**
7379
7216
  * Field signal context for child fields
7380
7217
  */
7381
7218
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- FieldSignalContext is contravariant in TModel, using any allows accepting any form type
7382
- fieldSignalContext = input.required(...(ngDevMode ? [{ debugName: "fieldSignalContext" }] : []));
7219
+ fieldSignalContext = input.required(...(ngDevMode ? [{ debugName: "fieldSignalContext" }] : /* istanbul ignore next */ []));
7383
7220
  /**
7384
7221
  * Computed signal that tracks which pages are hidden.
7385
7222
  * Returns an array of booleans where true means the page is hidden.
@@ -7388,7 +7225,7 @@ class PageOrchestratorComponent {
7388
7225
  pageHiddenStates = computed(() => {
7389
7226
  const pages = this.pageFields();
7390
7227
  return pages.map((page) => this.evaluatePageHidden(page));
7391
- }, ...(ngDevMode ? [{ debugName: "pageHiddenStates" }] : []));
7228
+ }, ...(ngDevMode ? [{ debugName: "pageHiddenStates" }] : /* istanbul ignore next */ []));
7392
7229
  /**
7393
7230
  * Computed signal that returns indices of visible (non-hidden) pages.
7394
7231
  * This is used for navigation to skip hidden pages.
@@ -7399,7 +7236,7 @@ class PageOrchestratorComponent {
7399
7236
  .map((hidden, index) => ({ index, hidden }))
7400
7237
  .filter((item) => !item.hidden)
7401
7238
  .map((item) => item.index);
7402
- }, ...(ngDevMode ? [{ debugName: "visiblePageIndices" }] : []));
7239
+ }, ...(ngDevMode ? [{ debugName: "visiblePageIndices" }] : /* istanbul ignore next */ []));
7403
7240
  /**
7404
7241
  * Internal signal for current page index that tracks with page fields.
7405
7242
  * This tracks the actual page index, not the visible page index.
@@ -7414,7 +7251,7 @@ class PageOrchestratorComponent {
7414
7251
  return 0;
7415
7252
  // Start on page 0 (will be adjusted if page 0 is hidden by initial navigation)
7416
7253
  return 0;
7417
- }, ...(ngDevMode ? [{ debugName: "currentPageIndex" }] : []));
7254
+ }, ...(ngDevMode ? [{ debugName: "currentPageIndex" }] : /* istanbul ignore next */ []));
7418
7255
  /**
7419
7256
  * Computed state for the orchestrator
7420
7257
  */
@@ -7433,7 +7270,7 @@ class PageOrchestratorComponent {
7433
7270
  isLastPage: isLastVisiblePage,
7434
7271
  navigationDisabled: false,
7435
7272
  };
7436
- }, ...(ngDevMode ? [{ debugName: "state" }] : []));
7273
+ }, ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
7437
7274
  /**
7438
7275
  * Signal indicating whether all fields on the current page are valid.
7439
7276
  *
@@ -7467,7 +7304,7 @@ class PageOrchestratorComponent {
7467
7304
  }
7468
7305
  }
7469
7306
  return true;
7470
- }, ...(ngDevMode ? [{ debugName: "currentPageValid" }] : []));
7307
+ }, ...(ngDevMode ? [{ debugName: "currentPageValid" }] : /* istanbul ignore next */ []));
7471
7308
  /**
7472
7309
  * Extended field signal context that includes currentPageValid.
7473
7310
  *
@@ -7478,7 +7315,7 @@ class PageOrchestratorComponent {
7478
7315
  extendedFieldSignalContext = computed(() => ({
7479
7316
  ...this.fieldSignalContext(),
7480
7317
  currentPageValid: this.currentPageValid,
7481
- }), ...(ngDevMode ? [{ debugName: "extendedFieldSignalContext" }] : []));
7318
+ }), ...(ngDevMode ? [{ debugName: "extendedFieldSignalContext" }] : /* istanbul ignore next */ []));
7482
7319
  constructor() {
7483
7320
  // Setup event listeners for navigation
7484
7321
  this.setupEventListeners();
@@ -7685,8 +7522,8 @@ class PageOrchestratorComponent {
7685
7522
  }
7686
7523
  return false;
7687
7524
  }
7688
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: PageOrchestratorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7689
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", 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: [
7525
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: PageOrchestratorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7526
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", 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: [
7690
7527
  {
7691
7528
  provide: FIELD_SIGNAL_CONTEXT,
7692
7529
  useFactory: (orchestrator) => orchestrator.extendedFieldSignalContext(),
@@ -7716,9 +7553,9 @@ class PageOrchestratorComponent {
7716
7553
  }
7717
7554
  }
7718
7555
  }
7719
- `, isInline: true, styles: [":host{display:block;position:relative;width:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [import('./ng-forge-dynamic-forms-page-field.component-D6M_uJKu.mjs').then(m => m.default)], () => [import('./ng-forge-dynamic-forms-page-field.component-D6M_uJKu.mjs').then(m => m.default)]] });
7556
+ `, isInline: true, styles: [":host{display:block;position:relative;width:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [import('./ng-forge-dynamic-forms-page-field.component-Cen4ArED.mjs').then(m => m.default)], () => [import('./ng-forge-dynamic-forms-page-field.component-Cen4ArED.mjs').then(m => m.default)]] });
7720
7557
  }
7721
- i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "21.2.0", ngImport: i0, type: PageOrchestratorComponent, resolveDeferredDeps: () => [import('./ng-forge-dynamic-forms-page-field.component-D6M_uJKu.mjs').then(m => m.default)], resolveMetadata: PageFieldComponent => ({ decorators: [{
7558
+ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "21.2.6", ngImport: i0, type: PageOrchestratorComponent, resolveDeferredDeps: () => [import('./ng-forge-dynamic-forms-page-field.component-Cen4ArED.mjs').then(m => m.default)], resolveMetadata: PageFieldComponent => ({ decorators: [{
7722
7559
  type: Component,
7723
7560
  args: [{ selector: 'div[page-orchestrator]', imports: [PageFieldComponent], template: `
7724
7561
  @for (pageField of pageFields(); track pageField.key; let i = $index) {
@@ -8244,6 +8081,83 @@ class HttpConditionFunctionCacheService {
8244
8081
  httpConditionFunctionCache = new Map();
8245
8082
  }
8246
8083
 
8084
+ /**
8085
+ * Wraps a `Resource` so that the previous resolved value is preserved while the resource
8086
+ * is loading or reloading. This prevents UI flicker when params change and a new request
8087
+ * is in-flight — the consumer sees the stale value with a `loading`/`reloading` status
8088
+ * instead of `undefined`.
8089
+ *
8090
+ * Uses Angular's `resource.snapshot` + `resourceFromSnapshots` composition pattern.
8091
+ *
8092
+ * @example
8093
+ * ```typescript
8094
+ * const user = withPreviousValue(
8095
+ * resource({ params: () => userId(), loader: ({ params }) => fetchUser(params) })
8096
+ * );
8097
+ * // user.value() keeps the old user data during loading transitions
8098
+ * ```
8099
+ *
8100
+ * @experimental Uses Angular's experimental resource composition APIs.
8101
+ */
8102
+ function withPreviousValue(input) {
8103
+ const derived = linkedSignal({ ...(ngDevMode ? { debugName: "derived" } : /* istanbul ignore next */ {}), source: input.snapshot,
8104
+ computation: (snapshot, previous) => {
8105
+ // During loading/reloading, keep the previous resolved value if available.
8106
+ // Don't preserve values from error states — those aren't useful to show.
8107
+ if ((snapshot.status === 'loading' || snapshot.status === 'reloading') &&
8108
+ previous !== undefined &&
8109
+ previous.value.status !== 'error') {
8110
+ return { status: snapshot.status, value: previous.value.value };
8111
+ }
8112
+ return snapshot;
8113
+ } });
8114
+ return resourceFromSnapshots(derived);
8115
+ }
8116
+
8117
+ /**
8118
+ * Type guard to check if a value is an array of Signals.
8119
+ * @internal
8120
+ */
8121
+ function isSignalArray(value) {
8122
+ return Array.isArray(value) && value.every((item) => isSignal(item));
8123
+ }
8124
+ /**
8125
+ * Type guard to check if a value is a record (object) of Signals.
8126
+ * @internal
8127
+ */
8128
+ function isSignalRecord(value) {
8129
+ return typeof value === 'object' && value !== null && !Array.isArray(value) && Object.values(value).every((item) => isSignal(item));
8130
+ }
8131
+ // Implementation
8132
+ function derivedFromDeferred(source, operator, options) {
8133
+ const deferred$ = defer(() => {
8134
+ // Handle single signal
8135
+ if (isSignal(source)) {
8136
+ return toObservable(source, { injector: options.injector });
8137
+ }
8138
+ // Handle array of signals
8139
+ if (isSignalArray(source)) {
8140
+ const observables = source.map((s) => toObservable(s, { injector: options.injector }));
8141
+ return combineLatest(observables);
8142
+ }
8143
+ // Handle object of signals
8144
+ if (isSignalRecord(source)) {
8145
+ const keys = Object.keys(source);
8146
+ const observables = keys.map((key) => toObservable(source[key], { injector: options.injector }));
8147
+ return combineLatest(observables, (...values) => {
8148
+ const result = {};
8149
+ keys.forEach((key, index) => {
8150
+ result[key] = values[index];
8151
+ });
8152
+ return result;
8153
+ });
8154
+ }
8155
+ // Fallback - should not happen with proper typing
8156
+ throw new Error('Invalid source type. Expected a Signal, array of Signals, or object of Signals.');
8157
+ }).pipe(operator);
8158
+ return toSignal(deferred$, { initialValue: options.initialValue, injector: options.injector });
8159
+ }
8160
+
8247
8161
  /**
8248
8162
  * Extracts a boolean from an HTTP response using an optional expression.
8249
8163
  * When `responseExpression` is provided, evaluates it with `{ response }` scope.
@@ -8269,10 +8183,10 @@ function extractBoolean(response, responseExpression, pendingValue, logger) {
8269
8183
  /**
8270
8184
  * Creates a logic function for an HTTP condition.
8271
8185
  *
8272
- * Uses a signal-based async resolution pattern: the LogicFn updates a `resolvedRequest` signal,
8273
- * a reactive pipeline fetches the response and updates a `resultValue` signal.
8274
- * The LogicFn returns the current `resultValue()`, which starts as `pendingValue` and
8275
- * transitions to the actual HTTP result.
8186
+ * Uses Angular's `rxResource()` API with snapshot composition for async resolution:
8187
+ * the LogicFn updates a `resolvedRequest` signal, a debounced version feeds into
8188
+ * an `rxResource()` that manages the HTTP lifecycle, and `withPreviousValue()` preserves
8189
+ * the last resolved boolean during re-fetching to prevent UI flicker.
8276
8190
  *
8277
8191
  * Must be called in injection context (same as `createLogicFunction`).
8278
8192
  */
@@ -8303,30 +8217,45 @@ function createHttpConditionLogicFunction(condition) {
8303
8217
  const contextKey = safeReadPathKeys(ctx).join('.');
8304
8218
  let signalPair = perFunctionSignalStore.get(contextKey);
8305
8219
  if (!signalPair) {
8306
- const resolvedRequest = signal(undefined, ...(ngDevMode ? [{ debugName: "resolvedRequest" }] : []));
8307
- // Wrap in untracked() to avoid NG0602: toObservable() internally calls effect(),
8220
+ const resolvedRequest = signal(undefined, ...(ngDevMode ? [{ debugName: "resolvedRequest" }] : /* istanbul ignore next */ []));
8221
+ // Wrap in untracked() to avoid NG0602: resource() internally creates effects,
8308
8222
  // which cannot be created inside a reactive context (computed). The LogicFn runs
8309
8223
  // inside Angular Signal Forms' BooleanOrLogic.compute (a computed), so we must
8310
- // clear the active reactive consumer before creating the observable pipeline.
8311
- const resultValue = untracked(() => {
8312
- const pipeline = toObservable(resolvedRequest, { injector }).pipe(debounceTime(debounceMs), distinctUntilChanged((prev, curr) => stableStringify(prev) === stableStringify(curr)), filter((request) => request !== undefined), switchMap$1((request) => {
8313
- const method = request.method ?? 'GET';
8314
- const options = {};
8315
- if (request.body)
8316
- options['body'] = request.body;
8317
- if (request.headers)
8318
- options['headers'] = request.headers;
8319
- return httpClient.request(method, request.url, options).pipe(map$1((response) => extractBoolean(response, condition.responseExpression, pendingValue, logger)), tap((value) => {
8320
- const requestKey = stableStringify(request);
8321
- cache.set(requestKey, value, cacheDurationMs);
8322
- }), catchError((error) => {
8323
- logger.warn('HTTP condition request failed:', error);
8324
- return of(pendingValue);
8325
- }));
8326
- }), startWith(pendingValue));
8327
- return toSignal(pipeline, { injector, initialValue: pendingValue });
8224
+ // clear the active reactive consumer before creating the resource pipeline.
8225
+ const resultResource = untracked(() => {
8226
+ // Create a debounced, stabilized version of the request signal.
8227
+ // This prevents rapid re-fetches when form values change quickly.
8228
+ const debouncedRequest = derivedFromDeferred(resolvedRequest, pipe(debounceTime(debounceMs), distinctUntilChanged((prev, curr) => stableStringify(prev) === stableStringify(curr))), { initialValue: undefined, injector });
8229
+ // rxResource() manages the HTTP lifecycle natively with Observables:
8230
+ // auto-cancellation via unsubscription, loading/resolved/error status tracking,
8231
+ // and signal-based reactivity.
8232
+ const httpResource = rxResource({
8233
+ params: () => debouncedRequest() ?? undefined,
8234
+ // When params() returns undefined, rxResource() enters idle state and skips the stream.
8235
+ stream: ({ params: request }) => {
8236
+ const method = request.method ?? 'GET';
8237
+ const options = {};
8238
+ if (request.body)
8239
+ options['body'] = request.body;
8240
+ if (request.headers)
8241
+ options['headers'] = request.headers;
8242
+ return httpClient.request(method, request.url, options).pipe(map$1((response) => extractBoolean(response, condition.responseExpression, pendingValue, logger)), tap((value) => {
8243
+ const requestKey = stableStringify(request);
8244
+ cache.set(requestKey, value, cacheDurationMs);
8245
+ }), catchError((error) => {
8246
+ logger.warn('HTTP condition request failed:', error);
8247
+ return of(pendingValue);
8248
+ }));
8249
+ },
8250
+ defaultValue: pendingValue,
8251
+ injector,
8252
+ });
8253
+ // Snapshot composition: preserve the previous boolean result during re-fetching.
8254
+ // Without this, the condition would briefly flash to pendingValue when params change,
8255
+ // causing visible UI flicker (e.g., a conditionally visible field briefly disappearing).
8256
+ return withPreviousValue(httpResource);
8328
8257
  });
8329
- signalPair = { resolvedRequest, resultValue };
8258
+ signalPair = { resolvedRequest, resultResource };
8330
8259
  perFunctionSignalStore.set(contextKey, signalPair);
8331
8260
  }
8332
8261
  // Build reactive evaluation context (creates signal dependencies on form values)
@@ -8334,7 +8263,7 @@ function createHttpConditionLogicFunction(condition) {
8334
8263
  // Returns null when a path param is undefined — skip the request and return pending value
8335
8264
  const resolved = resolveHttpRequest(condition.http, evaluationContext);
8336
8265
  if (!resolved) {
8337
- return signalPair.resultValue();
8266
+ return signalPair.resultResource.value();
8338
8267
  }
8339
8268
  const requestKey = stableStringify(resolved);
8340
8269
  // Check response cache first
@@ -8342,15 +8271,15 @@ function createHttpConditionLogicFunction(condition) {
8342
8271
  if (cachedResult !== undefined) {
8343
8272
  return cachedResult;
8344
8273
  }
8345
- // Update the resolved request signal (triggers pipeline if request changed)
8346
- const { resolvedRequest, resultValue } = signalPair;
8274
+ // Update the resolved request signal (triggers resource if request changed)
8275
+ const { resolvedRequest, resultResource } = signalPair;
8347
8276
  untracked(() => {
8348
8277
  const current = resolvedRequest();
8349
8278
  if (stableStringify(current) !== requestKey) {
8350
8279
  resolvedRequest.set(resolved);
8351
8280
  }
8352
8281
  });
8353
- return resultValue();
8282
+ return resultResource.value();
8354
8283
  };
8355
8284
  cacheService.httpConditionFunctionCache.set(cacheKey, fn);
8356
8285
  return fn;
@@ -8374,10 +8303,11 @@ class AsyncConditionFunctionCacheService {
8374
8303
  /**
8375
8304
  * Creates a logic function for an async condition.
8376
8305
  *
8377
- * Uses a signal-based async resolution pattern: the LogicFn updates a `trigger` signal,
8378
- * a reactive pipeline calls the async function and updates a `resultValue` signal.
8379
- * The LogicFn returns the current `resultValue()`, which starts as `pendingValue` and
8380
- * transitions to the actual async result.
8306
+ * Uses Angular's `rxResource()` API with snapshot composition for async resolution:
8307
+ * the LogicFn updates a `trigger` signal (serialized evaluation context), a debounced
8308
+ * version feeds into an `rxResource()` that manages the async function lifecycle, and
8309
+ * `withPreviousValue()` preserves the last resolved boolean during re-evaluation
8310
+ * to prevent UI flicker.
8381
8311
  *
8382
8312
  * Must be called in injection context (same as `createLogicFunction`).
8383
8313
  */
@@ -8401,33 +8331,53 @@ function createAsyncConditionLogicFunction(condition) {
8401
8331
  const contextKey = safeReadPathKeys(ctx).join('.');
8402
8332
  let signalPair = perFunctionSignalStore.get(contextKey);
8403
8333
  if (!signalPair) {
8404
- const trigger = signal(undefined, ...(ngDevMode ? [{ debugName: "trigger" }] : []));
8405
- // Wrap in untracked() to avoid NG0602: toObservable() internally calls effect(),
8334
+ const trigger = signal(undefined, ...(ngDevMode ? [{ debugName: "trigger" }] : /* istanbul ignore next */ []));
8335
+ const ctxByTrigger = new Map();
8336
+ // Wrap in untracked() to avoid NG0602: resource() internally creates effects,
8406
8337
  // which cannot be created inside a reactive context (computed). The LogicFn runs
8407
8338
  // inside Angular Signal Forms' BooleanOrLogic.compute (a computed), so we must
8408
- // clear the active reactive consumer before creating the observable pipeline.
8409
- const resultValue = untracked(() => {
8410
- const pipeline = toObservable(trigger, { injector }).pipe(debounceTime(debounceMs), distinctUntilChanged(), filter((value) => value !== undefined), switchMap$1(() => {
8411
- // Look up the async function at call time (fresh reference)
8412
- const asyncFn = functionRegistry.getAsyncConditionFunction(condition.asyncFunctionName);
8413
- if (!asyncFn) {
8414
- logger.warn(`Async Condition - function '${condition.asyncFunctionName}' not found. ` +
8415
- `Register it in customFnConfig.asyncConditions.`);
8416
- return of(pendingValue);
8417
- }
8418
- // Build evaluation context from current registry state
8419
- const evaluationContext = untracked(() => fieldContextRegistry.createReactiveEvaluationContext(ctx, functionRegistry.getCustomFunctions()));
8420
- // concat ensures pendingValue is emitted immediately when a new trigger
8421
- // arrives, before the async call resolves. This prevents the signal from
8422
- // showing a stale resolved value during re-evaluation.
8423
- return concat(of(pendingValue), from(asyncFn(evaluationContext)).pipe(map$1((result) => !!result), catchError((error) => {
8424
- logger.warn('Async Condition - function failed:', error);
8425
- return of(pendingValue);
8426
- })));
8427
- }));
8428
- return toSignal(pipeline, { injector, initialValue: pendingValue });
8339
+ // clear the active reactive consumer before creating the resource pipeline.
8340
+ const resultResource = untracked(() => {
8341
+ // Debounce the trigger to batch rapid form value changes.
8342
+ const debouncedTrigger = derivedFromDeferred(trigger, pipe(debounceTime(debounceMs), distinctUntilChanged()), {
8343
+ initialValue: undefined,
8344
+ injector,
8345
+ });
8346
+ // rxResource() manages the async function lifecycle natively with Observables:
8347
+ // auto-cancellation via unsubscription and signal-based reactivity.
8348
+ const asyncResource = rxResource({
8349
+ params: () => debouncedTrigger() ?? undefined,
8350
+ stream: ({ params: triggerKey }) => {
8351
+ // Look up the async function at call time (fresh reference)
8352
+ const asyncFn = functionRegistry.getAsyncConditionFunction(condition.asyncFunctionName);
8353
+ if (!asyncFn) {
8354
+ logger.warn(`Async Condition - function '${condition.asyncFunctionName}' not found. ` +
8355
+ `Register it in customFnConfig.asyncConditions.`);
8356
+ return of(pendingValue);
8357
+ }
8358
+ // Retrieve the FieldContext that was captured when this trigger key was set.
8359
+ // This avoids a race condition where a mutable ref could be overwritten by
8360
+ // a later LogicFn call before the loader finishes executing.
8361
+ const capturedCtx = ctxByTrigger.get(triggerKey);
8362
+ if (!capturedCtx)
8363
+ return of(pendingValue);
8364
+ const evaluationContext = untracked(() => fieldContextRegistry.createReactiveEvaluationContext(capturedCtx, functionRegistry.getCustomFunctions()));
8365
+ // asyncFn may return Promise<boolean> or Observable<boolean>.
8366
+ // from() normalizes both to Observable.
8367
+ return from(asyncFn(evaluationContext)).pipe(map$1((result) => !!result), catchError((error) => {
8368
+ logger.warn('Async Condition - function failed:', error);
8369
+ return of(pendingValue);
8370
+ }));
8371
+ },
8372
+ defaultValue: pendingValue,
8373
+ injector,
8374
+ });
8375
+ // Snapshot composition: preserve the previous boolean result during re-evaluation.
8376
+ // Without this, the condition would briefly flash to pendingValue when the async
8377
+ // function is re-invoked, causing visible UI flicker.
8378
+ return withPreviousValue(asyncResource);
8429
8379
  });
8430
- signalPair = { trigger, resultValue };
8380
+ signalPair = { trigger, resultResource, ctxByTrigger };
8431
8381
  perFunctionSignalStore.set(contextKey, signalPair);
8432
8382
  }
8433
8383
  // Build reactive evaluation context (creates signal dependencies on form values)
@@ -8438,15 +8388,18 @@ function createAsyncConditionLogicFunction(condition) {
8438
8388
  fieldValue: evaluationContext.fieldValue,
8439
8389
  externalData: evaluationContext.externalData,
8440
8390
  });
8441
- // Update the trigger signal (triggers pipeline if context changed)
8442
- const { trigger: triggerSignal, resultValue } = signalPair;
8391
+ // Capture the FieldContext for this trigger key so the loader can retrieve it.
8392
+ // Only keep the latest — previous entries are stale once the trigger changes.
8393
+ const { trigger: triggerSignal, resultResource, ctxByTrigger } = signalPair;
8394
+ ctxByTrigger.clear();
8395
+ ctxByTrigger.set(contextSnapshot, ctx);
8443
8396
  untracked(() => {
8444
8397
  const current = triggerSignal();
8445
8398
  if (current !== contextSnapshot) {
8446
8399
  triggerSignal.set(contextSnapshot);
8447
8400
  }
8448
8401
  });
8449
- return resultValue();
8402
+ return resultResource.value();
8450
8403
  };
8451
8404
  cacheService.asyncConditionFunctionCache.set(cacheKey, fn);
8452
8405
  return fn;
@@ -8574,7 +8527,7 @@ function createDebouncedLogicFunction(expression, debounceMs) {
8574
8527
  let signalPair = cacheService.debouncedSignalStore.get(contextKey);
8575
8528
  if (!signalPair) {
8576
8529
  // Create a signal to hold the immediate evaluation result
8577
- const immediateValue = signal(false, ...(ngDevMode ? [{ debugName: "immediateValue" }] : []));
8530
+ const immediateValue = signal(false, ...(ngDevMode ? [{ debugName: "immediateValue" }] : /* istanbul ignore next */ []));
8578
8531
  // Wrap in untracked() to avoid NG0602: toObservable() internally calls effect(),
8579
8532
  // which cannot be created inside a reactive context (computed). The LogicFn runs
8580
8533
  // inside Angular Signal Forms' BooleanOrLogic.compute (a computed).
@@ -8758,22 +8711,6 @@ function applyValidator(config, fieldPath) {
8758
8711
  case 'async':
8759
8712
  applyAsyncValidator(config, path);
8760
8713
  break;
8761
- case 'customAsync': {
8762
- // TODO(@ng-forge): remove deprecated code in next minor
8763
- const logger = inject(DynamicFormLogger);
8764
- const tracker = inject(DEPRECATION_WARNING_TRACKER);
8765
- warnDeprecated(logger, tracker, 'type:customAsync', "Validator type 'customAsync' is deprecated. Use type: 'async' instead.");
8766
- applyAsyncValidator(config, path);
8767
- break;
8768
- }
8769
- case 'customHttp': {
8770
- // TODO(@ng-forge): remove deprecated code in next minor
8771
- const logger = inject(DynamicFormLogger);
8772
- const tracker = inject(DEPRECATION_WARNING_TRACKER);
8773
- warnDeprecated(logger, tracker, 'type:customHttp', "Validator type 'customHttp' is deprecated. Use type: 'http' with functionName instead.");
8774
- applyFunctionHttpValidator(config, path);
8775
- break;
8776
- }
8777
8714
  case 'http':
8778
8715
  applyUnifiedHttpValidator(config, path);
8779
8716
  break;
@@ -8979,8 +8916,8 @@ function getConfigDebounceMs(config) {
8979
8916
  return undefined;
8980
8917
  }
8981
8918
  function applyLogic(config, fieldPath) {
8982
- // Value derivations and property derivations are handled by their respective orchestrators — skip them.
8983
- if (isDerivationLogicConfig(config) || isPropertyDerivationLogicConfig(config))
8919
+ // Value derivations (including property derivations via targetProperty) are handled by their orchestrators — skip them.
8920
+ if (isDerivationLogicConfig(config))
8984
8921
  return;
8985
8922
  // Guard against unrecognized logic types that may be added in the future.
8986
8923
  if (!isStateLogicConfig(config)) {
@@ -9017,6 +8954,10 @@ function applyLogicFn(type, path, logicFn) {
9017
8954
  case 'required':
9018
8955
  required(path, { when: logicFn });
9019
8956
  break;
8957
+ default: {
8958
+ const _exhaustive = type;
8959
+ throw new DynamicFormError(`Unhandled state logic type: ${_exhaustive}`);
8960
+ }
9020
8961
  }
9021
8962
  }
9022
8963
  function applyMultipleLogic(configs, fieldPath) {
@@ -9027,7 +8968,7 @@ function applyMultipleLogic(configs, fieldPath) {
9027
8968
  * Create a type predicate function from a predicate string.
9028
8969
  *
9029
8970
  * Uses the secure ExpressionParser with whitelist-based evaluation instead of
9030
- * new Function() / eval. This provides security through:
8971
+ * dynamic code execution. This provides security through:
9031
8972
  * - AST-based parsing (no code execution)
9032
8973
  * - Whitelisted operators only
9033
8974
  * - Whitelisted methods only (Array.isArray, typeof, instanceof, etc.)
@@ -10353,17 +10294,25 @@ function flattenFields(fields, registry, options = {}) {
10353
10294
  * @returns Object containing memoized processing functions
10354
10295
  */
10355
10296
  function createContainerFieldProcessors() {
10297
+ const createFieldsResolver = (preserveRows = false) => (fields, registry) => {
10298
+ let key = '';
10299
+ for (const f of fields) {
10300
+ key += (f.key ?? '') + ':' + (f.type ?? '') + '|';
10301
+ }
10302
+ return key + registry.size + '|' + preserveRows;
10303
+ };
10356
10304
  const memoizedFlattenFields = memoize((fields, registry) => flattenFields([...fields], registry), {
10357
10305
  // registry.size is a valid cache key proxy because the field registry is populated
10358
10306
  // once at bootstrap and never mutated at runtime. If the registry were mutable,
10359
10307
  // we would need a content-based hash instead.
10360
- resolver: (fields, registry) => {
10361
- let key = '';
10362
- for (const f of fields) {
10363
- key += (f.key ?? '') + ':' + (f.type ?? '') + '|';
10364
- }
10365
- return key + registry.size;
10366
- },
10308
+ resolver: createFieldsResolver(),
10309
+ maxSize: 10,
10310
+ });
10311
+ const memoizedFlattenFieldsForRendering = memoize((fields, registry) => flattenFields([...fields], registry, { preserveRows: true }), {
10312
+ // registry.size is a valid cache key proxy because the field registry is populated
10313
+ // once at bootstrap and never mutated at runtime. If the registry were mutable,
10314
+ // we would need a content-based hash instead.
10315
+ resolver: createFieldsResolver(true),
10367
10316
  maxSize: 10,
10368
10317
  });
10369
10318
  const memoizedKeyBy = memoize((fields) => keyBy(fields, 'key'), {
@@ -10385,7 +10334,7 @@ function createContainerFieldProcessors() {
10385
10334
  },
10386
10335
  maxSize: 10,
10387
10336
  });
10388
- return { memoizedFlattenFields, memoizedKeyBy, memoizedDefaultValues };
10337
+ return { memoizedFlattenFields, memoizedFlattenFieldsForRendering, memoizedKeyBy, memoizedDefaultValues };
10389
10338
  }
10390
10339
  /**
10391
10340
  * Shared container field processors injection token.
@@ -10407,50 +10356,6 @@ const CONTAINER_FIELD_PROCESSORS = new InjectionToken('CONTAINER_FIELD_PROCESSOR
10407
10356
  factory: () => createContainerFieldProcessors(),
10408
10357
  });
10409
10358
 
10410
- /**
10411
- * Type guard to check if a value is an array of Signals.
10412
- * @internal
10413
- */
10414
- function isSignalArray(value) {
10415
- return Array.isArray(value) && value.every((item) => isSignal(item));
10416
- }
10417
- /**
10418
- * Type guard to check if a value is a record (object) of Signals.
10419
- * @internal
10420
- */
10421
- function isSignalRecord(value) {
10422
- return typeof value === 'object' && value !== null && !Array.isArray(value) && Object.values(value).every((item) => isSignal(item));
10423
- }
10424
- // Implementation
10425
- function derivedFromDeferred(source, operator, options) {
10426
- const deferred$ = defer(() => {
10427
- // Handle single signal
10428
- if (isSignal(source)) {
10429
- return toObservable(source, { injector: options.injector });
10430
- }
10431
- // Handle array of signals
10432
- if (isSignalArray(source)) {
10433
- const observables = source.map((s) => toObservable(s, { injector: options.injector }));
10434
- return combineLatest(observables);
10435
- }
10436
- // Handle object of signals
10437
- if (isSignalRecord(source)) {
10438
- const keys = Object.keys(source);
10439
- const observables = keys.map((key) => toObservable(source[key], { injector: options.injector }));
10440
- return combineLatest(observables, (...values) => {
10441
- const result = {};
10442
- keys.forEach((key, index) => {
10443
- result[key] = values[index];
10444
- });
10445
- return result;
10446
- });
10447
- }
10448
- // Fallback - should not happen with proper typing
10449
- throw new Error('Invalid source type. Expected a Signal, array of Signals, or object of Signals.');
10450
- }).pipe(operator);
10451
- return toSignal(deferred$, { initialValue: options.initialValue, injector: options.injector });
10452
- }
10453
-
10454
10359
  /**
10455
10360
  * Generates CSS class string for responsive grid layout based on field column configuration.
10456
10361
  *
@@ -11802,7 +11707,7 @@ class FormStateMachine {
11802
11707
  }
11803
11708
  constructor(config) {
11804
11709
  this.config = config;
11805
- this._state = signal(createUninitializedState(), ...(ngDevMode ? [{ debugName: "_state" }] : []));
11710
+ this._state = signal(createUninitializedState(), ...(ngDevMode ? [{ debugName: "_state" }] : /* istanbul ignore next */ []));
11806
11711
  this.state = this._state.asReadonly();
11807
11712
  this.state$ = toObservable(this._state, { injector: config.injector });
11808
11713
  this.setupActionProcessing();
@@ -12076,7 +11981,6 @@ class FormStateManager {
12076
11981
  injector = inject(Injector);
12077
11982
  destroyRef = inject(DestroyRef);
12078
11983
  logger = inject(DynamicFormLogger);
12079
- deprecationTracker = inject(DEPRECATION_WARNING_TRACKER, { optional: true });
12080
11984
  eventBus = inject(EventBus);
12081
11985
  functionRegistry = inject(FunctionRegistryService);
12082
11986
  schemaRegistry = inject(SchemaRegistryService);
@@ -12103,26 +12007,13 @@ class FormStateManager {
12103
12007
  // Memoized Functions
12104
12008
  // ─────────────────────────────────────────────────────────────────────────────
12105
12009
  fieldProcessors = inject(CONTAINER_FIELD_PROCESSORS);
12106
- memoizedFlattenFieldsForRendering = memoize((fields, registry) => flattenFields(fields, registry, { preserveRows: true }), {
12107
- // registry.size is a valid cache key proxy because the field registry is populated
12108
- // once at bootstrap and never mutated at runtime. If the registry were mutable,
12109
- // we would need a content-based hash instead.
12110
- resolver: (fields, registry) => {
12111
- let key = '';
12112
- for (const f of fields) {
12113
- key += (f.key ?? '') + ':' + (f.type ?? '') + '|';
12114
- }
12115
- return key + registry.size;
12116
- },
12117
- maxSize: 10,
12118
- });
12119
12010
  // ─────────────────────────────────────────────────────────────────────────────
12120
12011
  // Internal State Signals
12121
12012
  // ─────────────────────────────────────────────────────────────────────────────
12122
12013
  /**
12123
12014
  * Field loading errors accumulated during resolution.
12124
12015
  */
12125
- fieldLoadingErrors = signal([], ...(ngDevMode ? [{ debugName: "fieldLoadingErrors" }] : []));
12016
+ fieldLoadingErrors = signal([], ...(ngDevMode ? [{ debugName: "fieldLoadingErrors" }] : /* istanbul ignore next */ []));
12126
12017
  /**
12127
12018
  * Class-level form cache for the "hold until settled" pattern.
12128
12019
  * MUST be class-level — a local variable in the computed would reset on re-evaluation.
@@ -12153,7 +12044,7 @@ class FormStateManager {
12153
12044
  if (state.type === LifecycleState.Initializing)
12154
12045
  return state.config;
12155
12046
  return undefined;
12156
- }, ...(ngDevMode ? [{ debugName: "activeConfig" }] : []));
12047
+ }, ...(ngDevMode ? [{ debugName: "activeConfig" }] : /* istanbul ignore next */ []));
12157
12048
  /**
12158
12049
  * Current render phase: 'render' = showing form, 'teardown' = hiding old components.
12159
12050
  */
@@ -12162,9 +12053,9 @@ class FormStateManager {
12162
12053
  if (isTransitioningState(state) && state.phase === Phase.Teardown)
12163
12054
  return Phase.Teardown;
12164
12055
  return 'render';
12165
- }, ...(ngDevMode ? [{ debugName: "renderPhase" }] : []));
12056
+ }, ...(ngDevMode ? [{ debugName: "renderPhase" }] : /* istanbul ignore next */ []));
12166
12057
  /** Whether to render the form template. */
12167
- shouldRender = computed(() => this.activeConfig() !== undefined, ...(ngDevMode ? [{ debugName: "shouldRender" }] : []));
12058
+ shouldRender = computed(() => this.activeConfig() !== undefined, ...(ngDevMode ? [{ debugName: "shouldRender" }] : /* istanbul ignore next */ []));
12168
12059
  /**
12169
12060
  * Computed form mode detection with validation.
12170
12061
  */
@@ -12174,14 +12065,14 @@ class FormStateManager {
12174
12065
  return { mode: 'non-paged', isValid: true, errors: [] };
12175
12066
  }
12176
12067
  return detectFormMode(config.fields || []);
12177
- }, ...(ngDevMode ? [{ debugName: "formModeDetection" }] : []));
12068
+ }, ...(ngDevMode ? [{ debugName: "formModeDetection" }] : /* istanbul ignore next */ []));
12178
12069
  /** Validation result for the current form configuration. */
12179
12070
  formConfigValidation = computed(() => {
12180
12071
  const config = this.activeConfig();
12181
12072
  if (!config)
12182
12073
  return { isValid: true, errors: [], warnings: [] };
12183
12074
  return FormModeValidator.validateFormConfiguration(config.fields || []);
12184
- }, ...(ngDevMode ? [{ debugName: "formConfigValidation" }] : []));
12075
+ }, ...(ngDevMode ? [{ debugName: "formConfigValidation" }] : /* istanbul ignore next */ []));
12185
12076
  /**
12186
12077
  * Effective form options (merged from config and input).
12187
12078
  */
@@ -12190,7 +12081,7 @@ class FormStateManager {
12190
12081
  const configOptions = config?.options || {};
12191
12082
  const inputOptions = this.deps.formOptions() ?? undefined;
12192
12083
  return { ...configOptions, ...inputOptions };
12193
- }, ...(ngDevMode ? [{ debugName: "effectiveFormOptions" }] : []));
12084
+ }, ...(ngDevMode ? [{ debugName: "effectiveFormOptions" }] : /* istanbul ignore next */ []));
12194
12085
  /**
12195
12086
  * Page field definitions (for paged forms).
12196
12087
  */
@@ -12201,11 +12092,11 @@ class FormStateManager {
12201
12092
  return config.fields.filter(isPageField);
12202
12093
  }
12203
12094
  return [];
12204
- }, ...(ngDevMode ? [{ debugName: "pageFieldDefinitions" }] : []));
12095
+ }, ...(ngDevMode ? [{ debugName: "pageFieldDefinitions" }] : /* istanbul ignore next */ []));
12205
12096
  // ─────────────────────────────────────────────────────────────────────────────
12206
12097
  // Computed Signals - Form Setup
12207
12098
  // ─────────────────────────────────────────────────────────────────────────────
12208
- rawFieldRegistry = computed(() => this.fieldRegistry.raw, ...(ngDevMode ? [{ debugName: "rawFieldRegistry" }] : []));
12099
+ rawFieldRegistry = computed(() => this.fieldRegistry.raw, ...(ngDevMode ? [{ debugName: "rawFieldRegistry" }] : /* istanbul ignore next */ []));
12209
12100
  /** Computed form setup — reads from the state machine, computed from config on bootstrap. */
12210
12101
  formSetup = computed(() => {
12211
12102
  const registry = this.rawFieldRegistry();
@@ -12236,18 +12127,18 @@ class FormStateManager {
12236
12127
  return this.createFormSetupFromConfig(config.fields, modeDetection.mode, registry);
12237
12128
  }
12238
12129
  return this.createEmptyFormSetup(registry);
12239
- }, ...(ngDevMode ? [{ debugName: "formSetup" }] : []));
12130
+ }, ...(ngDevMode ? [{ debugName: "formSetup" }] : /* istanbul ignore next */ []));
12240
12131
  /**
12241
12132
  * Default values computed from field definitions.
12242
12133
  */
12243
- defaultValues = linkedSignal(() => this.formSetup().defaultValues, ...(ngDevMode ? [{ debugName: "defaultValues" }] : []));
12134
+ defaultValues = linkedSignal(() => this.formSetup().defaultValues, ...(ngDevMode ? [{ debugName: "defaultValues" }] : /* istanbul ignore next */ []));
12244
12135
  /** Valid field keys — memoized separately so the Set isn't rebuilt on every keystroke. */
12245
12136
  validKeys = computed(() => {
12246
12137
  const schemaFields = this.formSetup().schemaFields;
12247
12138
  if (!schemaFields || schemaFields.length === 0)
12248
12139
  return undefined;
12249
12140
  return new Set(schemaFields.map((f) => f.key).filter((key) => key !== undefined));
12250
- }, ...(ngDevMode ? [{ debugName: "validKeys" }] : []));
12141
+ }, ...(ngDevMode ? [{ debugName: "validKeys" }] : /* istanbul ignore next */ []));
12251
12142
  // ─────────────────────────────────────────────────────────────────────────────
12252
12143
  // Computed Signals - Entity & Form
12253
12144
  // ─────────────────────────────────────────────────────────────────────────────
@@ -12307,7 +12198,7 @@ class FormStateManager {
12307
12198
  return createFormLevelSchema(config.schema);
12308
12199
  }
12309
12200
  return undefined;
12310
- }), ...(ngDevMode ? [{ debugName: "formSchema" }] : []));
12201
+ }), ...(ngDevMode ? [{ debugName: "formSchema" }] : /* istanbul ignore next */ []));
12311
12202
  /**
12312
12203
  * The Angular Signal Form instance.
12313
12204
  */
@@ -12315,7 +12206,7 @@ class FormStateManager {
12315
12206
  const schema = this.formSchema();
12316
12207
  const injector = this.injector;
12317
12208
  return untracked(() => (schema ? form(this.entity, schema, { injector }) : form(this.entity, { injector })));
12318
- }, ...(ngDevMode ? [{ debugName: "form" }] : []));
12209
+ }, ...(ngDevMode ? [{ debugName: "form" }] : /* istanbul ignore next */ []));
12319
12210
  /** Whether resolvedFields has caught up with fieldsSource (set in constructor). */
12320
12211
  isFieldPipelineSettled;
12321
12212
  /**
@@ -12342,14 +12233,14 @@ class FormStateManager {
12342
12233
  return currentForm;
12343
12234
  },
12344
12235
  };
12345
- }, ...(ngDevMode ? [{ debugName: "fieldSignalContext" }] : []));
12236
+ }, ...(ngDevMode ? [{ debugName: "fieldSignalContext" }] : /* istanbul ignore next */ []));
12346
12237
  // ─────────────────────────────────────────────────────────────────────────────
12347
12238
  // Computed Signals - Form State
12348
12239
  // ─────────────────────────────────────────────────────────────────────────────
12349
12240
  /** Intermediate computed that unwraps the double-signal (form()()) once. */
12350
- formInstance = computed(() => this.form()(), ...(ngDevMode ? [{ debugName: "formInstance" }] : []));
12241
+ formInstance = computed(() => this.form()(), ...(ngDevMode ? [{ debugName: "formInstance" }] : /* istanbul ignore next */ []));
12351
12242
  /** Current form values (reactive). */
12352
- formValue = computed(() => this.formInstance().value(), ...(ngDevMode ? [{ debugName: "formValue" }] : []));
12243
+ formValue = computed(() => this.formInstance().value(), ...(ngDevMode ? [{ debugName: "formValue" }] : /* istanbul ignore next */ []));
12353
12244
  /**
12354
12245
  * Form values filtered by value exclusion rules.
12355
12246
  *
@@ -12379,25 +12270,25 @@ class FormStateManager {
12379
12270
  // FieldTree doesn't expose this index signature, so we use a helper cast.
12380
12271
  const fieldTreeRecord = asFieldTreeRecord(formTree);
12381
12272
  return filterFormValue(rawValue, setup.schemaFields, fieldTreeRecord, setup.registry, this.valueExclusionDefaults, formOptions);
12382
- }, ...(ngDevMode ? [{ debugName: "filteredFormValue" }] : []));
12273
+ }, ...(ngDevMode ? [{ debugName: "filteredFormValue" }] : /* istanbul ignore next */ []));
12383
12274
  /** Whether the form is currently valid. */
12384
- valid = computed(() => this.formInstance().valid(), ...(ngDevMode ? [{ debugName: "valid" }] : []));
12275
+ valid = computed(() => this.formInstance().valid(), ...(ngDevMode ? [{ debugName: "valid" }] : /* istanbul ignore next */ []));
12385
12276
  /** Whether the form is currently invalid. */
12386
- invalid = computed(() => this.formInstance().invalid(), ...(ngDevMode ? [{ debugName: "invalid" }] : []));
12277
+ invalid = computed(() => this.formInstance().invalid(), ...(ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []));
12387
12278
  /** Whether any form field has been modified. */
12388
- dirty = computed(() => this.formInstance().dirty(), ...(ngDevMode ? [{ debugName: "dirty" }] : []));
12279
+ dirty = computed(() => this.formInstance().dirty(), ...(ngDevMode ? [{ debugName: "dirty" }] : /* istanbul ignore next */ []));
12389
12280
  /** Whether any form field has been touched (blurred). */
12390
- touched = computed(() => this.formInstance().touched(), ...(ngDevMode ? [{ debugName: "touched" }] : []));
12281
+ touched = computed(() => this.formInstance().touched(), ...(ngDevMode ? [{ debugName: "touched" }] : /* istanbul ignore next */ []));
12391
12282
  /** Current validation errors from all fields. */
12392
- errors = computed(() => this.formInstance().errors(), ...(ngDevMode ? [{ debugName: "errors" }] : []));
12283
+ errors = computed(() => this.formInstance().errors(), ...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
12393
12284
  /** Whether the form is disabled (from options or form state). */
12394
12285
  disabled = computed(() => {
12395
12286
  const optionsDisabled = this.effectiveFormOptions().disabled;
12396
12287
  const formDisabled = this.formInstance().disabled();
12397
12288
  return optionsDisabled ?? formDisabled;
12398
- }, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
12289
+ }, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
12399
12290
  /** Whether the form is currently submitting. */
12400
- submitting = computed(() => this.formInstance().submitting(), ...(ngDevMode ? [{ debugName: "submitting" }] : []));
12291
+ submitting = computed(() => this.formInstance().submitting(), ...(ngDevMode ? [{ debugName: "submitting" }] : /* istanbul ignore next */ []));
12401
12292
  // ─────────────────────────────────────────────────────────────────────────────
12402
12293
  // Field Resolution
12403
12294
  // ─────────────────────────────────────────────────────────────────────────────
@@ -12420,7 +12311,7 @@ class FormStateManager {
12420
12311
  }
12421
12312
  }
12422
12313
  return this.formSetup().fields;
12423
- }, { ...(ngDevMode ? { debugName: "fieldsSource" } : {}), equal: (a, b) => {
12314
+ }, { ...(ngDevMode ? { debugName: "fieldsSource" } : /* istanbul ignore next */ {}), equal: (a, b) => {
12424
12315
  if (a === b)
12425
12316
  return true;
12426
12317
  if (a.length !== b.length)
@@ -12439,7 +12330,7 @@ class FormStateManager {
12439
12330
  fieldInjector = computed(() => Injector.create({
12440
12331
  parent: this.injector,
12441
12332
  providers: [{ provide: FIELD_SIGNAL_CONTEXT, useValue: this.fieldSignalContext() }],
12442
- }), ...(ngDevMode ? [{ debugName: "fieldInjector" }] : []));
12333
+ }), ...(ngDevMode ? [{ debugName: "fieldInjector" }] : /* istanbul ignore next */ []));
12443
12334
  /** Resolved fields ready for rendering. */
12444
12335
  resolvedFields;
12445
12336
  // ─────────────────────────────────────────────────────────────────────────────
@@ -12519,7 +12410,7 @@ class FormStateManager {
12519
12410
  // fieldsSource changes atomically during transitions (lengths won't match until settled).
12520
12411
  this.isFieldPipelineSettled = computed(() => {
12521
12412
  return this.fieldsSource().length === this.resolvedFields().length;
12522
- }, ...(ngDevMode ? [{ debugName: "isFieldPipelineSettled" }] : []));
12413
+ }, ...(ngDevMode ? [{ debugName: "isFieldPipelineSettled" }] : /* istanbul ignore next */ []));
12523
12414
  this.submitted$ = this.eventBus.on('submit').pipe(filter(() => {
12524
12415
  if (!this.valid()) {
12525
12416
  this.logger.debug('Form submitted while invalid, not emitting to (submitted) output');
@@ -12667,13 +12558,6 @@ class FormStateManager {
12667
12558
  if (customFnConfig.derivations) {
12668
12559
  this.functionRegistry.setDerivationFunctions(customFnConfig.derivations);
12669
12560
  }
12670
- // TODO(@ng-forge): remove deprecated code in next minor
12671
- if (customFnConfig.propertyDerivations) {
12672
- if (this.deprecationTracker) {
12673
- warnDeprecated(this.logger, this.deprecationTracker, 'customFnConfig:propertyDerivations', "customFnConfig.propertyDerivations is deprecated. Register functions under 'derivations' instead and use type: 'derivation' with targetProperty.");
12674
- }
12675
- this.functionRegistry.setPropertyDerivationFunctions(customFnConfig.propertyDerivations);
12676
- }
12677
12561
  if (customFnConfig.asyncDerivations) {
12678
12562
  this.functionRegistry.setAsyncDerivationFunctions(customFnConfig.asyncDerivations);
12679
12563
  }
@@ -12682,10 +12566,6 @@ class FormStateManager {
12682
12566
  }
12683
12567
  this.functionRegistry.setValidators(customFnConfig.validators);
12684
12568
  this.functionRegistry.setAsyncValidators(customFnConfig.asyncValidators);
12685
- // TODO(@ng-forge): remove deprecated code in next minor
12686
- if (customFnConfig.httpValidators && this.deprecationTracker) {
12687
- warnDeprecated(this.logger, this.deprecationTracker, 'customFnConfig:httpValidators', "customFnConfig.httpValidators registration path is deprecated. Use type: 'http' with functionName (for function-based) or http + responseMapping (for declarative).");
12688
- }
12689
12569
  this.functionRegistry.setHttpValidators(customFnConfig.httpValidators);
12690
12570
  }
12691
12571
  createFormSetupFromConfig(fields, mode, registry) {
@@ -12694,7 +12574,7 @@ class FormStateManager {
12694
12574
  // into full ArrayField.fields and are reachable during traversal.
12695
12575
  validateFormConfig(normalizedFields, registry, this.logger);
12696
12576
  const flattenedFields = this.fieldProcessors.memoizedFlattenFields(normalizedFields, registry);
12697
- const flattenedFieldsForRendering = this.memoizedFlattenFieldsForRendering(normalizedFields, registry);
12577
+ const flattenedFieldsForRendering = this.fieldProcessors.memoizedFlattenFieldsForRendering(normalizedFields, registry);
12698
12578
  const fieldsById = this.fieldProcessors.memoizedKeyBy(flattenedFields);
12699
12579
  const defaultValues = this.fieldProcessors.memoizedDefaultValues(fieldsById, registry);
12700
12580
  const fieldsToRender = mode === 'paged' ? [] : flattenedFieldsForRendering;
@@ -12722,10 +12602,10 @@ class FormStateManager {
12722
12602
  ngOnDestroy() {
12723
12603
  this.machine.dispatch({ type: Action.Destroy });
12724
12604
  }
12725
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FormStateManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
12726
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FormStateManager });
12605
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FormStateManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
12606
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FormStateManager });
12727
12607
  }
12728
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FormStateManager, decorators: [{
12608
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FormStateManager, decorators: [{
12729
12609
  type: Injectable
12730
12610
  }], ctorParameters: () => [] });
12731
12611
 
@@ -13126,10 +13006,10 @@ class EventDispatcher {
13126
13006
  disconnect() {
13127
13007
  this.bus = undefined;
13128
13008
  }
13129
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: EventDispatcher, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
13130
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: EventDispatcher });
13009
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EventDispatcher, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
13010
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EventDispatcher });
13131
13011
  }
13132
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: EventDispatcher, decorators: [{
13012
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EventDispatcher, decorators: [{
13133
13013
  type: Injectable
13134
13014
  }] });
13135
13015
 
@@ -13147,16 +13027,17 @@ class DynamicForm {
13147
13027
  // Inputs (must be declared BEFORE deps connection and stateManager injection)
13148
13028
  // ─────────────────────────────────────────────────────────────────────────────
13149
13029
  /** Form configuration defining the structure, validation, and behavior. */
13150
- config = input.required({ ...(ngDevMode ? { debugName: "config" } : {}), alias: 'dynamic-form' });
13030
+ config = input.required({ ...(ngDevMode ? { debugName: "config" } : /* istanbul ignore next */ {}), alias: 'dynamic-form' });
13151
13031
  /** Runtime form options that override config options when provided. */
13152
- formOptions = input(undefined, ...(ngDevMode ? [{ debugName: "formOptions" }] : []));
13032
+ formOptions = input(undefined, ...(ngDevMode ? [{ debugName: "formOptions" }] : /* istanbul ignore next */ []));
13153
13033
  /** Form values for two-way data binding. */
13154
- value = model(undefined, ...(ngDevMode ? [{ debugName: "value" }] : []));
13034
+ value = model(undefined, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
13155
13035
  // ─────────────────────────────────────────────────────────────────────────────
13156
13036
  // Dependencies
13157
13037
  // ─────────────────────────────────────────────────────────────────────────────
13158
13038
  destroyRef = inject(DestroyRef);
13159
13039
  injector = inject(Injector);
13040
+ environmentInjector = inject(EnvironmentInjector);
13160
13041
  eventBus = inject(EventBus);
13161
13042
  logger = inject(DynamicFormLogger);
13162
13043
  dispatcher = inject(EventDispatcher, { optional: true });
@@ -13221,7 +13102,7 @@ class DynamicForm {
13221
13102
  totalComponentsCount = computed(() => {
13222
13103
  const fields = this.stateManager.formSetup()?.fields ?? [];
13223
13104
  return countContainersRecursive(fields) + 1;
13224
- }, ...(ngDevMode ? [{ debugName: "totalComponentsCount" }] : []));
13105
+ }, ...(ngDevMode ? [{ debugName: "totalComponentsCount" }] : /* istanbul ignore next */ []));
13225
13106
  // ─────────────────────────────────────────────────────────────────────────────
13226
13107
  // Initialization
13227
13108
  // ─────────────────────────────────────────────────────────────────────────────
@@ -13338,28 +13219,54 @@ class DynamicForm {
13338
13219
  error: (err) => this.logger.error('Submission handler error', err),
13339
13220
  });
13340
13221
  }
13341
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DynamicForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
13342
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", 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: [provideDynamicFormDI()], ngImport: i0, template: `
13222
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: DynamicForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
13223
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", 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: [provideDynamicFormDI()], ngImport: i0, template: `
13343
13224
  @if (shouldRender()) {
13344
- @if (formModeDetection().mode === 'paged') {
13345
- <div page-orchestrator [pageFields]="pageFieldDefinitions()" [form]="form()" [fieldSignalContext]="fieldSignalContext()"></div>
13346
- } @else {
13347
- @for (field of resolvedFields(); track field.key) {
13348
- <ng-container *ngComponentOutlet="field.component; injector: field.injector; inputs: field.inputs()" />
13225
+ @switch (formModeDetection().mode) {
13226
+ @case ('paged') {
13227
+ <div page-orchestrator [pageFields]="pageFieldDefinitions()" [form]="form()" [fieldSignalContext]="fieldSignalContext()"></div>
13228
+ }
13229
+ @case ('non-paged') {
13230
+ @for (field of resolvedFields(); track field.key) {
13231
+ <ng-container
13232
+ *ngComponentOutlet="
13233
+ field.component;
13234
+ injector: field.injector;
13235
+ environmentInjector: environmentInjector;
13236
+ inputs: field.inputs()
13237
+ "
13238
+ />
13239
+ }
13240
+ }
13241
+ @default {
13242
+ never;
13349
13243
  }
13350
13244
  }
13351
13245
  }
13352
13246
  `, 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-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-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 });
13353
13247
  }
13354
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DynamicForm, decorators: [{
13248
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: DynamicForm, decorators: [{
13355
13249
  type: Component,
13356
13250
  args: [{ selector: 'form[dynamic-form]', imports: [NgComponentOutlet, PageOrchestratorComponent], template: `
13357
13251
  @if (shouldRender()) {
13358
- @if (formModeDetection().mode === 'paged') {
13359
- <div page-orchestrator [pageFields]="pageFieldDefinitions()" [form]="form()" [fieldSignalContext]="fieldSignalContext()"></div>
13360
- } @else {
13361
- @for (field of resolvedFields(); track field.key) {
13362
- <ng-container *ngComponentOutlet="field.component; injector: field.injector; inputs: field.inputs()" />
13252
+ @switch (formModeDetection().mode) {
13253
+ @case ('paged') {
13254
+ <div page-orchestrator [pageFields]="pageFieldDefinitions()" [form]="form()" [fieldSignalContext]="fieldSignalContext()"></div>
13255
+ }
13256
+ @case ('non-paged') {
13257
+ @for (field of resolvedFields(); track field.key) {
13258
+ <ng-container
13259
+ *ngComponentOutlet="
13260
+ field.component;
13261
+ injector: field.injector;
13262
+ environmentInjector: environmentInjector;
13263
+ inputs: field.inputs()
13264
+ "
13265
+ />
13266
+ }
13267
+ }
13268
+ @default {
13269
+ never;
13363
13270
  }
13364
13271
  }
13365
13272
  }
@@ -13926,13 +13833,13 @@ const BUILT_IN_FIELDS = [
13926
13833
  },
13927
13834
  {
13928
13835
  name: 'page',
13929
- loadComponent: () => import('./ng-forge-dynamic-forms-page-field.component-D6M_uJKu.mjs'),
13836
+ loadComponent: () => import('./ng-forge-dynamic-forms-page-field.component-Cen4ArED.mjs'),
13930
13837
  mapper: pageFieldMapper,
13931
13838
  valueHandling: 'flatten',
13932
13839
  },
13933
13840
  {
13934
13841
  name: 'text',
13935
- loadComponent: () => import('./ng-forge-dynamic-forms-text-field.component-Ael-STTb.mjs'),
13842
+ loadComponent: () => import('./ng-forge-dynamic-forms-text-field.component-cE1EUmYR.mjs'),
13936
13843
  mapper: textFieldMapper,
13937
13844
  valueHandling: 'exclude',
13938
13845
  },
@@ -14698,14 +14605,13 @@ class DynamicTextPipe {
14698
14605
  }
14699
14606
  return of(value || '');
14700
14607
  }
14701
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DynamicTextPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
14702
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DynamicTextPipe, isStandalone: true, name: "dynamicText" });
14608
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: DynamicTextPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
14609
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.6", ngImport: i0, type: DynamicTextPipe, isStandalone: true, name: "dynamicText" });
14703
14610
  }
14704
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DynamicTextPipe, decorators: [{
14611
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: DynamicTextPipe, decorators: [{
14705
14612
  type: Pipe,
14706
14613
  args: [{
14707
14614
  name: 'dynamicText',
14708
- standalone: true,
14709
14615
  }]
14710
14616
  }] });
14711
14617
 
@@ -14780,25 +14686,26 @@ class RowFieldComponent {
14780
14686
  destroyRef = inject(DestroyRef);
14781
14687
  fieldRegistry = injectFieldRegistry();
14782
14688
  injector = inject(Injector);
14689
+ environmentInjector = inject(EnvironmentInjector);
14783
14690
  eventBus = inject(EventBus);
14784
14691
  logger = inject(DynamicFormLogger);
14785
14692
  // ─────────────────────────────────────────────────────────────────────────────
14786
14693
  // Inputs
14787
14694
  // ─────────────────────────────────────────────────────────────────────────────
14788
- field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
14789
- key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
14790
- className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
14791
- hidden = input(false, ...(ngDevMode ? [{ debugName: "hidden" }] : []));
14695
+ field = input.required(...(ngDevMode ? [{ debugName: "field" }] : /* istanbul ignore next */ []));
14696
+ key = input.required(...(ngDevMode ? [{ debugName: "key" }] : /* istanbul ignore next */ []));
14697
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : /* istanbul ignore next */ []));
14698
+ hidden = input(false, ...(ngDevMode ? [{ debugName: "hidden" }] : /* istanbul ignore next */ []));
14792
14699
  // ─────────────────────────────────────────────────────────────────────────────
14793
14700
  // Computed Signals
14794
14701
  // ─────────────────────────────────────────────────────────────────────────────
14795
- hostClasses = computed(() => computeContainerHostClasses('row', this.className()), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
14796
- disabled = computed(() => this.field().disabled || false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
14797
- rawFieldRegistry = computed(() => this.fieldRegistry.raw, ...(ngDevMode ? [{ debugName: "rawFieldRegistry" }] : []));
14702
+ hostClasses = computed(() => computeContainerHostClasses('row', this.className()), ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
14703
+ disabled = computed(() => this.field().disabled || false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
14704
+ rawFieldRegistry = computed(() => this.fieldRegistry.raw, ...(ngDevMode ? [{ debugName: "rawFieldRegistry" }] : /* istanbul ignore next */ []));
14798
14705
  // ─────────────────────────────────────────────────────────────────────────────
14799
14706
  // Field Resolution
14800
14707
  // ─────────────────────────────────────────────────────────────────────────────
14801
- fieldsSource = computed(() => (this.field().fields || []), ...(ngDevMode ? [{ debugName: "fieldsSource" }] : []));
14708
+ fieldsSource = computed(() => (this.field().fields || []), ...(ngDevMode ? [{ debugName: "fieldsSource" }] : /* istanbul ignore next */ []));
14802
14709
  resolvedFields = derivedFromDeferred(this.fieldsSource, createFieldResolutionPipe(() => ({
14803
14710
  loadTypeComponent: (type) => this.fieldRegistry.loadTypeComponent(type),
14804
14711
  registry: this.rawFieldRegistry(),
@@ -14823,18 +14730,22 @@ class RowFieldComponent {
14823
14730
  setupEffects() {
14824
14731
  setupContainerInitEffect(this.resolvedFields, this.eventBus, 'row', () => this.field().key, this.injector);
14825
14732
  }
14826
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: RowFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
14827
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", 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 }, 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.disabled": "disabled()", "class.df-container-hidden": "hidden()", "attr.aria-hidden": "hidden() || null", "id": "`${key()}`", "attr.data-testid": "key()" } }, ngImport: i0, template: `
14733
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: RowFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
14734
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", 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 }, 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.disabled": "disabled()", "class.df-container-hidden": "hidden()", "attr.aria-hidden": "hidden() || null", "id": "`${key()}`", "attr.data-testid": "key()" } }, ngImport: i0, template: `
14828
14735
  @for (field of resolvedFields(); track field.key) {
14829
- <ng-container *ngComponentOutlet="field.component; injector: field.injector; inputs: field.inputs()" />
14736
+ <ng-container
14737
+ *ngComponentOutlet="field.component; injector: field.injector; environmentInjector: environmentInjector; inputs: field.inputs()"
14738
+ />
14830
14739
  }
14831
- `, 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-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: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)}}:host.df-container-hidden{display:none}@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 });
14740
+ `, 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-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: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 ::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)}}:host.df-container-hidden{display:none}@media(max-width:576px){: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 });
14832
14741
  }
14833
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: RowFieldComponent, decorators: [{
14742
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: RowFieldComponent, decorators: [{
14834
14743
  type: Component,
14835
14744
  args: [{ selector: 'div[row-field]', imports: [NgComponentOutlet], template: `
14836
14745
  @for (field of resolvedFields(); track field.key) {
14837
- <ng-container *ngComponentOutlet="field.component; injector: field.injector; inputs: field.inputs()" />
14746
+ <ng-container
14747
+ *ngComponentOutlet="field.component; injector: field.injector; environmentInjector: environmentInjector; inputs: field.inputs()"
14748
+ />
14838
14749
  }
14839
14750
  `, host: {
14840
14751
  '[class]': 'hostClasses()',
@@ -14843,7 +14754,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
14843
14754
  '[attr.aria-hidden]': 'hidden() || null',
14844
14755
  '[id]': '`${key()}`',
14845
14756
  '[attr.data-testid]': 'key()',
14846
- }, 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: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)}}:host.df-container-hidden{display:none}@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"] }]
14757
+ }, 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: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 ::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)}}:host.df-container-hidden{display:none}@media(max-width:576px){: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"] }]
14847
14758
  }], 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 }] }] } });
14848
14759
 
14849
14760
  var rowField_component = /*#__PURE__*/Object.freeze({
@@ -14867,6 +14778,7 @@ class GroupFieldComponent {
14867
14778
  fieldRegistry = injectFieldRegistry();
14868
14779
  parentFieldSignalContext = inject(FIELD_SIGNAL_CONTEXT);
14869
14780
  injector = inject(Injector);
14781
+ environmentInjector = inject(EnvironmentInjector);
14870
14782
  eventBus = inject(EventBus);
14871
14783
  logger = inject(DynamicFormLogger);
14872
14784
  // ─────────────────────────────────────────────────────────────────────────────
@@ -14876,24 +14788,26 @@ class GroupFieldComponent {
14876
14788
  // ─────────────────────────────────────────────────────────────────────────────
14877
14789
  // Inputs
14878
14790
  // ─────────────────────────────────────────────────────────────────────────────
14879
- field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
14880
- key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
14881
- className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
14882
- hidden = input(false, ...(ngDevMode ? [{ debugName: "hidden" }] : []));
14791
+ field = input.required(...(ngDevMode ? [{ debugName: "field" }] : /* istanbul ignore next */ []));
14792
+ key = input.required(...(ngDevMode ? [{ debugName: "key" }] : /* istanbul ignore next */ []));
14793
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : /* istanbul ignore next */ []));
14794
+ hidden = input(false, ...(ngDevMode ? [{ debugName: "hidden" }] : /* istanbul ignore next */ []));
14883
14795
  // ─────────────────────────────────────────────────────────────────────────────
14884
14796
  // Computed Signals
14885
14797
  // ─────────────────────────────────────────────────────────────────────────────
14886
- hostClasses = computed(() => computeContainerHostClasses('group', this.className()), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
14887
- rawFieldRegistry = computed(() => this.fieldRegistry.raw, ...(ngDevMode ? [{ debugName: "rawFieldRegistry" }] : []));
14798
+ hostClasses = computed(() => computeContainerHostClasses('group', this.className()), ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
14799
+ rawFieldRegistry = computed(() => this.fieldRegistry.raw, ...(ngDevMode ? [{ debugName: "rawFieldRegistry" }] : /* istanbul ignore next */ []));
14888
14800
  formSetup = computed(() => {
14889
14801
  const groupField = this.field();
14890
14802
  const registry = this.rawFieldRegistry();
14891
14803
  if (groupField.fields && groupField.fields.length > 0) {
14892
14804
  const flattenedFields = this.fieldProcessors.memoizedFlattenFields(groupField.fields, registry);
14805
+ const flattenedFieldsForRendering = this.fieldProcessors.memoizedFlattenFieldsForRendering(groupField.fields, registry);
14893
14806
  const fieldsById = this.fieldProcessors.memoizedKeyBy(flattenedFields);
14894
14807
  const defaultValues = this.fieldProcessors.memoizedDefaultValues(fieldsById, registry);
14895
14808
  return {
14896
- fields: flattenedFields,
14809
+ fields: flattenedFieldsForRendering,
14810
+ schemaFields: flattenedFields,
14897
14811
  originalFields: groupField.fields,
14898
14812
  defaultValues,
14899
14813
  registry,
@@ -14901,12 +14815,13 @@ class GroupFieldComponent {
14901
14815
  }
14902
14816
  return {
14903
14817
  fields: [],
14818
+ schemaFields: [],
14904
14819
  originalFields: [],
14905
14820
  defaultValues: {},
14906
14821
  registry,
14907
14822
  };
14908
- }, ...(ngDevMode ? [{ debugName: "formSetup" }] : []));
14909
- defaultValues = linkedSignal(() => this.formSetup().defaultValues, ...(ngDevMode ? [{ debugName: "defaultValues" }] : []));
14823
+ }, ...(ngDevMode ? [{ debugName: "formSetup" }] : /* istanbul ignore next */ []));
14824
+ defaultValues = linkedSignal(() => this.formSetup().defaultValues, ...(ngDevMode ? [{ debugName: "defaultValues" }] : /* istanbul ignore next */ []));
14910
14825
  /**
14911
14826
  * Entity computed from parent value, group key, and defaults.
14912
14827
  * Uses deep equality check to prevent unnecessary updates when
@@ -14925,28 +14840,28 @@ class GroupFieldComponent {
14925
14840
  form = computed(() => {
14926
14841
  return runInInjectionContext(this.injector, () => {
14927
14842
  const setup = this.formSetup();
14928
- if (setup.fields.length > 0) {
14929
- const schema = createSchemaFromFields(setup.fields, setup.registry);
14843
+ if (setup.schemaFields.length > 0) {
14844
+ const schema = createSchemaFromFields(setup.schemaFields, setup.registry);
14930
14845
  return untracked(() => form(this.entity, schema));
14931
14846
  }
14932
14847
  return untracked(() => form(this.entity));
14933
14848
  });
14934
- }, ...(ngDevMode ? [{ debugName: "form" }] : []));
14849
+ }, ...(ngDevMode ? [{ debugName: "form" }] : /* istanbul ignore next */ []));
14935
14850
  // ─────────────────────────────────────────────────────────────────────────────
14936
14851
  // Public State Signals
14937
14852
  // ─────────────────────────────────────────────────────────────────────────────
14938
- formValue = computed(() => this.entity(), ...(ngDevMode ? [{ debugName: "formValue" }] : []));
14939
- valid = computed(() => this.form()().valid(), ...(ngDevMode ? [{ debugName: "valid" }] : []));
14940
- invalid = computed(() => this.form()().invalid(), ...(ngDevMode ? [{ debugName: "invalid" }] : []));
14941
- dirty = computed(() => this.form()().dirty(), ...(ngDevMode ? [{ debugName: "dirty" }] : []));
14942
- touched = computed(() => this.form()().touched(), ...(ngDevMode ? [{ debugName: "touched" }] : []));
14943
- errors = computed(() => this.form()().errors(), ...(ngDevMode ? [{ debugName: "errors" }] : []));
14944
- disabled = computed(() => this.form()().disabled(), ...(ngDevMode ? [{ debugName: "disabled" }] : []));
14853
+ formValue = computed(() => this.entity(), ...(ngDevMode ? [{ debugName: "formValue" }] : /* istanbul ignore next */ []));
14854
+ valid = computed(() => this.form()().valid(), ...(ngDevMode ? [{ debugName: "valid" }] : /* istanbul ignore next */ []));
14855
+ invalid = computed(() => this.form()().invalid(), ...(ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []));
14856
+ dirty = computed(() => this.form()().dirty(), ...(ngDevMode ? [{ debugName: "dirty" }] : /* istanbul ignore next */ []));
14857
+ touched = computed(() => this.form()().touched(), ...(ngDevMode ? [{ debugName: "touched" }] : /* istanbul ignore next */ []));
14858
+ errors = computed(() => this.form()().errors(), ...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
14859
+ disabled = computed(() => this.form()().disabled(), ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
14945
14860
  nestedFieldTree = computed(() => {
14946
14861
  const parentForm = this.parentFieldSignalContext.form;
14947
14862
  const groupKey = this.field().key;
14948
14863
  return parentForm[groupKey];
14949
- }, ...(ngDevMode ? [{ debugName: "nestedFieldTree" }] : []));
14864
+ }, ...(ngDevMode ? [{ debugName: "nestedFieldTree" }] : /* istanbul ignore next */ []));
14950
14865
  groupFieldSignalContext = (() => {
14951
14866
  const nestedFieldTree = this.nestedFieldTree;
14952
14867
  return {
@@ -14971,7 +14886,7 @@ class GroupFieldComponent {
14971
14886
  // ─────────────────────────────────────────────────────────────────────────────
14972
14887
  // Field Resolution
14973
14888
  // ─────────────────────────────────────────────────────────────────────────────
14974
- fieldsSource = computed(() => this.formSetup().fields, ...(ngDevMode ? [{ debugName: "fieldsSource" }] : []));
14889
+ fieldsSource = computed(() => this.formSetup().fields, ...(ngDevMode ? [{ debugName: "fieldsSource" }] : /* istanbul ignore next */ []));
14975
14890
  resolvedFields = derivedFromDeferred(this.fieldsSource, createFieldResolutionPipe(() => ({
14976
14891
  loadTypeComponent: (type) => this.fieldRegistry.loadTypeComponent(type),
14977
14892
  registry: this.rawFieldRegistry(),
@@ -15000,18 +14915,22 @@ class GroupFieldComponent {
15000
14915
  }
15001
14916
  }, { defer: true });
15002
14917
  }
15003
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: GroupFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
15004
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", 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 }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { validityChange: "validityChange", dirtyChange: "dirtyChange", submitted: "submitted" }, host: { attributes: { "role": "group" }, properties: { "class": "hostClasses()", "class.disabled": "disabled()", "class.df-container-hidden": "hidden()", "attr.aria-hidden": "hidden() || null", "id": "`${key()}`", "attr.data-testid": "key()" } }, ngImport: i0, template: `
14918
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: GroupFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
14919
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", 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 }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { validityChange: "validityChange", dirtyChange: "dirtyChange", submitted: "submitted" }, host: { attributes: { "role": "group" }, properties: { "class": "hostClasses()", "class.disabled": "disabled()", "class.df-container-hidden": "hidden()", "attr.aria-hidden": "hidden() || null", "id": "`${key()}`", "attr.data-testid": "key()" } }, ngImport: i0, template: `
15005
14920
  @for (field of resolvedFields(); track field.key) {
15006
- <ng-container *ngComponentOutlet="field.component; injector: field.injector; inputs: field.inputs()" />
14921
+ <ng-container
14922
+ *ngComponentOutlet="field.component; injector: field.injector; environmentInjector: environmentInjector; inputs: field.inputs()"
14923
+ />
15007
14924
  }
15008
14925
  `, 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-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{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}:host.df-container-hidden{display:none}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
15009
14926
  }
15010
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: GroupFieldComponent, decorators: [{
14927
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: GroupFieldComponent, decorators: [{
15011
14928
  type: Component,
15012
14929
  args: [{ selector: 'fieldset[group-field]', imports: [NgComponentOutlet], template: `
15013
14930
  @for (field of resolvedFields(); track field.key) {
15014
- <ng-container *ngComponentOutlet="field.component; injector: field.injector; inputs: field.inputs()" />
14931
+ <ng-container
14932
+ *ngComponentOutlet="field.component; injector: field.injector; environmentInjector: environmentInjector; inputs: field.inputs()"
14933
+ />
15015
14934
  }
15016
14935
  `, host: {
15017
14936
  '[class]': 'hostClasses()',
@@ -15112,7 +15031,7 @@ function createArrayItemInjectorAndInputs(options) {
15112
15031
  return undefined;
15113
15032
  }
15114
15033
  return arrayFieldTree[index];
15115
- }, { ...(ngDevMode ? { debugName: "itemFormAccessor" } : {}), equal: isEqual });
15034
+ }, { ...(ngDevMode ? { debugName: "itemFormAccessor" } : /* istanbul ignore next */ {}), equal: isEqual });
15116
15035
  const injector = createItemInjector({
15117
15036
  itemFormAccessor,
15118
15037
  indexSignal,
@@ -15219,7 +15138,7 @@ function resolveArrayItem(options) {
15219
15138
  const indexSignal = linkedSignal(() => {
15220
15139
  const positionMap = itemPositionMap();
15221
15140
  return positionMap.get(itemId) ?? index;
15222
- }, ...(ngDevMode ? [{ debugName: "indexSignal" }] : []));
15141
+ }, ...(ngDevMode ? [{ debugName: "indexSignal" }] : /* istanbul ignore next */ []));
15223
15142
  // Resolve all templates in parallel
15224
15143
  const fieldObservables = templates.map((template) => from(loadTypeComponent(template.type)).pipe(map$1((component) => {
15225
15144
  if (destroyRef.destroyed) {
@@ -15339,6 +15258,7 @@ class ArrayFieldComponent {
15339
15258
  fieldRegistry = injectFieldRegistry();
15340
15259
  parentFieldSignalContext = inject(FIELD_SIGNAL_CONTEXT);
15341
15260
  parentInjector = inject(Injector);
15261
+ environmentInjector = inject(EnvironmentInjector);
15342
15262
  eventBus = inject(EventBus);
15343
15263
  logger = inject(DynamicFormLogger);
15344
15264
  templateRegistry = inject(ARRAY_TEMPLATE_REGISTRY);
@@ -15346,10 +15266,10 @@ class ArrayFieldComponent {
15346
15266
  // ─────────────────────────────────────────────────────────────────────────────
15347
15267
  // Inputs
15348
15268
  // ─────────────────────────────────────────────────────────────────────────────
15349
- field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
15350
- key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
15351
- className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
15352
- hidden = input(false, ...(ngDevMode ? [{ debugName: "hidden" }] : []));
15269
+ field = input.required(...(ngDevMode ? [{ debugName: "field" }] : /* istanbul ignore next */ []));
15270
+ key = input.required(...(ngDevMode ? [{ debugName: "key" }] : /* istanbul ignore next */ []));
15271
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : /* istanbul ignore next */ []));
15272
+ hidden = input(false, ...(ngDevMode ? [{ debugName: "hidden" }] : /* istanbul ignore next */ []));
15353
15273
  // ─────────────────────────────────────────────────────────────────────────────
15354
15274
  // Computed Signals
15355
15275
  // ─────────────────────────────────────────────────────────────────────────────
@@ -15357,8 +15277,8 @@ class ArrayFieldComponent {
15357
15277
  const base = 'df-field df-array';
15358
15278
  const custom = this.className();
15359
15279
  return custom ? `${base} ${custom}` : base;
15360
- }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
15361
- rawFieldRegistry = computed(() => this.fieldRegistry.raw, ...(ngDevMode ? [{ debugName: "rawFieldRegistry" }] : []));
15280
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
15281
+ rawFieldRegistry = computed(() => this.fieldRegistry.raw, ...(ngDevMode ? [{ debugName: "rawFieldRegistry" }] : /* istanbul ignore next */ []));
15362
15282
  /**
15363
15283
  * Gets the auto-remove button FieldDef from normalization metadata.
15364
15284
  * Set by simplified array normalization for primitive arrays with remove buttons.
@@ -15368,7 +15288,7 @@ class ArrayFieldComponent {
15368
15288
  autoRemoveButton = computed(() => {
15369
15289
  const metadata = getNormalizedArrayMetadata(this.field());
15370
15290
  return metadata?.autoRemoveButton;
15371
- }, ...(ngDevMode ? [{ debugName: "autoRemoveButton" }] : []));
15291
+ }, ...(ngDevMode ? [{ debugName: "autoRemoveButton" }] : /* istanbul ignore next */ []));
15372
15292
  /**
15373
15293
  * For primitive array items, the key of the value field template (e.g., 'value').
15374
15294
  * Used to wrap the FormControl in the item context so getFieldTree(key) works.
@@ -15394,7 +15314,7 @@ class ArrayFieldComponent {
15394
15314
  return definitions[0].key;
15395
15315
  }
15396
15316
  return undefined;
15397
- }, ...(ngDevMode ? [{ debugName: "primitiveFieldKey" }] : []));
15317
+ }, ...(ngDevMode ? [{ debugName: "primitiveFieldKey" }] : /* istanbul ignore next */ []));
15398
15318
  /**
15399
15319
  * Gets the item templates (field definitions) for the array.
15400
15320
  * Each element can be either:
@@ -15420,7 +15340,7 @@ class ArrayFieldComponent {
15420
15340
  }
15421
15341
  return normalized;
15422
15342
  });
15423
- }, ...(ngDevMode ? [{ debugName: "itemTemplates" }] : []));
15343
+ }, ...(ngDevMode ? [{ debugName: "itemTemplates" }] : /* istanbul ignore next */ []));
15424
15344
  arrayFieldTrees = computed(() => {
15425
15345
  const arrayKey = this.field().key;
15426
15346
  const parentForm = this.parentFieldSignalContext.form;
@@ -15438,12 +15358,12 @@ class ArrayFieldComponent {
15438
15358
  items.push(itemFieldTree ?? null);
15439
15359
  }
15440
15360
  return items;
15441
- }, ...(ngDevMode ? [{ debugName: "arrayFieldTrees" }] : []));
15361
+ }, ...(ngDevMode ? [{ debugName: "arrayFieldTrees" }] : /* istanbul ignore next */ []));
15442
15362
  // ─────────────────────────────────────────────────────────────────────────────
15443
15363
  // State Signals
15444
15364
  // ─────────────────────────────────────────────────────────────────────────────
15445
- resolvedItemsSignal = signal([], ...(ngDevMode ? [{ debugName: "resolvedItemsSignal" }] : []));
15446
- updateVersion = signal(0, ...(ngDevMode ? [{ debugName: "updateVersion" }] : []));
15365
+ resolvedItemsSignal = signal([], ...(ngDevMode ? [{ debugName: "resolvedItemsSignal" }] : /* istanbul ignore next */ []));
15366
+ updateVersion = signal(0, ...(ngDevMode ? [{ debugName: "updateVersion" }] : /* istanbul ignore next */ []));
15447
15367
  /**
15448
15368
  * Map of item IDs to their current positions. O(1) lookup vs O(n) indexOf().
15449
15369
  * Used by child linkedSignals to reactively track their position in the array.
@@ -15451,9 +15371,9 @@ class ArrayFieldComponent {
15451
15371
  itemPositionMap = computed(() => {
15452
15372
  const items = this.resolvedItemsSignal();
15453
15373
  return new Map(items.map((item, idx) => [item.id, idx]));
15454
- }, ...(ngDevMode ? [{ debugName: "itemPositionMap" }] : []));
15374
+ }, ...(ngDevMode ? [{ debugName: "itemPositionMap" }] : /* istanbul ignore next */ []));
15455
15375
  /** Read-only view of resolved items for template consumption. */
15456
- resolvedItems = computed(() => this.resolvedItemsSignal(), ...(ngDevMode ? [{ debugName: "resolvedItems" }] : []));
15376
+ resolvedItems = computed(() => this.resolvedItemsSignal(), ...(ngDevMode ? [{ debugName: "resolvedItems" }] : /* istanbul ignore next */ []));
15457
15377
  /**
15458
15378
  * Whether the array has reached its configured maxLength.
15459
15379
  * Exposed as a public signal so add-button components can bind [disabled]="atMaxLength()".
@@ -15465,7 +15385,7 @@ class ArrayFieldComponent {
15465
15385
  const arrayKey = this.field().key;
15466
15386
  const currentArray = getArrayValue(this.parentFieldSignalContext.value(), arrayKey);
15467
15387
  return currentArray.length >= maxLength;
15468
- }, ...(ngDevMode ? [{ debugName: "atMaxLength" }] : []));
15388
+ }, ...(ngDevMode ? [{ debugName: "atMaxLength" }] : /* istanbul ignore next */ []));
15469
15389
  // ─────────────────────────────────────────────────────────────────────────────
15470
15390
  // Auto-remove Cache
15471
15391
  // ─────────────────────────────────────────────────────────────────────────────
@@ -15831,8 +15751,8 @@ class ArrayFieldComponent {
15831
15751
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
15832
15752
  parentForm().value.set({ ...currentValue, [arrayKey]: newArray });
15833
15753
  }
15834
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ArrayFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
15835
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", 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()" } }, providers: [
15754
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: ArrayFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
15755
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", 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()" } }, providers: [
15836
15756
  // Each array gets its own template registry to track templates used for dynamically added items
15837
15757
  { provide: ARRAY_TEMPLATE_REGISTRY, useFactory: () => new Map() },
15838
15758
  // Each array gets its own ID generator for SSR hydration compatibility
@@ -15847,13 +15767,15 @@ class ArrayFieldComponent {
15847
15767
  [attr.data-array-item-index]="i"
15848
15768
  >
15849
15769
  @for (field of item.fields; track $index) {
15850
- <ng-container *ngComponentOutlet="field.component; injector: field.injector; inputs: field.inputs()" />
15770
+ <ng-container
15771
+ *ngComponentOutlet="field.component; injector: field.injector; environmentInjector: environmentInjector; inputs: field.inputs()"
15772
+ />
15851
15773
  }
15852
15774
  </div>
15853
15775
  }
15854
15776
  `, 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-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"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
15855
15777
  }
15856
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ArrayFieldComponent, decorators: [{
15778
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: ArrayFieldComponent, decorators: [{
15857
15779
  type: Component,
15858
15780
  args: [{ selector: 'array-field', imports: [NgComponentOutlet], template: `
15859
15781
  @for (item of resolvedItems(); track item.id; let i = $index) {
@@ -15865,7 +15787,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
15865
15787
  [attr.data-array-item-index]="i"
15866
15788
  >
15867
15789
  @for (field of item.fields; track $index) {
15868
- <ng-container *ngComponentOutlet="field.component; injector: field.injector; inputs: field.inputs()" />
15790
+ <ng-container
15791
+ *ngComponentOutlet="field.component; injector: field.injector; environmentInjector: environmentInjector; inputs: field.inputs()"
15792
+ />
15869
15793
  }
15870
15794
  </div>
15871
15795
  }
@@ -16028,5 +15952,5 @@ function extractErrorParams(error) {
16028
15952
  * Generated bundle index. Do not edit.
16029
15953
  */
16030
15954
 
16031
- export { hasFormValue as $, ARRAY_CONTEXT as A, BUILT_IN_FIELDS as B, ConsoleLogger as C, DynamicFormLogger as D, EventBus as E, FIELD_REGISTRY as F, GroupFieldComponent as G, applyMetaToElement as H, INITIALIZATION_TIMEOUT_MS as I, applyValidator as J, applyValidators as K, arrayEvent as L, arrayFieldMapper as M, NextPageEvent as N, baseFieldMapper as O, PageChangeEvent as P, buildBaseInputs as Q, RemoveAtIndexEvent as R, ShiftArrayItemEvent as S, createField as T, dynamicTextToObservable as U, evaluateNonFieldDisabled as V, evaluateNonFieldHidden as W, field as X, formConfig as Y, getArrayLength as Z, groupFieldMapper as _, createFieldResolutionPipe as a, interpolateParams as a0, isArrayField as a1, isCheckedField as a2, isContainerField as a3, isDisplayOnlyField as a4, isEqual as a5, isFormStateCondition as a6, isGroupField as a7, isLeafField as a8, isPageField as a9, isPropertyDerivationLogicConfig as aa, isRowField as ab, isSimplifiedArrayField as ac, isValueBearingField as ad, isValueField as ae, omit as af, pageFieldMapper as ag, provideDynamicForm as ah, resolveNextButtonDisabled as ai, resolveNonFieldDisabled as aj, resolveNonFieldHidden as ak, resolveSubmitButtonDisabled as al, resolveTokens as am, rowFieldMapper as an, textFieldMapper as ao, withEventFormValue as ap, withLoggerConfig as aq, withValueExclusionDefaults as ar, DynamicTextPipe as b, computeContainerHostClasses as c, derivedFromDeferred as d, AppendArrayItemEvent as e, ArrayFieldComponent as f, DEFAULT_PROPS as g, DEFAULT_VALIDATION_MESSAGES as h, injectFieldRegistry as i, DynamicForm as j, DynamicFormError as k, EventDispatcher as l, FIELD_SIGNAL_CONTEXT as m, FORM_OPTIONS as n, FormClearEvent as o, FormResetEvent as p, InsertArrayItemEvent as q, NoopLogger as r, setupContainerInitEffect as s, PopArrayItemEvent as t, PrependArrayItemEvent as u, validatePageNesting as v, PreviousPageEvent as w, RootFormRegistryService as x, RowFieldComponent as y, SubmitEvent as z };
16032
- //# sourceMappingURL=ng-forge-dynamic-forms-ng-forge-dynamic-forms-DXXp5M0q.mjs.map
15955
+ export { hasFormValue as $, ARRAY_CONTEXT as A, BUILT_IN_FIELDS as B, ConsoleLogger as C, DynamicFormLogger as D, EventBus as E, FIELD_REGISTRY as F, GroupFieldComponent as G, applyMetaToElement as H, INITIALIZATION_TIMEOUT_MS as I, applyValidator as J, applyValidators as K, arrayEvent as L, arrayFieldMapper as M, NextPageEvent as N, baseFieldMapper as O, PageChangeEvent as P, buildBaseInputs as Q, RemoveAtIndexEvent as R, ShiftArrayItemEvent as S, createField as T, dynamicTextToObservable as U, evaluateNonFieldDisabled as V, evaluateNonFieldHidden as W, field as X, formConfig as Y, getArrayLength as Z, groupFieldMapper as _, createFieldResolutionPipe as a, interpolateParams as a0, isArrayField as a1, isCheckedField as a2, isContainerField as a3, isDisplayOnlyField as a4, isEqual as a5, isFormStateCondition as a6, isGroupField as a7, isLeafField as a8, isPageField as a9, isRowField as aa, isSimplifiedArrayField as ab, isValueBearingField as ac, isValueField as ad, omit as ae, pageFieldMapper as af, provideDynamicForm as ag, resolveNextButtonDisabled as ah, resolveNonFieldDisabled as ai, resolveNonFieldHidden as aj, resolveSubmitButtonDisabled as ak, resolveTokens as al, rowFieldMapper as am, textFieldMapper as an, withEventFormValue as ao, withLoggerConfig as ap, withPreviousValue as aq, withValueExclusionDefaults as ar, DynamicTextPipe as b, computeContainerHostClasses as c, derivedFromDeferred as d, AppendArrayItemEvent as e, ArrayFieldComponent as f, DEFAULT_PROPS as g, DEFAULT_VALIDATION_MESSAGES as h, injectFieldRegistry as i, DynamicForm as j, DynamicFormError as k, EventDispatcher as l, FIELD_SIGNAL_CONTEXT as m, FORM_OPTIONS as n, FormClearEvent as o, FormResetEvent as p, InsertArrayItemEvent as q, NoopLogger as r, setupContainerInitEffect as s, PopArrayItemEvent as t, PrependArrayItemEvent as u, validatePageNesting as v, PreviousPageEvent as w, RootFormRegistryService as x, RowFieldComponent as y, SubmitEvent as z };
15956
+ //# sourceMappingURL=ng-forge-dynamic-forms-ng-forge-dynamic-forms-Sad9wa1d.mjs.map