@ngx-formly/core 7.1.0 → 9.0.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.
Files changed (102) hide show
  1. package/README.md +26 -9
  2. package/fesm2022/ngx-formly-core-json-schema.mjs +159 -39
  3. package/fesm2022/ngx-formly-core-json-schema.mjs.map +1 -1
  4. package/fesm2022/ngx-formly-core-preset.mjs +4 -4
  5. package/fesm2022/ngx-formly-core-preset.mjs.map +1 -1
  6. package/fesm2022/ngx-formly-core-select.mjs +28 -21
  7. package/fesm2022/ngx-formly-core-select.mjs.map +1 -1
  8. package/fesm2022/ngx-formly-core-testing.mjs +3 -3
  9. package/fesm2022/ngx-formly-core-testing.mjs.map +1 -1
  10. package/fesm2022/ngx-formly-core.mjs +181 -89
  11. package/fesm2022/ngx-formly-core.mjs.map +1 -1
  12. package/index.d.ts +738 -3
  13. package/json-schema/index.d.ts +39 -5
  14. package/package.json +2 -12
  15. package/preset/index.d.ts +13 -5
  16. package/select/index.d.ts +44 -5
  17. package/testing/index.d.ts +37 -5
  18. package/esm2022/json-schema/formly-json-schema.service.mjs +0 -728
  19. package/esm2022/json-schema/ngx-formly-core-json-schema.mjs +0 -5
  20. package/esm2022/json-schema/public_api.mjs +0 -2
  21. package/esm2022/lib/components/formly.field.mjs +0 -292
  22. package/esm2022/lib/components/formly.form.mjs +0 -171
  23. package/esm2022/lib/components/formly.template.mjs +0 -36
  24. package/esm2022/lib/core.config.mjs +0 -66
  25. package/esm2022/lib/core.mjs +0 -20
  26. package/esm2022/lib/core.module.mjs +0 -74
  27. package/esm2022/lib/extensions/core/core.mjs +0 -144
  28. package/esm2022/lib/extensions/field-expression/field-expression.mjs +0 -8
  29. package/esm2022/lib/extensions/field-expression/utils.mjs +0 -459
  30. package/esm2022/lib/extensions/field-expression-legacy/field-expression.mjs +0 -249
  31. package/esm2022/lib/extensions/field-expression-legacy/utils.mjs +0 -20
  32. package/esm2022/lib/extensions/field-form/field-form.mjs +0 -141
  33. package/esm2022/lib/extensions/field-form/utils.mjs +0 -100
  34. package/esm2022/lib/extensions/field-validation/field-validation.mjs +0 -135
  35. package/esm2022/lib/models/config.mjs +0 -2
  36. package/esm2022/lib/models/fieldconfig.cache.mjs +0 -2
  37. package/esm2022/lib/models/fieldconfig.mjs +0 -2
  38. package/esm2022/lib/models/index.mjs +0 -4
  39. package/esm2022/lib/services/formly.builder.mjs +0 -98
  40. package/esm2022/lib/services/formly.config.mjs +0 -236
  41. package/esm2022/lib/templates/field-array.type.mjs +0 -84
  42. package/esm2022/lib/templates/field-template.type.mjs +0 -34
  43. package/esm2022/lib/templates/field.type.mjs +0 -57
  44. package/esm2022/lib/templates/field.wrapper.mjs +0 -21
  45. package/esm2022/lib/templates/formly.attributes.mjs +0 -201
  46. package/esm2022/lib/templates/formly.group.mjs +0 -31
  47. package/esm2022/lib/templates/formly.validation-message.mjs +0 -84
  48. package/esm2022/lib/utils.mjs +0 -313
  49. package/esm2022/ngx-formly-core.mjs +0 -5
  50. package/esm2022/preset/ngx-formly-core-preset.mjs +0 -5
  51. package/esm2022/preset/preset-substitution.extension.mjs +0 -30
  52. package/esm2022/preset/preset.config.mjs +0 -11
  53. package/esm2022/preset/preset.module.mjs +0 -18
  54. package/esm2022/preset/public_api.mjs +0 -3
  55. package/esm2022/public_api.mjs +0 -5
  56. package/esm2022/select/ngx-formly-core-select.mjs +0 -5
  57. package/esm2022/select/public_api.mjs +0 -3
  58. package/esm2022/select/select-options.pipe.mjs +0 -108
  59. package/esm2022/select/select.module.mjs +0 -16
  60. package/esm2022/testing/component-factory.mjs +0 -86
  61. package/esm2022/testing/ngx-formly-core-testing.mjs +0 -5
  62. package/esm2022/testing/public_api.mjs +0 -2
  63. package/json-schema/formly-json-schema.service.d.ts +0 -31
  64. package/json-schema/public_api.d.ts +0 -1
  65. package/lib/components/formly.field.d.ts +0 -44
  66. package/lib/components/formly.form.d.ts +0 -50
  67. package/lib/components/formly.template.d.ts +0 -19
  68. package/lib/core.config.d.ts +0 -11
  69. package/lib/core.d.ts +0 -20
  70. package/lib/core.module.d.ts +0 -18
  71. package/lib/extensions/core/core.d.ts +0 -14
  72. package/lib/extensions/field-expression/field-expression.d.ts +0 -4
  73. package/lib/extensions/field-expression/utils.d.ts +0 -4
  74. package/lib/extensions/field-expression-legacy/field-expression.d.ts +0 -16
  75. package/lib/extensions/field-expression-legacy/utils.d.ts +0 -5
  76. package/lib/extensions/field-form/field-form.d.ts +0 -11
  77. package/lib/extensions/field-form/utils.d.ts +0 -7
  78. package/lib/extensions/field-validation/field-validation.d.ts +0 -11
  79. package/lib/models/config.d.ts +0 -90
  80. package/lib/models/fieldconfig.cache.d.ts +0 -50
  81. package/lib/models/fieldconfig.d.ts +0 -243
  82. package/lib/models/index.d.ts +0 -3
  83. package/lib/services/formly.builder.d.ts +0 -18
  84. package/lib/services/formly.config.d.ts +0 -56
  85. package/lib/templates/field-array.type.d.ts +0 -22
  86. package/lib/templates/field-template.type.d.ts +0 -12
  87. package/lib/templates/field.type.d.ts +0 -30
  88. package/lib/templates/field.wrapper.d.ts +0 -12
  89. package/lib/templates/formly.attributes.d.ts +0 -52
  90. package/lib/templates/formly.group.d.ts +0 -7
  91. package/lib/templates/formly.validation-message.d.ts +0 -23
  92. package/lib/utils.d.ts +0 -47
  93. package/preset/preset-substitution.extension.d.ts +0 -13
  94. package/preset/preset.config.d.ts +0 -2
  95. package/preset/preset.module.d.ts +0 -7
  96. package/preset/public_api.d.ts +0 -2
  97. package/public_api.d.ts +0 -1
  98. package/select/public_api.d.ts +0 -2
  99. package/select/select-options.pipe.d.ts +0 -33
  100. package/select/select.module.d.ts +0 -7
  101. package/testing/component-factory.d.ts +0 -35
  102. package/testing/public_api.d.ts +0 -1
@@ -1,18 +1,22 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Type, TemplateRef, ComponentRef, ChangeDetectorRef, ɵNoopNgZone as _NoopNgZone, VERSION, Input, ViewChildren, Directive, ChangeDetectionStrategy, Component, Injectable, ViewContainerRef, ViewChild, Optional, InjectionToken, inject, Inject, EventEmitter, ContentChildren, Output, NgModule } from '@angular/core';
2
+ import { Type, TemplateRef, ComponentRef, ChangeDetectorRef, ɵNoopNgZone as _NoopNgZone, VERSION, Input, ViewChildren, Directive, ChangeDetectionStrategy, Component, Injectable, Injector, ViewContainerRef, ViewChild, Optional, InjectionToken, inject, Inject, EventEmitter, ContentChildren, Output, DOCUMENT, NgModule } from '@angular/core';
3
3
  import { isObservable, Observable, Subject, of, merge } from 'rxjs';
4
4
  import * as i2 from '@angular/forms';
5
5
  import { AbstractControl, UntypedFormArray, UntypedFormGroup, FormControl, UntypedFormControl, Validators, NgControl } from '@angular/forms';
6
- import { tap, map, distinctUntilChanged, startWith, debounceTime, filter, switchMap, take } from 'rxjs/operators';
6
+ import { tap, map, startWith, distinctUntilChanged, skip, debounceTime, filter, switchMap, take } from 'rxjs/operators';
7
7
  import * as i1 from '@angular/platform-browser';
8
8
  import * as i2$1 from '@angular/common';
9
- import { DOCUMENT, AsyncPipe, CommonModule } from '@angular/common';
9
+ import { AsyncPipe, CommonModule } from '@angular/common';
10
10
 
11
11
  function disableTreeValidityCall(form, callback) {
12
12
  const _updateTreeValidity = form._updateTreeValidity.bind(form);
13
13
  form._updateTreeValidity = () => { };
14
- callback();
15
- form._updateTreeValidity = _updateTreeValidity;
14
+ try {
15
+ callback();
16
+ }
17
+ finally {
18
+ form._updateTreeValidity = _updateTreeValidity;
19
+ }
16
20
  }
17
21
  function getFieldId(formId, field, index) {
18
22
  if (field.id) {
@@ -490,16 +494,31 @@ let FieldExpressionExtension$1 = class FieldExpressionExtension {
490
494
  return;
491
495
  }
492
496
  checkLocked = true;
493
- const fieldChanged = this.checkExpressions(f, ignoreCache);
494
- const options = field.options;
495
- options._hiddenFieldsForCheck
496
- .sort((f) => (f.field.hide ? -1 : 1))
497
- .forEach((f) => this.changeHideState(f.field, f.field.hide ?? f.default, !ignoreCache));
498
- options._hiddenFieldsForCheck = [];
499
- if (fieldChanged) {
500
- this.checkExpressions(field);
497
+ try {
498
+ // ponytail: initial-tree budget; add an override if valid dynamic forms need more passes.
499
+ const maxPasses = Math.max(100, 2 * this.countFields(field));
500
+ const options = field.options;
501
+ // Rebuilds preserve supplied values, but defaults may need clearing after visibility changes.
502
+ const restoredDefaults = ignoreCache ? new Set() : undefined;
503
+ const fieldChanged = this.checkExpressions(f, ignoreCache) || options._hiddenFieldsForCheck.length > 0;
504
+ let passes = 0;
505
+ do {
506
+ if (passes++ === maxPasses) {
507
+ console.warn('[Formly] The form may be inconsistent. Check for circular hide expressions');
508
+ throw new Error(`[Formly Error] Expressions did not settle after ${maxPasses} passes.`);
509
+ }
510
+ options._hiddenFieldsForCheck
511
+ .sort((f) => (f.field.hide ? -1 : 1))
512
+ .forEach((f) => this.changeHideState(f.field, f.field.hide ?? f.default, !ignoreCache, f.emitEvent, restoredDefaults));
513
+ options._hiddenFieldsForCheck = [];
514
+ if (fieldChanged) {
515
+ this.checkExpressions(field);
516
+ }
517
+ } while (options._hiddenFieldsForCheck.length > 0);
518
+ }
519
+ finally {
520
+ checkLocked = false;
501
521
  }
502
- checkLocked = false;
503
522
  };
504
523
  }
505
524
  }
@@ -547,15 +566,29 @@ let FieldExpressionExtension$1 = class FieldExpressionExtension {
547
566
  _evalStringExpression(expression, argNames) {
548
567
  return evalStringExpressionLegacy(expression, argNames);
549
568
  }
569
+ countFields(field) {
570
+ return field ? 1 + (field.fieldGroup?.reduce((count, f) => count + this.countFields(f), 0) ?? 0) : 0;
571
+ }
550
572
  checkExpressions(field, ignoreCache = false) {
551
573
  if (!field) {
552
574
  return false;
553
575
  }
554
576
  let fieldChanged = false;
555
577
  if (field._expressions) {
578
+ const hide = field.hide;
556
579
  for (const key of Object.keys(field._expressions)) {
557
580
  field._expressions[key].callback?.(ignoreCache) && (fieldChanged = true);
558
581
  }
582
+ if (ignoreCache && field._expressions.hide && hide === false && field.hide === false) {
583
+ let parent = field.parent;
584
+ while (parent && !parent.hide) {
585
+ parent = parent.parent;
586
+ }
587
+ if (!parent) {
588
+ // Restore defaults after rebuilding without reporting a visibility change.
589
+ field.options._hiddenFieldsForCheck.push({ field, emitEvent: false });
590
+ }
591
+ }
559
592
  }
560
593
  field.fieldGroup?.forEach((f) => this.checkExpressions(f, ignoreCache) && (fieldChanged = true));
561
594
  return fieldChanged;
@@ -570,11 +603,12 @@ let FieldExpressionExtension$1 = class FieldExpressionExtension {
570
603
  field.props.disabled = value;
571
604
  }
572
605
  }
573
- changeHideState(field, hide, resetOnHide) {
606
+ changeHideState(field, hide, resetOnHide, emitEvent = true, restoredDefaults) {
607
+ hide = field.hide || hide;
574
608
  if (field.fieldGroup) {
575
609
  field.fieldGroup
576
610
  .filter((f) => f && !f._expressions.hide)
577
- .forEach((f) => this.changeHideState(f, hide, resetOnHide));
611
+ .forEach((f) => this.changeHideState(f, hide, resetOnHide, emitEvent, restoredDefaults));
578
612
  }
579
613
  if (field.formControl && hasKey(field)) {
580
614
  defineHiddenProp(field, '_hide', !!(hide || field.hide));
@@ -584,8 +618,9 @@ let FieldExpressionExtension$1 = class FieldExpressionExtension {
584
618
  }
585
619
  if (hide === true && (!c._fields || c._fields.every((f) => !!f._hide))) {
586
620
  unregisterControl(field, true);
587
- if (resetOnHide && field.resetOnHide) {
621
+ if ((resetOnHide || restoredDefaults?.has(c)) && field.resetOnHide) {
588
622
  assignFieldValue(field, undefined);
623
+ restoredDefaults?.delete(c);
589
624
  field.formControl.reset({ value: undefined, disabled: field.formControl.disabled });
590
625
  field.options.fieldChanges.next({ value: undefined, field, type: 'valueChanges' });
591
626
  if (field.fieldGroup && field.formControl instanceof UntypedFormArray) {
@@ -596,6 +631,7 @@ let FieldExpressionExtension$1 = class FieldExpressionExtension {
596
631
  else if (hide === false) {
597
632
  if (field.resetOnHide && !isUndefined(field.defaultValue) && isUndefined(getFieldValue(field))) {
598
633
  assignFieldValue(field, field.defaultValue);
634
+ restoredDefaults?.add(c);
599
635
  }
600
636
  registerControl(field, undefined, true);
601
637
  if (field.resetOnHide && field.fieldArray && field.fieldGroup?.length !== field.model?.length) {
@@ -603,7 +639,7 @@ let FieldExpressionExtension$1 = class FieldExpressionExtension {
603
639
  }
604
640
  }
605
641
  }
606
- if (field.options.fieldChanges) {
642
+ if (emitEvent && field.options.fieldChanges) {
607
643
  field.options.fieldChanges.next({ field, type: 'hidden', value: hide });
608
644
  }
609
645
  }
@@ -1594,10 +1630,10 @@ class FieldType {
1594
1630
  get formState() {
1595
1631
  return this.options?.formState || {};
1596
1632
  }
1597
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FieldType, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1598
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: FieldType, inputs: { field: "field" }, viewQueries: [{ propertyName: "_formlyControls", predicate: NgControl, descendants: true }], ngImport: i0 }); }
1633
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FieldType, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1634
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.33", type: FieldType, isStandalone: true, inputs: { field: "field" }, viewQueries: [{ propertyName: "_formlyControls", predicate: NgControl, descendants: true }], ngImport: i0 }); }
1599
1635
  }
1600
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FieldType, decorators: [{
1636
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FieldType, decorators: [{
1601
1637
  type: Directive
1602
1638
  }], propDecorators: { _formlyControls: [{
1603
1639
  type: ViewChildren,
@@ -1624,15 +1660,16 @@ class FormlyTemplateType extends FieldType {
1624
1660
  this.sanitizer = sanitizer;
1625
1661
  this.innerHtml = {};
1626
1662
  }
1627
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyTemplateType, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component }); }
1628
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: FormlyTemplateType, selector: "formly-template", usesInheritance: true, ngImport: i0, template: `<div [innerHtml]="template"></div>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1663
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyTemplateType, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component }); }
1664
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.33", type: FormlyTemplateType, isStandalone: false, selector: "formly-template", usesInheritance: true, ngImport: i0, template: `<div [innerHtml]="template"></div>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1629
1665
  }
1630
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyTemplateType, decorators: [{
1666
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyTemplateType, decorators: [{
1631
1667
  type: Component,
1632
1668
  args: [{
1633
1669
  selector: 'formly-template',
1634
1670
  template: `<div [innerHtml]="template"></div>`,
1635
1671
  changeDetection: ChangeDetectionStrategy.OnPush,
1672
+ standalone: false,
1636
1673
  }]
1637
1674
  }], ctorParameters: () => [{ type: i1.DomSanitizer }] });
1638
1675
 
@@ -1861,10 +1898,10 @@ class FormlyConfig {
1861
1898
  this.types[name].wrappers = extendedType.wrappers;
1862
1899
  }
1863
1900
  }
1864
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyConfig, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1865
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyConfig, providedIn: 'root' }); }
1901
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyConfig, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1902
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyConfig, providedIn: 'root' }); }
1866
1903
  }
1867
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyConfig, decorators: [{
1904
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyConfig, decorators: [{
1868
1905
  type: Injectable,
1869
1906
  args: [{ providedIn: 'root' }]
1870
1907
  }] });
@@ -1876,10 +1913,10 @@ class FormlyTemplate {
1876
1913
  ngOnChanges() {
1877
1914
  this.name = this.name || 'formly-group';
1878
1915
  }
1879
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyTemplate, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); }
1880
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: FormlyTemplate, isStandalone: true, selector: "[formlyTemplate]", inputs: { name: ["formlyTemplate", "name"] }, usesOnChanges: true, ngImport: i0 }); }
1916
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyTemplate, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); }
1917
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.33", type: FormlyTemplate, isStandalone: true, selector: "[formlyTemplate]", inputs: { name: ["formlyTemplate", "name"] }, usesOnChanges: true, ngImport: i0 }); }
1881
1918
  }
1882
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyTemplate, decorators: [{
1919
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyTemplate, decorators: [{
1883
1920
  type: Directive,
1884
1921
  args: [{ selector: '[formlyTemplate]', standalone: true }]
1885
1922
  }], ctorParameters: () => [{ type: i0.TemplateRef }], propDecorators: { name: [{
@@ -1887,19 +1924,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1887
1924
  args: ['formlyTemplate']
1888
1925
  }] } });
1889
1926
  class LegacyFormlyTemplate extends FormlyTemplate {
1890
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyTemplate, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
1891
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: LegacyFormlyTemplate, selector: "[formlyTemplate]", usesInheritance: true, ngImport: i0 }); }
1927
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: LegacyFormlyTemplate, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
1928
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.33", type: LegacyFormlyTemplate, isStandalone: false, selector: "[formlyTemplate]", usesInheritance: true, ngImport: i0 }); }
1892
1929
  }
1893
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyTemplate, decorators: [{
1930
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: LegacyFormlyTemplate, decorators: [{
1894
1931
  type: Directive,
1895
1932
  args: [{ selector: '[formlyTemplate]', standalone: false }]
1896
1933
  }] });
1897
1934
  // workarround for https://github.com/angular/angular/issues/43227#issuecomment-904173738
1898
1935
  class FormlyFieldTemplates {
1899
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyFieldTemplates, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1900
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyFieldTemplates }); }
1936
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyFieldTemplates, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1937
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyFieldTemplates }); }
1901
1938
  }
1902
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyFieldTemplates, decorators: [{
1939
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyFieldTemplates, decorators: [{
1903
1940
  type: Injectable
1904
1941
  }] });
1905
1942
 
@@ -1919,11 +1956,12 @@ class FormlyField {
1919
1956
  }
1920
1957
  return null;
1921
1958
  }
1922
- constructor(config, renderer, _elementRef, hostContainerRef, form) {
1959
+ constructor(config, renderer, _elementRef, hostContainerRef, injector, form) {
1923
1960
  this.config = config;
1924
1961
  this.renderer = renderer;
1925
1962
  this._elementRef = _elementRef;
1926
1963
  this.hostContainerRef = hostContainerRef;
1964
+ this.injector = injector;
1927
1965
  this.form = form;
1928
1966
  this.hostObservers = [];
1929
1967
  this.componentRefs = [];
@@ -1986,7 +2024,7 @@ class FormlyField {
1986
2024
  const inlineType = this.form?.templates?.find((ref) => ref.name === f.type);
1987
2025
  let ref;
1988
2026
  if (inlineType) {
1989
- ref = containerRef.createEmbeddedView(inlineType.ref, { $implicit: f });
2027
+ ref = containerRef.createEmbeddedView(inlineType.ref, { $implicit: f }, { injector: this.createFieldInjector() });
1990
2028
  }
1991
2029
  else {
1992
2030
  const { component } = this.config.getType(f.type, true);
@@ -2014,6 +2052,28 @@ class FormlyField {
2014
2052
  this.render();
2015
2053
  }
2016
2054
  }
2055
+ attachLocalField(field, previousField) {
2056
+ const currentField = this.field;
2057
+ if (!currentField) {
2058
+ return;
2059
+ }
2060
+ const localFields = (currentField._localFields || []).filter((f) => f !== field && f !== previousField);
2061
+ if (field && field !== currentField) {
2062
+ localFields.push(field);
2063
+ }
2064
+ if (currentField._localFields) {
2065
+ currentField._localFields = localFields;
2066
+ }
2067
+ else if (localFields.length > 0) {
2068
+ defineHiddenProp(currentField, '_localFields', localFields);
2069
+ }
2070
+ }
2071
+ createFieldInjector() {
2072
+ return Injector.create({
2073
+ providers: [{ provide: FormlyField, useValue: this }],
2074
+ parent: this.injector,
2075
+ });
2076
+ }
2017
2077
  attachComponentRef(ref, field) {
2018
2078
  this.componentRefs.push(ref);
2019
2079
  field._componentRefs.push(ref);
@@ -2123,7 +2183,7 @@ class FormlyField {
2123
2183
  }
2124
2184
  if (field.formControl && !field.fieldGroup) {
2125
2185
  const control = field.formControl;
2126
- let valueChanges = control.valueChanges.pipe(map((value) => {
2186
+ let valueChanges = control.valueChanges.pipe(startWith(control.value), map((value) => {
2127
2187
  field.parsers?.map((parserFn) => (value = parserFn(value, field)));
2128
2188
  if (!Object.is(value, field.formControl.value)) {
2129
2189
  field.formControl.setValue(value);
@@ -2134,7 +2194,7 @@ class FormlyField {
2134
2194
  return false;
2135
2195
  }
2136
2196
  return true;
2137
- }));
2197
+ }), skip(1));
2138
2198
  if (control.value !== getFieldValue(field)) {
2139
2199
  valueChanges = valueChanges.pipe(startWith(control.value));
2140
2200
  }
@@ -2164,13 +2224,13 @@ class FormlyField {
2164
2224
  templateFieldsSubs.forEach((unsubscribe) => unsubscribe());
2165
2225
  };
2166
2226
  }
2167
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyField, deps: [{ token: FormlyConfig }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: FormlyFieldTemplates, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
2168
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: FormlyField, isStandalone: true, selector: "formly-field", inputs: { field: "field" }, viewQueries: [{ propertyName: "viewContainerRef", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: '<ng-template #container></ng-template>', isInline: true, styles: [":host:empty{display:none}\n"] }); }
2227
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyField, deps: [{ token: FormlyConfig }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: i0.Injector }, { token: FormlyFieldTemplates, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
2228
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.33", type: FormlyField, isStandalone: true, selector: "formly-field", inputs: { field: "field" }, viewQueries: [{ propertyName: "viewContainerRef", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: '<ng-template #container></ng-template>', isInline: true, styles: [":host:empty{display:none}\n"] }); }
2169
2229
  }
2170
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyField, decorators: [{
2230
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyField, decorators: [{
2171
2231
  type: Component,
2172
2232
  args: [{ selector: 'formly-field', template: '<ng-template #container></ng-template>', standalone: true, styles: [":host:empty{display:none}\n"] }]
2173
- }], ctorParameters: () => [{ type: FormlyConfig }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: FormlyFieldTemplates, decorators: [{
2233
+ }], ctorParameters: () => [{ type: FormlyConfig }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i0.Injector }, { type: FormlyFieldTemplates, decorators: [{
2174
2234
  type: Optional
2175
2235
  }] }], propDecorators: { field: [{
2176
2236
  type: Input
@@ -2179,25 +2239,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2179
2239
  args: ['container', { read: ViewContainerRef, static: true }]
2180
2240
  }] } });
2181
2241
  class LegacyFormlyField extends FormlyField {
2182
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyField, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2183
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: LegacyFormlyField, selector: "formly-field", usesInheritance: true, ngImport: i0, template: '<ng-template #container></ng-template>', isInline: true, styles: [":host:empty{display:none}\n"] }); }
2242
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: LegacyFormlyField, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2243
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.33", type: LegacyFormlyField, isStandalone: false, selector: "formly-field", usesInheritance: true, ngImport: i0, template: '<ng-template #container></ng-template>', isInline: true, styles: [":host:empty{display:none}\n"] }); }
2184
2244
  }
2185
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyField, decorators: [{
2245
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: LegacyFormlyField, decorators: [{
2186
2246
  type: Component,
2187
2247
  args: [{ selector: 'formly-field', template: '<ng-template #container></ng-template>', standalone: false, styles: [":host:empty{display:none}\n"] }]
2188
2248
  }] });
2189
2249
 
2190
2250
  /** @ignore */
2191
2251
  class FormlyGroup extends FieldType {
2192
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyGroup, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2193
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FormlyGroup, selector: "formly-group", host: { properties: { "class": "field.fieldGroupClassName || \"\"" } }, usesInheritance: true, ngImport: i0, template: `
2252
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyGroup, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2253
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.33", type: FormlyGroup, isStandalone: false, selector: "formly-group", host: { properties: { "class": "field.fieldGroupClassName || \"\"" } }, usesInheritance: true, ngImport: i0, template: `
2194
2254
  @for (f of field.fieldGroup; track $index) {
2195
2255
  <formly-field [field]="f"></formly-field>
2196
2256
  }
2197
2257
  <ng-content></ng-content>
2198
2258
  `, isInline: true, dependencies: [{ kind: "component", type: LegacyFormlyField, selector: "formly-field" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2199
2259
  }
2200
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyGroup, decorators: [{
2260
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyGroup, decorators: [{
2201
2261
  type: Component,
2202
2262
  args: [{
2203
2263
  selector: 'formly-group',
@@ -2211,6 +2271,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2211
2271
  '[class]': 'field.fieldGroupClassName || ""',
2212
2272
  },
2213
2273
  changeDetection: ChangeDetectionStrategy.OnPush,
2274
+ standalone: false,
2214
2275
  }]
2215
2276
  }] });
2216
2277
 
@@ -2249,6 +2310,7 @@ function withFormlyFieldExpression() {
2249
2310
  }
2250
2311
  const provideFormlyCore = (configs = []) => {
2251
2312
  return [
2313
+ FormlyConfig,
2252
2314
  { provide: FORMLY_CONFIG, multi: true, useFactory: withDefaultConfig, deps: [FormlyConfig] },
2253
2315
  provideFormlyConfig(configs),
2254
2316
  ];
@@ -2262,8 +2324,9 @@ const provideFormlyConfig = (configs = []) => {
2262
2324
  skipSelf: true,
2263
2325
  optional: true,
2264
2326
  });
2265
- if (currentConfig) {
2266
- currentConfig.push(configs);
2327
+ if (currentConfig && inject(FormlyConfig) === inject(FormlyConfig, { skipSelf: true, optional: true })) {
2328
+ configs = Array.isArray(configs) ? configs : [configs];
2329
+ currentConfig.push(...configs);
2267
2330
  return currentConfig;
2268
2331
  }
2269
2332
  return configs;
@@ -2345,10 +2408,10 @@ class FormlyFormBuilder {
2345
2408
  }
2346
2409
  }
2347
2410
  }
2348
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyFormBuilder, deps: [{ token: FormlyConfig }, { token: i0.Injector }, { token: i0.ViewContainerRef, optional: true }, { token: i2.FormGroupDirective, optional: true }, { token: FORMLY_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
2349
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyFormBuilder, providedIn: 'root' }); }
2411
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyFormBuilder, deps: [{ token: FormlyConfig }, { token: i0.Injector }, { token: i0.ViewContainerRef, optional: true }, { token: i2.FormGroupDirective, optional: true }, { token: FORMLY_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
2412
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyFormBuilder, providedIn: 'root' }); }
2350
2413
  }
2351
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyFormBuilder, decorators: [{
2414
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyFormBuilder, decorators: [{
2352
2415
  type: Injectable,
2353
2416
  args: [{ providedIn: 'root' }]
2354
2417
  }], ctorParameters: () => [{ type: FormlyConfig }, { type: i0.Injector }, { type: i0.ViewContainerRef, decorators: [{
@@ -2472,18 +2535,18 @@ class FormlyForm {
2472
2535
  Object.keys(field).forEach((p) => (this.field[p] = field[p]));
2473
2536
  }
2474
2537
  }
2475
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyForm, deps: [{ token: FormlyFormBuilder }, { token: FormlyConfig }, { token: i0.NgZone }, { token: FormlyFieldTemplates }], target: i0.ɵɵFactoryTarget.Component }); }
2476
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: FormlyForm, isStandalone: true, selector: "formly-form", inputs: { form: "form", model: "model", fields: "fields", options: "options" }, outputs: { modelChange: "modelChange" }, providers: [FormlyFormBuilder, FormlyFieldTemplates], queries: [{ propertyName: "templates", predicate: FormlyTemplate }], usesOnChanges: true, ngImport: i0, template: '<formly-field [field]="field"></formly-field>', isInline: true, dependencies: [{ kind: "component", type: FormlyField, selector: "formly-field", inputs: ["field"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2538
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyForm, deps: [{ token: FormlyFormBuilder }, { token: FormlyConfig }, { token: i0.NgZone }, { token: FormlyFieldTemplates }], target: i0.ɵɵFactoryTarget.Component }); }
2539
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.33", type: FormlyForm, isStandalone: true, selector: "formly-form", inputs: { form: "form", model: "model", fields: "fields", options: "options" }, outputs: { modelChange: "modelChange" }, providers: [FormlyFormBuilder, FormlyFieldTemplates], queries: [{ propertyName: "templates", predicate: FormlyTemplate }], usesOnChanges: true, ngImport: i0, template: '<formly-field [field]="field"></formly-field>', isInline: true, dependencies: [{ kind: "component", type: FormlyField, selector: "formly-field", inputs: ["field"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2477
2540
  }
2478
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyForm, decorators: [{
2541
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyForm, decorators: [{
2479
2542
  type: Component,
2480
2543
  args: [{
2481
2544
  selector: 'formly-form',
2482
2545
  template: '<formly-field [field]="field"></formly-field>',
2483
2546
  providers: [FormlyFormBuilder, FormlyFieldTemplates],
2547
+ standalone: true,
2484
2548
  imports: [FormlyField],
2485
2549
  changeDetection: ChangeDetectionStrategy.OnPush,
2486
- standalone: true,
2487
2550
  }]
2488
2551
  }], ctorParameters: () => [{ type: FormlyFormBuilder }, { type: FormlyConfig }, { type: i0.NgZone }, { type: FormlyFieldTemplates }], propDecorators: { form: [{
2489
2552
  type: Input
@@ -2503,10 +2566,10 @@ class LegacyFormlyForm extends FormlyForm {
2503
2566
  set templates(templates) {
2504
2567
  this.fieldTemplates.templates = templates;
2505
2568
  }
2506
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyForm, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2507
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: LegacyFormlyForm, selector: "formly-form", providers: [FormlyFormBuilder, FormlyFieldTemplates], queries: [{ propertyName: "templates", predicate: LegacyFormlyTemplate }], usesInheritance: true, ngImport: i0, template: '<formly-field [field]="field"></formly-field>', isInline: true, dependencies: [{ kind: "component", type: LegacyFormlyField, selector: "formly-field" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2569
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: LegacyFormlyForm, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2570
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.33", type: LegacyFormlyForm, isStandalone: false, selector: "formly-form", providers: [FormlyFormBuilder, FormlyFieldTemplates], queries: [{ propertyName: "templates", predicate: LegacyFormlyTemplate }], usesInheritance: true, ngImport: i0, template: '<formly-field [field]="field"></formly-field>', isInline: true, dependencies: [{ kind: "component", type: LegacyFormlyField, selector: "formly-field" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2508
2571
  }
2509
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyForm, decorators: [{
2572
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: LegacyFormlyForm, decorators: [{
2510
2573
  type: Component,
2511
2574
  args: [{
2512
2575
  selector: 'formly-form',
@@ -2530,9 +2593,10 @@ class FormlyAttributes {
2530
2593
  get fieldAttrElements() {
2531
2594
  return this.field?.['_elementRefs'] || [];
2532
2595
  }
2533
- constructor(renderer, elementRef, _document) {
2596
+ constructor(renderer, elementRef, _document, formlyField) {
2534
2597
  this.renderer = renderer;
2535
2598
  this.elementRef = elementRef;
2599
+ this.formlyField = formlyField;
2536
2600
  this.uiAttributesCache = {};
2537
2601
  /**
2538
2602
  * HostBinding doesn't register listeners conditionally which may produce some perf issues.
@@ -2580,8 +2644,10 @@ class FormlyAttributes {
2580
2644
  }
2581
2645
  });
2582
2646
  }
2583
- this.detachElementRef(changes.field.previousValue);
2647
+ const previousField = changes.field.previousValue;
2648
+ this.detachElementRef(previousField);
2584
2649
  this.attachElementRef(changes.field.currentValue);
2650
+ this.formlyField?.attachLocalField(changes.field.currentValue, previousField?._elementRefs?.length ? undefined : previousField);
2585
2651
  if (this.fieldAttrElements.length === 1) {
2586
2652
  !this.id && this.field.id && this.setAttribute('id', this.field.id);
2587
2653
  this.focusObserver = observe(this.field, ['focus'], ({ currentValue }) => {
@@ -2613,7 +2679,7 @@ class FormlyAttributes {
2613
2679
  (!this.props.attributes || !this.props.attributes.hasOwnProperty(attr.toLowerCase()))) {
2614
2680
  this.uiAttributesCache[attr] = value;
2615
2681
  if (value || value === 0) {
2616
- this.setAttribute(attr, value === true ? attr : `${value}`);
2682
+ this.setAttribute(attr, this.getSafeAttributeValue(attr, value));
2617
2683
  }
2618
2684
  else {
2619
2685
  this.removeAttribute(attr);
@@ -2624,6 +2690,9 @@ class FormlyAttributes {
2624
2690
  ngOnDestroy() {
2625
2691
  this.uiEvents.listeners.forEach((listener) => listener());
2626
2692
  this.detachElementRef(this.field);
2693
+ if (!this.field?._elementRefs?.length) {
2694
+ this.formlyField?.attachLocalField(undefined, this.field);
2695
+ }
2627
2696
  this.focusObserver?.unsubscribe();
2628
2697
  }
2629
2698
  toggleFocus(value) {
@@ -2671,10 +2740,22 @@ class FormlyAttributes {
2671
2740
  }
2672
2741
  }
2673
2742
  detachElementRef(f) {
2674
- const index = f?.['_elementRefs'] ? this.fieldAttrElements.indexOf(this.elementRef) : -1;
2743
+ const elements = f?.['_elementRefs'] || [];
2744
+ const index = elements.indexOf(this.elementRef);
2675
2745
  if (index !== -1) {
2676
- f['_elementRefs'].splice(index, 1);
2746
+ elements.splice(index, 1);
2747
+ }
2748
+ }
2749
+ getSafeAttributeValue(attr, value) {
2750
+ if (attr === 'pattern') {
2751
+ let pattern = value instanceof RegExp ? value.source : value;
2752
+ // 1. Safely escape unescaped hyphens inside character classes for 'v' flag compatibility
2753
+ pattern = pattern.replace(/(\[[^\]]*?)(?<!\\)-(.*?\])/g, '$1\\-$2');
2754
+ // 2. Cleanly strip leading ^ and trailing $ so HTML5 handles the boundaries natively
2755
+ pattern = pattern.replace(/^^\^/, '').replace(/\$$/, '');
2756
+ return pattern;
2677
2757
  }
2758
+ return value === true ? attr : `${value}`;
2678
2759
  }
2679
2760
  setAttribute(attr, value) {
2680
2761
  this.renderer.setAttribute(this.elementRef.nativeElement, attr, value);
@@ -2682,10 +2763,10 @@ class FormlyAttributes {
2682
2763
  removeAttribute(attr) {
2683
2764
  this.renderer.removeAttribute(this.elementRef.nativeElement, attr);
2684
2765
  }
2685
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyAttributes, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive }); }
2686
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: FormlyAttributes, isStandalone: true, selector: "[formlyAttributes]", inputs: { field: ["formlyAttributes", "field"], id: "id" }, host: { listeners: { "change": "onHostChange($event)" } }, usesOnChanges: true, ngImport: i0 }); }
2766
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyAttributes, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: DOCUMENT }, { token: FormlyField, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
2767
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.33", type: FormlyAttributes, isStandalone: true, selector: "[formlyAttributes]", inputs: { field: ["formlyAttributes", "field"], id: "id" }, host: { listeners: { "change": "onHostChange($event)" } }, usesOnChanges: true, ngImport: i0 }); }
2687
2768
  }
2688
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyAttributes, decorators: [{
2769
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyAttributes, decorators: [{
2689
2770
  type: Directive,
2690
2771
  args: [{
2691
2772
  selector: '[formlyAttributes]',
@@ -2697,6 +2778,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2697
2778
  }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: undefined, decorators: [{
2698
2779
  type: Inject,
2699
2780
  args: [DOCUMENT]
2781
+ }] }, { type: FormlyField, decorators: [{
2782
+ type: Optional
2700
2783
  }] }], propDecorators: { field: [{
2701
2784
  type: Input,
2702
2785
  args: ['formlyAttributes']
@@ -2704,16 +2787,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2704
2787
  type: Input
2705
2788
  }] } });
2706
2789
  class LegacyFormlyAttributes extends FormlyAttributes {
2707
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyAttributes, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2708
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: LegacyFormlyAttributes, selector: "[formlyAttributes]", host: { listeners: { "change": "onHostChange($event)" } }, usesInheritance: true, ngImport: i0 }); }
2790
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: LegacyFormlyAttributes, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2791
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.33", type: LegacyFormlyAttributes, isStandalone: false, selector: "[formlyAttributes]", host: { listeners: { "change": "onHostChange($event)" } }, usesInheritance: true, ngImport: i0 }); }
2709
2792
  }
2710
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyAttributes, decorators: [{
2793
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: LegacyFormlyAttributes, decorators: [{
2711
2794
  type: Directive,
2712
2795
  args: [{
2713
2796
  selector: '[formlyAttributes]',
2714
2797
  host: {
2715
2798
  '(change)': 'onHostChange($event)',
2716
2799
  },
2800
+ standalone: false,
2717
2801
  }]
2718
2802
  }] });
2719
2803
 
@@ -2764,10 +2848,10 @@ class FormlyValidationMessage {
2764
2848
  }
2765
2849
  return undefined;
2766
2850
  }
2767
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyValidationMessage, deps: [{ token: FormlyConfig }], target: i0.ɵɵFactoryTarget.Component }); }
2768
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: FormlyValidationMessage, isStandalone: true, selector: "formly-validation-message", inputs: { field: "field" }, usesOnChanges: true, ngImport: i0, template: '{{ errorMessage$ | async }}', isInline: true, dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2851
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyValidationMessage, deps: [{ token: FormlyConfig }], target: i0.ɵɵFactoryTarget.Component }); }
2852
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.33", type: FormlyValidationMessage, isStandalone: true, selector: "formly-validation-message", inputs: { field: "field" }, usesOnChanges: true, ngImport: i0, template: '{{ errorMessage$ | async }}', isInline: true, dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2769
2853
  }
2770
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyValidationMessage, decorators: [{
2854
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyValidationMessage, decorators: [{
2771
2855
  type: Component,
2772
2856
  args: [{
2773
2857
  selector: 'formly-validation-message',
@@ -2780,15 +2864,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2780
2864
  type: Input
2781
2865
  }] } });
2782
2866
  class LegacyFormlyValidationMessage extends FormlyValidationMessage {
2783
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyValidationMessage, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2784
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: LegacyFormlyValidationMessage, selector: "formly-validation-message", usesInheritance: true, ngImport: i0, template: '{{ errorMessage$ | async }}', isInline: true, dependencies: [{ kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2867
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: LegacyFormlyValidationMessage, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2868
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.33", type: LegacyFormlyValidationMessage, isStandalone: false, selector: "formly-validation-message", usesInheritance: true, ngImport: i0, template: '{{ errorMessage$ | async }}', isInline: true, dependencies: [{ kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2785
2869
  }
2786
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyValidationMessage, decorators: [{
2870
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: LegacyFormlyValidationMessage, decorators: [{
2787
2871
  type: Component,
2788
2872
  args: [{
2789
2873
  selector: 'formly-validation-message',
2790
2874
  template: '{{ errorMessage$ | async }}',
2791
2875
  changeDetection: ChangeDetectionStrategy.OnPush,
2876
+ standalone: false,
2792
2877
  }]
2793
2878
  }] });
2794
2879
 
@@ -2863,10 +2948,10 @@ class FieldArrayType extends FieldType {
2863
2948
  this.options._hiddenFieldsForCheck.push({ field: f });
2864
2949
  }
2865
2950
  }
2866
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FieldArrayType, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2867
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: FieldArrayType, usesInheritance: true, ngImport: i0 }); }
2951
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FieldArrayType, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2952
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.33", type: FieldArrayType, isStandalone: true, usesInheritance: true, ngImport: i0 }); }
2868
2953
  }
2869
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FieldArrayType, decorators: [{
2954
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FieldArrayType, decorators: [{
2870
2955
  type: Directive
2871
2956
  }] });
2872
2957
 
@@ -2875,10 +2960,10 @@ class FieldWrapper extends FieldType {
2875
2960
  set _staticContent(content) {
2876
2961
  this.fieldComponent = content;
2877
2962
  }
2878
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FieldWrapper, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2879
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: FieldWrapper, viewQueries: [{ propertyName: "fieldComponent", first: true, predicate: ["fieldComponent"], descendants: true, read: ViewContainerRef }, { propertyName: "_staticContent", first: true, predicate: ["fieldComponent"], descendants: true, read: ViewContainerRef, static: true }], usesInheritance: true, ngImport: i0 }); }
2963
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FieldWrapper, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2964
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.33", type: FieldWrapper, isStandalone: true, viewQueries: [{ propertyName: "fieldComponent", first: true, predicate: ["fieldComponent"], descendants: true, read: ViewContainerRef }, { propertyName: "_staticContent", first: true, predicate: ["fieldComponent"], descendants: true, read: ViewContainerRef, static: true }], usesInheritance: true, ngImport: i0 }); }
2880
2965
  }
2881
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FieldWrapper, decorators: [{
2966
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FieldWrapper, decorators: [{
2882
2967
  type: Directive
2883
2968
  }], propDecorators: { fieldComponent: [{
2884
2969
  type: ViewChild,
@@ -2888,6 +2973,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2888
2973
  args: ['fieldComponent', { read: ViewContainerRef, static: true }]
2889
2974
  }] } });
2890
2975
 
2976
+ /**
2977
+ * Registers Formly components and configuration for NgModule-based applications.
2978
+ *
2979
+ * `forRoot()` provides the shared `FormlyConfig` at the application root, while
2980
+ * `forChild()` adds feature configuration using the inherited service. This follows
2981
+ * Angular's [root/child module registration convention](https://frontendatlas.com/angular/trivia/angular-forroot-forchild).
2982
+ */
2891
2983
  class FormlyModule {
2892
2984
  static forRoot(config = {}) {
2893
2985
  return {
@@ -2910,8 +3002,8 @@ class FormlyModule {
2910
3002
  ],
2911
3003
  };
2912
3004
  }
2913
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2914
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: FormlyModule, declarations: [LegacyFormlyTemplate,
3005
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
3006
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.33", ngImport: i0, type: FormlyModule, declarations: [LegacyFormlyTemplate,
2915
3007
  LegacyFormlyForm,
2916
3008
  LegacyFormlyField,
2917
3009
  LegacyFormlyAttributes,
@@ -2923,9 +3015,9 @@ class FormlyModule {
2923
3015
  LegacyFormlyAttributes,
2924
3016
  LegacyFormlyValidationMessage,
2925
3017
  FormlyGroup] }); }
2926
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyModule, imports: [CommonModule] }); }
3018
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyModule, imports: [CommonModule] }); }
2927
3019
  }
2928
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyModule, decorators: [{
3020
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: FormlyModule, decorators: [{
2929
3021
  type: NgModule,
2930
3022
  args: [{
2931
3023
  declarations: [