@ngx-formly/core 7.0.1 → 8.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 (72) hide show
  1. package/README.md +10 -0
  2. package/fesm2022/ngx-formly-core-json-schema.mjs +259 -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 +621 -78
  11. package/fesm2022/ngx-formly-core.mjs.map +1 -1
  12. package/json-schema/formly-json-schema.service.d.ts +8 -0
  13. package/lib/components/formly.field.d.ts +7 -4
  14. package/lib/core.config.d.ts +1 -0
  15. package/lib/core.d.ts +2 -2
  16. package/lib/core.module.d.ts +7 -0
  17. package/lib/extensions/field-expression/field-expression.d.ts +3 -12
  18. package/lib/extensions/field-expression/utils.d.ts +4 -2
  19. package/lib/extensions/field-expression-legacy/field-expression.d.ts +16 -0
  20. package/lib/extensions/field-expression-legacy/utils.d.ts +5 -0
  21. package/lib/templates/field-array.type.d.ts +1 -1
  22. package/lib/templates/field.type.d.ts +1 -1
  23. package/lib/templates/field.wrapper.d.ts +1 -1
  24. package/lib/templates/formly.attributes.d.ts +5 -2
  25. package/lib/templates/formly.validation-message.d.ts +2 -2
  26. package/package.json +2 -12
  27. package/select/select-options.pipe.d.ts +1 -0
  28. package/esm2022/json-schema/formly-json-schema.service.mjs +0 -628
  29. package/esm2022/json-schema/ngx-formly-core-json-schema.mjs +0 -5
  30. package/esm2022/json-schema/public_api.mjs +0 -2
  31. package/esm2022/lib/components/formly.field.mjs +0 -292
  32. package/esm2022/lib/components/formly.form.mjs +0 -171
  33. package/esm2022/lib/components/formly.template.mjs +0 -36
  34. package/esm2022/lib/core.config.mjs +0 -50
  35. package/esm2022/lib/core.mjs +0 -20
  36. package/esm2022/lib/core.module.mjs +0 -74
  37. package/esm2022/lib/extensions/core/core.mjs +0 -144
  38. package/esm2022/lib/extensions/field-expression/field-expression.mjs +0 -246
  39. package/esm2022/lib/extensions/field-expression/utils.mjs +0 -17
  40. package/esm2022/lib/extensions/field-form/field-form.mjs +0 -141
  41. package/esm2022/lib/extensions/field-form/utils.mjs +0 -100
  42. package/esm2022/lib/extensions/field-validation/field-validation.mjs +0 -135
  43. package/esm2022/lib/extensions/index.mjs +0 -2
  44. package/esm2022/lib/models/config.mjs +0 -2
  45. package/esm2022/lib/models/fieldconfig.cache.mjs +0 -2
  46. package/esm2022/lib/models/fieldconfig.mjs +0 -2
  47. package/esm2022/lib/models/index.mjs +0 -4
  48. package/esm2022/lib/services/formly.builder.mjs +0 -98
  49. package/esm2022/lib/services/formly.config.mjs +0 -236
  50. package/esm2022/lib/templates/field-array.type.mjs +0 -84
  51. package/esm2022/lib/templates/field-template.type.mjs +0 -34
  52. package/esm2022/lib/templates/field.type.mjs +0 -57
  53. package/esm2022/lib/templates/field.wrapper.mjs +0 -21
  54. package/esm2022/lib/templates/formly.attributes.mjs +0 -201
  55. package/esm2022/lib/templates/formly.group.mjs +0 -31
  56. package/esm2022/lib/templates/formly.validation-message.mjs +0 -84
  57. package/esm2022/lib/utils.mjs +0 -312
  58. package/esm2022/ngx-formly-core.mjs +0 -5
  59. package/esm2022/preset/ngx-formly-core-preset.mjs +0 -5
  60. package/esm2022/preset/preset-substitution.extension.mjs +0 -30
  61. package/esm2022/preset/preset.config.mjs +0 -11
  62. package/esm2022/preset/preset.module.mjs +0 -18
  63. package/esm2022/preset/public_api.mjs +0 -3
  64. package/esm2022/public_api.mjs +0 -5
  65. package/esm2022/select/ngx-formly-core-select.mjs +0 -5
  66. package/esm2022/select/public_api.mjs +0 -3
  67. package/esm2022/select/select-options.pipe.mjs +0 -108
  68. package/esm2022/select/select.module.mjs +0 -16
  69. package/esm2022/testing/component-factory.mjs +0 -86
  70. package/esm2022/testing/ngx-formly-core-testing.mjs +0 -5
  71. package/esm2022/testing/public_api.mjs +0 -2
  72. package/lib/extensions/index.d.ts +0 -1
@@ -1,9 +1,9 @@
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, 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
9
  import { DOCUMENT, AsyncPipe, CommonModule } from '@angular/common';
@@ -131,6 +131,7 @@ function isPromise(obj) {
131
131
  function clone(value) {
132
132
  if (!isObject(value) ||
133
133
  isObservable(value) ||
134
+ isPromise(value) ||
134
135
  value instanceof TemplateRef ||
135
136
  /* instanceof SafeHtmlImpl */ value.changingThisBreaksApplicationSecurity ||
136
137
  ['RegExp', 'FileList', 'File', 'Blob'].indexOf(value.constructor?.name) !== -1) {
@@ -317,7 +318,10 @@ function isSignalRequired() {
317
318
  return +VERSION.major > 18 || (+VERSION.major >= 18 && +VERSION.minor >= 1);
318
319
  }
319
320
 
320
- function evalStringExpression(expression, argNames) {
321
+ /**
322
+ * Legacy implementation
323
+ */
324
+ function evalStringExpressionLegacy(expression, argNames) {
321
325
  try {
322
326
  return Function(...argNames, `return ${expression};`);
323
327
  }
@@ -432,7 +436,7 @@ function clearControl(form) {
432
436
  }
433
437
  }
434
438
 
435
- class FieldExpressionExtension {
439
+ let FieldExpressionExtension$1 = class FieldExpressionExtension {
436
440
  onPopulate(field) {
437
441
  if (field._expressions) {
438
442
  return;
@@ -515,7 +519,7 @@ class FieldExpressionExtension {
515
519
  }
516
520
  expr = expr || (() => false);
517
521
  if (typeof expr === 'string') {
518
- expr = evalStringExpression(expr, ['model', 'formState', 'field']);
522
+ expr = this._evalStringExpression(expr, ['model', 'formState', 'field']);
519
523
  }
520
524
  let currentValue;
521
525
  return {
@@ -540,6 +544,9 @@ class FieldExpressionExtension {
540
544
  },
541
545
  };
542
546
  }
547
+ _evalStringExpression(expression, argNames) {
548
+ return evalStringExpressionLegacy(expression, argNames);
549
+ }
543
550
  checkExpressions(field, ignoreCache = false) {
544
551
  if (!field) {
545
552
  return false;
@@ -670,6 +677,471 @@ class FieldExpressionExtension {
670
677
  }
671
678
  return paths;
672
679
  }
680
+ };
681
+
682
+ // CSP-compliant expression parser for Formly expressions
683
+ // Supports: model.path, formState.path, field.path, comparisons, logical operators, and negation
684
+ // Tokenizer
685
+ var TokenType;
686
+ (function (TokenType) {
687
+ TokenType["IDENTIFIER"] = "IDENTIFIER";
688
+ TokenType["DOT"] = "DOT";
689
+ TokenType["BRACKET_OPEN"] = "BRACKET_OPEN";
690
+ TokenType["BRACKET_CLOSE"] = "BRACKET_CLOSE";
691
+ TokenType["STRING"] = "STRING";
692
+ TokenType["NUMBER"] = "NUMBER";
693
+ TokenType["BOOLEAN"] = "BOOLEAN";
694
+ TokenType["NULL"] = "NULL";
695
+ TokenType["UNDEFINED"] = "UNDEFINED";
696
+ TokenType["OPERATOR"] = "OPERATOR";
697
+ TokenType["LOGICAL"] = "LOGICAL";
698
+ TokenType["NOT"] = "NOT";
699
+ TokenType["ARITHMETIC"] = "ARITHMETIC";
700
+ TokenType["PAREN_OPEN"] = "PAREN_OPEN";
701
+ TokenType["PAREN_CLOSE"] = "PAREN_CLOSE";
702
+ TokenType["TERNARY_QUESTION"] = "TERNARY_QUESTION";
703
+ TokenType["TERNARY_COLON"] = "TERNARY_COLON";
704
+ TokenType["EOF"] = "EOF";
705
+ })(TokenType || (TokenType = {}));
706
+ class Tokenizer {
707
+ constructor(input) {
708
+ this.pos = 0;
709
+ this.input = input.trim();
710
+ }
711
+ tokenize() {
712
+ const tokens = [];
713
+ while (this.pos < this.input.length) {
714
+ this.skipWhitespace();
715
+ if (this.pos >= this.input.length)
716
+ break;
717
+ const char = this.input[this.pos];
718
+ // String literals
719
+ if (char === '"' || char === "'") {
720
+ tokens.push(this.readString());
721
+ }
722
+ // Numbers
723
+ else if (/\d/.test(char)) {
724
+ tokens.push(this.readNumber());
725
+ }
726
+ // Identifiers and keywords
727
+ else if (/[a-zA-Z_$]/.test(char)) {
728
+ tokens.push(this.readIdentifier());
729
+ }
730
+ // Operators and symbols
731
+ else if (char === '.') {
732
+ tokens.push({ type: TokenType.DOT, value: '.' });
733
+ this.pos++;
734
+ }
735
+ else if (char === '[') {
736
+ tokens.push({ type: TokenType.BRACKET_OPEN, value: '[' });
737
+ this.pos++;
738
+ }
739
+ else if (char === ']') {
740
+ tokens.push({ type: TokenType.BRACKET_CLOSE, value: ']' });
741
+ this.pos++;
742
+ }
743
+ else if (char === '(') {
744
+ tokens.push({ type: TokenType.PAREN_OPEN, value: '(' });
745
+ this.pos++;
746
+ }
747
+ else if (char === ')') {
748
+ tokens.push({ type: TokenType.PAREN_CLOSE, value: ')' });
749
+ this.pos++;
750
+ }
751
+ else if (char === '?') {
752
+ tokens.push({ type: TokenType.TERNARY_QUESTION, value: '?' });
753
+ this.pos++;
754
+ }
755
+ else if (char === ':') {
756
+ tokens.push({ type: TokenType.TERNARY_COLON, value: ':' });
757
+ this.pos++;
758
+ }
759
+ else if (char === '!') {
760
+ if (this.peek() === '=') {
761
+ if (this.input[this.pos + 2] === '=') {
762
+ tokens.push({ type: TokenType.OPERATOR, value: '!==' });
763
+ this.pos += 3;
764
+ }
765
+ else {
766
+ tokens.push({ type: TokenType.OPERATOR, value: '!=' });
767
+ this.pos += 2;
768
+ }
769
+ }
770
+ else {
771
+ tokens.push({ type: TokenType.NOT, value: '!' });
772
+ this.pos++;
773
+ }
774
+ }
775
+ else if (char === '=' || char === '<' || char === '>') {
776
+ tokens.push(this.readOperator());
777
+ }
778
+ else if (char === '+' || char === '*' || char === '/' || char === '%') {
779
+ tokens.push({ type: TokenType.ARITHMETIC, value: char });
780
+ this.pos++;
781
+ }
782
+ else if (char === '-') {
783
+ // Check if this is a negative number or subtraction
784
+ // It's a negative number if preceded by an operator, opening paren, or at the start
785
+ const lastToken = tokens[tokens.length - 1];
786
+ const isNegativeNumber = tokens.length === 0 ||
787
+ lastToken?.type === TokenType.OPERATOR ||
788
+ lastToken?.type === TokenType.LOGICAL ||
789
+ lastToken?.type === TokenType.ARITHMETIC ||
790
+ lastToken?.type === TokenType.PAREN_OPEN ||
791
+ lastToken?.type === TokenType.TERNARY_QUESTION ||
792
+ lastToken?.type === TokenType.TERNARY_COLON;
793
+ if (isNegativeNumber && this.peek() && /\d/.test(this.peek())) {
794
+ tokens.push(this.readNumber());
795
+ }
796
+ else {
797
+ tokens.push({ type: TokenType.ARITHMETIC, value: '-' });
798
+ this.pos++;
799
+ }
800
+ }
801
+ else if (char === '&' && this.peek() === '&') {
802
+ tokens.push({ type: TokenType.LOGICAL, value: '&&' });
803
+ this.pos += 2;
804
+ }
805
+ else if (char === '|' && this.peek() === '|') {
806
+ tokens.push({ type: TokenType.LOGICAL, value: '||' });
807
+ this.pos += 2;
808
+ }
809
+ else {
810
+ throw new Error(`Unexpected character: ${char} at position ${this.pos}`);
811
+ }
812
+ }
813
+ tokens.push({ type: TokenType.EOF, value: null });
814
+ return tokens;
815
+ }
816
+ skipWhitespace() {
817
+ while (this.pos < this.input.length && /\s/.test(this.input[this.pos])) {
818
+ this.pos++;
819
+ }
820
+ }
821
+ peek(offset = 1) {
822
+ return this.input[this.pos + offset] || '';
823
+ }
824
+ readString() {
825
+ const quote = this.input[this.pos];
826
+ this.pos++;
827
+ let value = '';
828
+ while (this.pos < this.input.length && this.input[this.pos] !== quote) {
829
+ if (this.input[this.pos] === '\\') {
830
+ this.pos++;
831
+ if (this.pos < this.input.length) {
832
+ const escaped = this.input[this.pos];
833
+ switch (escaped) {
834
+ case 'n':
835
+ value += '\n';
836
+ break;
837
+ case 't':
838
+ value += '\t';
839
+ break;
840
+ case 'r':
841
+ value += '\r';
842
+ break;
843
+ default:
844
+ value += escaped;
845
+ }
846
+ }
847
+ }
848
+ else {
849
+ value += this.input[this.pos];
850
+ }
851
+ this.pos++;
852
+ }
853
+ this.pos++; // skip closing quote
854
+ return { type: TokenType.STRING, value };
855
+ }
856
+ readNumber() {
857
+ let value = '';
858
+ // Handle negatives
859
+ if (this.input[this.pos] === '-') {
860
+ value += '-';
861
+ this.pos++;
862
+ }
863
+ let hasDecimal = false;
864
+ while (this.pos < this.input.length && /[\d.]/.test(this.input[this.pos])) {
865
+ if (this.input[this.pos] === '.') {
866
+ if (hasDecimal) {
867
+ throw new Error(`Invalid number format: multiple decimal points at position ${this.pos}`);
868
+ }
869
+ hasDecimal = true;
870
+ }
871
+ value += this.input[this.pos];
872
+ this.pos++;
873
+ }
874
+ const parsed = parseFloat(value);
875
+ if (isNaN(parsed)) {
876
+ throw new Error(`Invalid number format: ${value}`);
877
+ }
878
+ return { type: TokenType.NUMBER, value: parsed };
879
+ }
880
+ readIdentifier() {
881
+ let value = '';
882
+ while (this.pos < this.input.length && /[a-zA-Z0-9_$]/.test(this.input[this.pos])) {
883
+ value += this.input[this.pos];
884
+ this.pos++;
885
+ }
886
+ // Check for keywords
887
+ if (value === 'true' || value === 'false') {
888
+ return { type: TokenType.BOOLEAN, value: value === 'true' };
889
+ }
890
+ if (value === 'null') {
891
+ return { type: TokenType.NULL, value: null };
892
+ }
893
+ if (value === 'undefined') {
894
+ return { type: TokenType.UNDEFINED, value: undefined };
895
+ }
896
+ return { type: TokenType.IDENTIFIER, value };
897
+ }
898
+ readOperator() {
899
+ let op = this.input[this.pos];
900
+ this.pos++;
901
+ if (this.pos < this.input.length) {
902
+ const next = this.input[this.pos];
903
+ if ((op === '=' && next === '=') ||
904
+ (op === '!' && next === '=') ||
905
+ (op === '<' && next === '=') ||
906
+ (op === '>' && next === '=')) {
907
+ op += next;
908
+ this.pos++;
909
+ // Check for === or !==
910
+ if (this.pos < this.input.length && this.input[this.pos] === '=') {
911
+ op += '=';
912
+ this.pos++;
913
+ }
914
+ }
915
+ }
916
+ return { type: TokenType.OPERATOR, value: op };
917
+ }
918
+ }
919
+ // Parser and Evaluator
920
+ class ExpressionParser {
921
+ constructor(tokens) {
922
+ this.pos = 0;
923
+ this.tokens = tokens;
924
+ }
925
+ parse() {
926
+ const expr = this.parseTernary();
927
+ return (context) => expr(context);
928
+ }
929
+ parseTernary() {
930
+ const expr = this.parseLogicalOr();
931
+ if (this.current().type === TokenType.TERNARY_QUESTION) {
932
+ this.consume(TokenType.TERNARY_QUESTION);
933
+ const trueExpr = this.parseLogicalOr();
934
+ this.consume(TokenType.TERNARY_COLON);
935
+ const falseExpr = this.parseTernary();
936
+ return (context) => {
937
+ return expr(context) ? trueExpr(context) : falseExpr(context);
938
+ };
939
+ }
940
+ return expr;
941
+ }
942
+ parseLogicalOr() {
943
+ let left = this.parseLogicalAnd();
944
+ while (this.current().type === TokenType.LOGICAL && this.current().value === '||') {
945
+ this.consume(TokenType.LOGICAL);
946
+ const right = this.parseLogicalAnd();
947
+ const prevLeft = left;
948
+ left = (context) => prevLeft(context) || right(context);
949
+ }
950
+ return left;
951
+ }
952
+ parseLogicalAnd() {
953
+ let left = this.parseComparison();
954
+ while (this.current().type === TokenType.LOGICAL && this.current().value === '&&') {
955
+ this.consume(TokenType.LOGICAL);
956
+ const right = this.parseComparison();
957
+ const prevLeft = left;
958
+ left = (context) => prevLeft(context) && right(context);
959
+ }
960
+ return left;
961
+ }
962
+ parseComparison() {
963
+ const left = this.parseAdditive();
964
+ if (this.current().type === TokenType.OPERATOR) {
965
+ const op = this.consume(TokenType.OPERATOR).value;
966
+ const right = this.parseAdditive();
967
+ return (context) => {
968
+ const leftVal = left(context);
969
+ const rightVal = right(context);
970
+ switch (op) {
971
+ case '===':
972
+ return leftVal === rightVal;
973
+ case '!==':
974
+ return leftVal !== rightVal;
975
+ case '==':
976
+ return leftVal == rightVal;
977
+ case '!=':
978
+ return leftVal != rightVal;
979
+ case '<':
980
+ return leftVal < rightVal;
981
+ case '<=':
982
+ return leftVal <= rightVal;
983
+ case '>':
984
+ return leftVal > rightVal;
985
+ case '>=':
986
+ return leftVal >= rightVal;
987
+ default:
988
+ throw new Error(`Unknown operator: ${op}`);
989
+ }
990
+ };
991
+ }
992
+ return left;
993
+ }
994
+ parseAdditive() {
995
+ let left = this.parseMultiplicative();
996
+ while (this.current().type === TokenType.ARITHMETIC &&
997
+ (this.current().value === '+' || this.current().value === '-')) {
998
+ const op = this.consume(TokenType.ARITHMETIC).value;
999
+ const right = this.parseMultiplicative();
1000
+ const prevLeft = left;
1001
+ if (op === '+') {
1002
+ left = (context) => prevLeft(context) + right(context);
1003
+ }
1004
+ else {
1005
+ left = (context) => prevLeft(context) - right(context);
1006
+ }
1007
+ }
1008
+ return left;
1009
+ }
1010
+ parseMultiplicative() {
1011
+ let left = this.parseUnary();
1012
+ while (this.current().type === TokenType.ARITHMETIC &&
1013
+ (this.current().value === '*' || this.current().value === '/' || this.current().value === '%')) {
1014
+ const op = this.consume(TokenType.ARITHMETIC).value;
1015
+ const right = this.parseUnary();
1016
+ const prevLeft = left;
1017
+ if (op === '*') {
1018
+ left = (context) => prevLeft(context) * right(context);
1019
+ }
1020
+ else if (op === '/') {
1021
+ left = (context) => prevLeft(context) / right(context);
1022
+ }
1023
+ else {
1024
+ left = (context) => prevLeft(context) % right(context);
1025
+ }
1026
+ }
1027
+ return left;
1028
+ }
1029
+ parseUnary() {
1030
+ if (this.current().type === TokenType.NOT) {
1031
+ this.consume(TokenType.NOT);
1032
+ const expr = this.parseUnary();
1033
+ return (context) => !expr(context);
1034
+ }
1035
+ return this.parsePrimary();
1036
+ }
1037
+ parsePrimary() {
1038
+ const token = this.current();
1039
+ // Parentheses
1040
+ if (token.type === TokenType.PAREN_OPEN) {
1041
+ this.consume(TokenType.PAREN_OPEN);
1042
+ const expr = this.parseTernary();
1043
+ this.consume(TokenType.PAREN_CLOSE);
1044
+ return expr;
1045
+ }
1046
+ // Literals
1047
+ if (token.type === TokenType.STRING ||
1048
+ token.type === TokenType.NUMBER ||
1049
+ token.type === TokenType.BOOLEAN ||
1050
+ token.type === TokenType.NULL ||
1051
+ token.type === TokenType.UNDEFINED) {
1052
+ const value = token.value;
1053
+ this.pos++;
1054
+ return () => value;
1055
+ }
1056
+ // Property access (model.field, formState.prop, etc)
1057
+ if (token.type === TokenType.IDENTIFIER) {
1058
+ return this.parsePropertyAccess();
1059
+ }
1060
+ throw new Error(`Unexpected token: ${JSON.stringify(token)}`);
1061
+ }
1062
+ parsePropertyAccess() {
1063
+ const path = [];
1064
+ // Read first identifier
1065
+ path.push(this.consume(TokenType.IDENTIFIER).value);
1066
+ // Read rest of path (dots and brackets)
1067
+ while (this.current().type === TokenType.DOT || this.current().type === TokenType.BRACKET_OPEN) {
1068
+ if (this.current().type === TokenType.DOT) {
1069
+ this.consume(TokenType.DOT);
1070
+ path.push(this.consume(TokenType.IDENTIFIER).value);
1071
+ }
1072
+ else {
1073
+ this.consume(TokenType.BRACKET_OPEN);
1074
+ // bracket notation can contain expressions
1075
+ if (this.current().type === TokenType.STRING) {
1076
+ path.push(this.consume(TokenType.STRING).value);
1077
+ }
1078
+ else if (this.current().type === TokenType.NUMBER) {
1079
+ path.push(String(this.consume(TokenType.NUMBER).value));
1080
+ }
1081
+ else {
1082
+ // dynamic property access
1083
+ const expr = this.parseTernary();
1084
+ path.push(expr);
1085
+ }
1086
+ this.consume(TokenType.BRACKET_CLOSE);
1087
+ }
1088
+ }
1089
+ return (context) => {
1090
+ let value = context;
1091
+ for (const segment of path) {
1092
+ if (value === null || value === undefined) {
1093
+ return undefined;
1094
+ }
1095
+ if (typeof segment === 'function') {
1096
+ value = value[segment(context)];
1097
+ }
1098
+ else {
1099
+ value = value[segment];
1100
+ }
1101
+ }
1102
+ return value;
1103
+ };
1104
+ }
1105
+ current() {
1106
+ return this.tokens[this.pos];
1107
+ }
1108
+ consume(expectedType) {
1109
+ const token = this.current();
1110
+ if (token.type !== expectedType) {
1111
+ throw new Error(`Expected ${expectedType}, got ${token.type}`);
1112
+ }
1113
+ this.pos++;
1114
+ return token;
1115
+ }
1116
+ }
1117
+ /**
1118
+ * Uses CSP-safe implementation
1119
+ */
1120
+ function parseExpression(expression, argNames) {
1121
+ try {
1122
+ const tokenizer = new Tokenizer(expression);
1123
+ const tokens = tokenizer.tokenize();
1124
+ const parser = new ExpressionParser(tokens);
1125
+ const evaluator = parser.parse();
1126
+ // Return a function that maps the args to the context
1127
+ return (...args) => {
1128
+ const context = {};
1129
+ argNames.forEach((name, i) => {
1130
+ context[name] = args[i];
1131
+ });
1132
+ return evaluator(context);
1133
+ };
1134
+ }
1135
+ catch (error) {
1136
+ console.error('Expression parse error:', error);
1137
+ return undefined;
1138
+ }
1139
+ }
1140
+
1141
+ class FieldExpressionExtension extends FieldExpressionExtension$1 {
1142
+ _evalStringExpression(expression, argNames) {
1143
+ return parseExpression(expression, argNames);
1144
+ }
673
1145
  }
674
1146
 
675
1147
  class CoreExtension {
@@ -1122,10 +1594,10 @@ class FieldType {
1122
1594
  get formState() {
1123
1595
  return this.options?.formState || {};
1124
1596
  }
1125
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FieldType, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1126
- 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 }); }
1597
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FieldType, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1598
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.25", type: FieldType, isStandalone: true, inputs: { field: "field" }, viewQueries: [{ propertyName: "_formlyControls", predicate: NgControl, descendants: true }], ngImport: i0 }); }
1127
1599
  }
1128
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FieldType, decorators: [{
1600
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FieldType, decorators: [{
1129
1601
  type: Directive
1130
1602
  }], propDecorators: { _formlyControls: [{
1131
1603
  type: ViewChildren,
@@ -1152,15 +1624,16 @@ class FormlyTemplateType extends FieldType {
1152
1624
  this.sanitizer = sanitizer;
1153
1625
  this.innerHtml = {};
1154
1626
  }
1155
- 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 }); }
1156
- 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 }); }
1627
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyTemplateType, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component }); }
1628
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", type: FormlyTemplateType, isStandalone: false, selector: "formly-template", usesInheritance: true, ngImport: i0, template: `<div [innerHtml]="template"></div>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1157
1629
  }
1158
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyTemplateType, decorators: [{
1630
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyTemplateType, decorators: [{
1159
1631
  type: Component,
1160
1632
  args: [{
1161
1633
  selector: 'formly-template',
1162
1634
  template: `<div [innerHtml]="template"></div>`,
1163
1635
  changeDetection: ChangeDetectionStrategy.OnPush,
1636
+ standalone: false,
1164
1637
  }]
1165
1638
  }], ctorParameters: () => [{ type: i1.DomSanitizer }] });
1166
1639
 
@@ -1389,10 +1862,10 @@ class FormlyConfig {
1389
1862
  this.types[name].wrappers = extendedType.wrappers;
1390
1863
  }
1391
1864
  }
1392
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyConfig, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1393
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyConfig, providedIn: 'root' }); }
1865
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyConfig, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1866
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyConfig, providedIn: 'root' }); }
1394
1867
  }
1395
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyConfig, decorators: [{
1868
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyConfig, decorators: [{
1396
1869
  type: Injectable,
1397
1870
  args: [{ providedIn: 'root' }]
1398
1871
  }] });
@@ -1404,10 +1877,10 @@ class FormlyTemplate {
1404
1877
  ngOnChanges() {
1405
1878
  this.name = this.name || 'formly-group';
1406
1879
  }
1407
- 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 }); }
1408
- 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 }); }
1880
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyTemplate, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); }
1881
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.25", type: FormlyTemplate, isStandalone: true, selector: "[formlyTemplate]", inputs: { name: ["formlyTemplate", "name"] }, usesOnChanges: true, ngImport: i0 }); }
1409
1882
  }
1410
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyTemplate, decorators: [{
1883
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyTemplate, decorators: [{
1411
1884
  type: Directive,
1412
1885
  args: [{ selector: '[formlyTemplate]', standalone: true }]
1413
1886
  }], ctorParameters: () => [{ type: i0.TemplateRef }], propDecorators: { name: [{
@@ -1415,19 +1888,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1415
1888
  args: ['formlyTemplate']
1416
1889
  }] } });
1417
1890
  class LegacyFormlyTemplate extends FormlyTemplate {
1418
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyTemplate, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
1419
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: LegacyFormlyTemplate, selector: "[formlyTemplate]", usesInheritance: true, ngImport: i0 }); }
1891
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: LegacyFormlyTemplate, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
1892
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.25", type: LegacyFormlyTemplate, isStandalone: false, selector: "[formlyTemplate]", usesInheritance: true, ngImport: i0 }); }
1420
1893
  }
1421
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyTemplate, decorators: [{
1894
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: LegacyFormlyTemplate, decorators: [{
1422
1895
  type: Directive,
1423
1896
  args: [{ selector: '[formlyTemplate]', standalone: false }]
1424
1897
  }] });
1425
1898
  // workarround for https://github.com/angular/angular/issues/43227#issuecomment-904173738
1426
1899
  class FormlyFieldTemplates {
1427
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyFieldTemplates, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1428
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyFieldTemplates }); }
1900
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyFieldTemplates, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1901
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyFieldTemplates }); }
1429
1902
  }
1430
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyFieldTemplates, decorators: [{
1903
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyFieldTemplates, decorators: [{
1431
1904
  type: Injectable
1432
1905
  }] });
1433
1906
 
@@ -1447,11 +1920,12 @@ class FormlyField {
1447
1920
  }
1448
1921
  return null;
1449
1922
  }
1450
- constructor(config, renderer, _elementRef, hostContainerRef, form) {
1923
+ constructor(config, renderer, _elementRef, hostContainerRef, injector, form) {
1451
1924
  this.config = config;
1452
1925
  this.renderer = renderer;
1453
1926
  this._elementRef = _elementRef;
1454
1927
  this.hostContainerRef = hostContainerRef;
1928
+ this.injector = injector;
1455
1929
  this.form = form;
1456
1930
  this.hostObservers = [];
1457
1931
  this.componentRefs = [];
@@ -1514,7 +1988,7 @@ class FormlyField {
1514
1988
  const inlineType = this.form?.templates?.find((ref) => ref.name === f.type);
1515
1989
  let ref;
1516
1990
  if (inlineType) {
1517
- ref = containerRef.createEmbeddedView(inlineType.ref, { $implicit: f });
1991
+ ref = containerRef.createEmbeddedView(inlineType.ref, { $implicit: f }, { injector: this.createFieldInjector() });
1518
1992
  }
1519
1993
  else {
1520
1994
  const { component } = this.config.getType(f.type, true);
@@ -1542,6 +2016,28 @@ class FormlyField {
1542
2016
  this.render();
1543
2017
  }
1544
2018
  }
2019
+ attachLocalField(field, previousField) {
2020
+ const currentField = this.field;
2021
+ if (!currentField) {
2022
+ return;
2023
+ }
2024
+ const localFields = (currentField._localFields || []).filter((f) => f !== field && f !== previousField);
2025
+ if (field && field !== currentField) {
2026
+ localFields.push(field);
2027
+ }
2028
+ if (currentField._localFields) {
2029
+ currentField._localFields = localFields;
2030
+ }
2031
+ else if (localFields.length > 0) {
2032
+ defineHiddenProp(currentField, '_localFields', localFields);
2033
+ }
2034
+ }
2035
+ createFieldInjector() {
2036
+ return Injector.create({
2037
+ providers: [{ provide: FormlyField, useValue: this }],
2038
+ parent: this.injector,
2039
+ });
2040
+ }
1545
2041
  attachComponentRef(ref, field) {
1546
2042
  this.componentRefs.push(ref);
1547
2043
  field._componentRefs.push(ref);
@@ -1651,7 +2147,7 @@ class FormlyField {
1651
2147
  }
1652
2148
  if (field.formControl && !field.fieldGroup) {
1653
2149
  const control = field.formControl;
1654
- let valueChanges = control.valueChanges.pipe(map((value) => {
2150
+ let valueChanges = control.valueChanges.pipe(startWith(control.value), map((value) => {
1655
2151
  field.parsers?.map((parserFn) => (value = parserFn(value, field)));
1656
2152
  if (!Object.is(value, field.formControl.value)) {
1657
2153
  field.formControl.setValue(value);
@@ -1662,7 +2158,7 @@ class FormlyField {
1662
2158
  return false;
1663
2159
  }
1664
2160
  return true;
1665
- }));
2161
+ }), skip(1));
1666
2162
  if (control.value !== getFieldValue(field)) {
1667
2163
  valueChanges = valueChanges.pipe(startWith(control.value));
1668
2164
  }
@@ -1692,13 +2188,13 @@ class FormlyField {
1692
2188
  templateFieldsSubs.forEach((unsubscribe) => unsubscribe());
1693
2189
  };
1694
2190
  }
1695
- 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 }); }
1696
- 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"] }); }
2191
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", 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 }); }
2192
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", 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"] }); }
1697
2193
  }
1698
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyField, decorators: [{
2194
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyField, decorators: [{
1699
2195
  type: Component,
1700
2196
  args: [{ selector: 'formly-field', template: '<ng-template #container></ng-template>', standalone: true, styles: [":host:empty{display:none}\n"] }]
1701
- }], ctorParameters: () => [{ type: FormlyConfig }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: FormlyFieldTemplates, decorators: [{
2197
+ }], ctorParameters: () => [{ type: FormlyConfig }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i0.Injector }, { type: FormlyFieldTemplates, decorators: [{
1702
2198
  type: Optional
1703
2199
  }] }], propDecorators: { field: [{
1704
2200
  type: Input
@@ -1707,25 +2203,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1707
2203
  args: ['container', { read: ViewContainerRef, static: true }]
1708
2204
  }] } });
1709
2205
  class LegacyFormlyField extends FormlyField {
1710
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyField, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1711
- 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"] }); }
2206
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: LegacyFormlyField, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2207
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", 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"] }); }
1712
2208
  }
1713
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyField, decorators: [{
2209
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: LegacyFormlyField, decorators: [{
1714
2210
  type: Component,
1715
2211
  args: [{ selector: 'formly-field', template: '<ng-template #container></ng-template>', standalone: false, styles: [":host:empty{display:none}\n"] }]
1716
2212
  }] });
1717
2213
 
1718
2214
  /** @ignore */
1719
2215
  class FormlyGroup extends FieldType {
1720
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyGroup, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1721
- 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: `
2216
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyGroup, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2217
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: FormlyGroup, isStandalone: false, selector: "formly-group", host: { properties: { "class": "field.fieldGroupClassName || \"\"" } }, usesInheritance: true, ngImport: i0, template: `
1722
2218
  @for (f of field.fieldGroup; track $index) {
1723
2219
  <formly-field [field]="f"></formly-field>
1724
2220
  }
1725
2221
  <ng-content></ng-content>
1726
2222
  `, isInline: true, dependencies: [{ kind: "component", type: LegacyFormlyField, selector: "formly-field" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1727
2223
  }
1728
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyGroup, decorators: [{
2224
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyGroup, decorators: [{
1729
2225
  type: Component,
1730
2226
  args: [{
1731
2227
  selector: 'formly-group',
@@ -1739,6 +2235,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1739
2235
  '[class]': 'field.fieldGroupClassName || ""',
1740
2236
  },
1741
2237
  changeDetection: ChangeDetectionStrategy.OnPush,
2238
+ standalone: false,
1742
2239
  }]
1743
2240
  }] });
1744
2241
 
@@ -1756,12 +2253,28 @@ function withDefaultConfig(config) {
1756
2253
  { name: 'core', extension: new CoreExtension(config), priority: -250 },
1757
2254
  { name: 'field-validation', extension: new FieldValidationExtension(config), priority: -200 },
1758
2255
  { name: 'field-form', extension: new FieldFormExtension(), priority: -150 },
1759
- { name: 'field-expression', extension: new FieldExpressionExtension(), priority: -100 },
2256
+ {
2257
+ name: 'field-expression',
2258
+ extension: new FieldExpressionExtension$1(),
2259
+ priority: -100,
2260
+ },
2261
+ ],
2262
+ };
2263
+ }
2264
+ function withFormlyFieldExpression() {
2265
+ return {
2266
+ extensions: [
2267
+ {
2268
+ name: 'field-expression',
2269
+ extension: new FieldExpressionExtension(),
2270
+ priority: -100,
2271
+ },
1760
2272
  ],
1761
2273
  };
1762
2274
  }
1763
2275
  const provideFormlyCore = (configs = []) => {
1764
2276
  return [
2277
+ FormlyConfig,
1765
2278
  { provide: FORMLY_CONFIG, multi: true, useFactory: withDefaultConfig, deps: [FormlyConfig] },
1766
2279
  provideFormlyConfig(configs),
1767
2280
  ];
@@ -1775,8 +2288,9 @@ const provideFormlyConfig = (configs = []) => {
1775
2288
  skipSelf: true,
1776
2289
  optional: true,
1777
2290
  });
1778
- if (currentConfig) {
1779
- currentConfig.push(configs);
2291
+ if (currentConfig && inject(FormlyConfig) === inject(FormlyConfig, { skipSelf: true, optional: true })) {
2292
+ configs = Array.isArray(configs) ? configs : [configs];
2293
+ currentConfig.push(...configs);
1780
2294
  return currentConfig;
1781
2295
  }
1782
2296
  return configs;
@@ -1858,10 +2372,10 @@ class FormlyFormBuilder {
1858
2372
  }
1859
2373
  }
1860
2374
  }
1861
- 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 }); }
1862
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyFormBuilder, providedIn: 'root' }); }
2375
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", 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 }); }
2376
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyFormBuilder, providedIn: 'root' }); }
1863
2377
  }
1864
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyFormBuilder, decorators: [{
2378
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyFormBuilder, decorators: [{
1865
2379
  type: Injectable,
1866
2380
  args: [{ providedIn: 'root' }]
1867
2381
  }], ctorParameters: () => [{ type: FormlyConfig }, { type: i0.Injector }, { type: i0.ViewContainerRef, decorators: [{
@@ -1985,18 +2499,18 @@ class FormlyForm {
1985
2499
  Object.keys(field).forEach((p) => (this.field[p] = field[p]));
1986
2500
  }
1987
2501
  }
1988
- 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 }); }
1989
- 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 }); }
2502
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyForm, deps: [{ token: FormlyFormBuilder }, { token: FormlyConfig }, { token: i0.NgZone }, { token: FormlyFieldTemplates }], target: i0.ɵɵFactoryTarget.Component }); }
2503
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", 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 }); }
1990
2504
  }
1991
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyForm, decorators: [{
2505
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyForm, decorators: [{
1992
2506
  type: Component,
1993
2507
  args: [{
1994
2508
  selector: 'formly-form',
1995
2509
  template: '<formly-field [field]="field"></formly-field>',
1996
2510
  providers: [FormlyFormBuilder, FormlyFieldTemplates],
2511
+ standalone: true,
1997
2512
  imports: [FormlyField],
1998
2513
  changeDetection: ChangeDetectionStrategy.OnPush,
1999
- standalone: true,
2000
2514
  }]
2001
2515
  }], ctorParameters: () => [{ type: FormlyFormBuilder }, { type: FormlyConfig }, { type: i0.NgZone }, { type: FormlyFieldTemplates }], propDecorators: { form: [{
2002
2516
  type: Input
@@ -2016,10 +2530,10 @@ class LegacyFormlyForm extends FormlyForm {
2016
2530
  set templates(templates) {
2017
2531
  this.fieldTemplates.templates = templates;
2018
2532
  }
2019
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyForm, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2020
- 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 }); }
2533
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: LegacyFormlyForm, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2534
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", 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 }); }
2021
2535
  }
2022
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyForm, decorators: [{
2536
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: LegacyFormlyForm, decorators: [{
2023
2537
  type: Component,
2024
2538
  args: [{
2025
2539
  selector: 'formly-form',
@@ -2043,9 +2557,10 @@ class FormlyAttributes {
2043
2557
  get fieldAttrElements() {
2044
2558
  return this.field?.['_elementRefs'] || [];
2045
2559
  }
2046
- constructor(renderer, elementRef, _document) {
2560
+ constructor(renderer, elementRef, _document, formlyField) {
2047
2561
  this.renderer = renderer;
2048
2562
  this.elementRef = elementRef;
2563
+ this.formlyField = formlyField;
2049
2564
  this.uiAttributesCache = {};
2050
2565
  /**
2051
2566
  * HostBinding doesn't register listeners conditionally which may produce some perf issues.
@@ -2093,8 +2608,10 @@ class FormlyAttributes {
2093
2608
  }
2094
2609
  });
2095
2610
  }
2096
- this.detachElementRef(changes.field.previousValue);
2611
+ const previousField = changes.field.previousValue;
2612
+ this.detachElementRef(previousField);
2097
2613
  this.attachElementRef(changes.field.currentValue);
2614
+ this.formlyField?.attachLocalField(changes.field.currentValue, previousField?._elementRefs?.length ? undefined : previousField);
2098
2615
  if (this.fieldAttrElements.length === 1) {
2099
2616
  !this.id && this.field.id && this.setAttribute('id', this.field.id);
2100
2617
  this.focusObserver = observe(this.field, ['focus'], ({ currentValue }) => {
@@ -2126,7 +2643,7 @@ class FormlyAttributes {
2126
2643
  (!this.props.attributes || !this.props.attributes.hasOwnProperty(attr.toLowerCase()))) {
2127
2644
  this.uiAttributesCache[attr] = value;
2128
2645
  if (value || value === 0) {
2129
- this.setAttribute(attr, value === true ? attr : `${value}`);
2646
+ this.setAttribute(attr, this.getSafeAttributeValue(attr, value));
2130
2647
  }
2131
2648
  else {
2132
2649
  this.removeAttribute(attr);
@@ -2137,6 +2654,9 @@ class FormlyAttributes {
2137
2654
  ngOnDestroy() {
2138
2655
  this.uiEvents.listeners.forEach((listener) => listener());
2139
2656
  this.detachElementRef(this.field);
2657
+ if (!this.field?._elementRefs?.length) {
2658
+ this.formlyField?.attachLocalField(undefined, this.field);
2659
+ }
2140
2660
  this.focusObserver?.unsubscribe();
2141
2661
  }
2142
2662
  toggleFocus(value) {
@@ -2184,21 +2704,33 @@ class FormlyAttributes {
2184
2704
  }
2185
2705
  }
2186
2706
  detachElementRef(f) {
2187
- const index = f?.['_elementRefs'] ? this.fieldAttrElements.indexOf(this.elementRef) : -1;
2707
+ const elements = f?.['_elementRefs'] || [];
2708
+ const index = elements.indexOf(this.elementRef);
2188
2709
  if (index !== -1) {
2189
- f['_elementRefs'].splice(index, 1);
2710
+ elements.splice(index, 1);
2190
2711
  }
2191
2712
  }
2713
+ getSafeAttributeValue(attr, value) {
2714
+ if (attr === 'pattern') {
2715
+ let pattern = value instanceof RegExp ? value.source : value;
2716
+ // 1. Safely escape unescaped hyphens inside character classes for 'v' flag compatibility
2717
+ pattern = pattern.replace(/(\[[^\]]*?)(?<!\\)-(.*?\])/g, '$1\\-$2');
2718
+ // 2. Cleanly strip leading ^ and trailing $ so HTML5 handles the boundaries natively
2719
+ pattern = pattern.replace(/^^\^/, '').replace(/\$$/, '');
2720
+ return pattern;
2721
+ }
2722
+ return value === true ? attr : `${value}`;
2723
+ }
2192
2724
  setAttribute(attr, value) {
2193
2725
  this.renderer.setAttribute(this.elementRef.nativeElement, attr, value);
2194
2726
  }
2195
2727
  removeAttribute(attr) {
2196
2728
  this.renderer.removeAttribute(this.elementRef.nativeElement, attr);
2197
2729
  }
2198
- 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 }); }
2199
- 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 }); }
2730
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyAttributes, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: DOCUMENT }, { token: FormlyField, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
2731
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.25", type: FormlyAttributes, isStandalone: true, selector: "[formlyAttributes]", inputs: { field: ["formlyAttributes", "field"], id: "id" }, host: { listeners: { "change": "onHostChange($event)" } }, usesOnChanges: true, ngImport: i0 }); }
2200
2732
  }
2201
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyAttributes, decorators: [{
2733
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyAttributes, decorators: [{
2202
2734
  type: Directive,
2203
2735
  args: [{
2204
2736
  selector: '[formlyAttributes]',
@@ -2210,6 +2742,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2210
2742
  }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: undefined, decorators: [{
2211
2743
  type: Inject,
2212
2744
  args: [DOCUMENT]
2745
+ }] }, { type: FormlyField, decorators: [{
2746
+ type: Optional
2213
2747
  }] }], propDecorators: { field: [{
2214
2748
  type: Input,
2215
2749
  args: ['formlyAttributes']
@@ -2217,16 +2751,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2217
2751
  type: Input
2218
2752
  }] } });
2219
2753
  class LegacyFormlyAttributes extends FormlyAttributes {
2220
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyAttributes, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2221
- 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 }); }
2754
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: LegacyFormlyAttributes, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2755
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.25", type: LegacyFormlyAttributes, isStandalone: false, selector: "[formlyAttributes]", host: { listeners: { "change": "onHostChange($event)" } }, usesInheritance: true, ngImport: i0 }); }
2222
2756
  }
2223
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyAttributes, decorators: [{
2757
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: LegacyFormlyAttributes, decorators: [{
2224
2758
  type: Directive,
2225
2759
  args: [{
2226
2760
  selector: '[formlyAttributes]',
2227
2761
  host: {
2228
2762
  '(change)': 'onHostChange($event)',
2229
2763
  },
2764
+ standalone: false,
2230
2765
  }]
2231
2766
  }] });
2232
2767
 
@@ -2277,10 +2812,10 @@ class FormlyValidationMessage {
2277
2812
  }
2278
2813
  return undefined;
2279
2814
  }
2280
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyValidationMessage, deps: [{ token: FormlyConfig }], target: i0.ɵɵFactoryTarget.Component }); }
2281
- 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 }); }
2815
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyValidationMessage, deps: [{ token: FormlyConfig }], target: i0.ɵɵFactoryTarget.Component }); }
2816
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", 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 }); }
2282
2817
  }
2283
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyValidationMessage, decorators: [{
2818
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyValidationMessage, decorators: [{
2284
2819
  type: Component,
2285
2820
  args: [{
2286
2821
  selector: 'formly-validation-message',
@@ -2293,15 +2828,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2293
2828
  type: Input
2294
2829
  }] } });
2295
2830
  class LegacyFormlyValidationMessage extends FormlyValidationMessage {
2296
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyValidationMessage, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2297
- 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 }); }
2831
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: LegacyFormlyValidationMessage, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2832
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", 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 }); }
2298
2833
  }
2299
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LegacyFormlyValidationMessage, decorators: [{
2834
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: LegacyFormlyValidationMessage, decorators: [{
2300
2835
  type: Component,
2301
2836
  args: [{
2302
2837
  selector: 'formly-validation-message',
2303
2838
  template: '{{ errorMessage$ | async }}',
2304
2839
  changeDetection: ChangeDetectionStrategy.OnPush,
2840
+ standalone: false,
2305
2841
  }]
2306
2842
  }] });
2307
2843
 
@@ -2376,10 +2912,10 @@ class FieldArrayType extends FieldType {
2376
2912
  this.options._hiddenFieldsForCheck.push({ field: f });
2377
2913
  }
2378
2914
  }
2379
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FieldArrayType, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2380
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: FieldArrayType, usesInheritance: true, ngImport: i0 }); }
2915
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FieldArrayType, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2916
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.25", type: FieldArrayType, isStandalone: true, usesInheritance: true, ngImport: i0 }); }
2381
2917
  }
2382
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FieldArrayType, decorators: [{
2918
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FieldArrayType, decorators: [{
2383
2919
  type: Directive
2384
2920
  }] });
2385
2921
 
@@ -2388,10 +2924,10 @@ class FieldWrapper extends FieldType {
2388
2924
  set _staticContent(content) {
2389
2925
  this.fieldComponent = content;
2390
2926
  }
2391
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FieldWrapper, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2392
- 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 }); }
2927
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FieldWrapper, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2928
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.25", 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 }); }
2393
2929
  }
2394
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FieldWrapper, decorators: [{
2930
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FieldWrapper, decorators: [{
2395
2931
  type: Directive
2396
2932
  }], propDecorators: { fieldComponent: [{
2397
2933
  type: ViewChild,
@@ -2401,6 +2937,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2401
2937
  args: ['fieldComponent', { read: ViewContainerRef, static: true }]
2402
2938
  }] } });
2403
2939
 
2940
+ /**
2941
+ * Registers Formly components and configuration for NgModule-based applications.
2942
+ *
2943
+ * `forRoot()` provides the shared `FormlyConfig` at the application root, while
2944
+ * `forChild()` adds feature configuration using the inherited service. This follows
2945
+ * Angular's [root/child module registration convention](https://frontendatlas.com/angular/trivia/angular-forroot-forchild).
2946
+ */
2404
2947
  class FormlyModule {
2405
2948
  static forRoot(config = {}) {
2406
2949
  return {
@@ -2423,8 +2966,8 @@ class FormlyModule {
2423
2966
  ],
2424
2967
  };
2425
2968
  }
2426
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2427
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: FormlyModule, declarations: [LegacyFormlyTemplate,
2969
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2970
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.25", ngImport: i0, type: FormlyModule, declarations: [LegacyFormlyTemplate,
2428
2971
  LegacyFormlyForm,
2429
2972
  LegacyFormlyField,
2430
2973
  LegacyFormlyAttributes,
@@ -2436,9 +2979,9 @@ class FormlyModule {
2436
2979
  LegacyFormlyAttributes,
2437
2980
  LegacyFormlyValidationMessage,
2438
2981
  FormlyGroup] }); }
2439
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyModule, imports: [CommonModule] }); }
2982
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyModule, imports: [CommonModule] }); }
2440
2983
  }
2441
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyModule, decorators: [{
2984
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormlyModule, decorators: [{
2442
2985
  type: NgModule,
2443
2986
  args: [{
2444
2987
  declarations: [
@@ -2470,5 +3013,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2470
3013
  * Generated bundle index. Do not edit.
2471
3014
  */
2472
3015
 
2473
- export { FORMLY_CONFIG, FieldArrayType, FieldType, FieldWrapper, FormlyAttributes, FormlyConfig, FormlyField, FormlyForm, FormlyFormBuilder, FormlyModule, FormlyTemplate, FormlyValidationMessage, LegacyFormlyAttributes, LegacyFormlyField, LegacyFormlyForm, LegacyFormlyValidationMessage, provideFormlyConfig, provideFormlyCore, FormlyGroup as ɵFormlyGroup, LegacyFormlyTemplate as ɵFormlyTemplate, clone as ɵclone, defineHiddenProp as ɵdefineHiddenProp, getFieldValue as ɵgetFieldValue, hasKey as ɵhasKey, observe as ɵobserve, reverseDeepMerge as ɵreverseDeepMerge };
3016
+ export { FORMLY_CONFIG, FieldArrayType, FieldType, FieldWrapper, FormlyAttributes, FormlyConfig, FormlyField, FormlyForm, FormlyFormBuilder, FormlyModule, FormlyTemplate, FormlyValidationMessage, LegacyFormlyAttributes, LegacyFormlyField, LegacyFormlyForm, LegacyFormlyValidationMessage, provideFormlyConfig, provideFormlyCore, withFormlyFieldExpression, FormlyGroup as ɵFormlyGroup, LegacyFormlyTemplate as ɵFormlyTemplate, clone as ɵclone, defineHiddenProp as ɵdefineHiddenProp, getFieldValue as ɵgetFieldValue, hasKey as ɵhasKey, observe as ɵobserve, reverseDeepMerge as ɵreverseDeepMerge };
2474
3017
  //# sourceMappingURL=ngx-formly-core.mjs.map