@angular/forms 21.2.0-next.2 → 21.2.0-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,64 +1,13 @@
1
1
  /**
2
- * @license Angular v21.2.0-next.2
2
+ * @license Angular v21.2.0-next.3
3
3
  * (c) 2010-2026 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
6
6
 
7
- import { FormGroup, FormArray, AbstractControl } from '@angular/forms';
8
7
  import { untracked, ɵRuntimeError as _RuntimeError, computed, runInInjectionContext, Injector, linkedSignal, signal, APP_ID, effect, inject } from '@angular/core';
8
+ import { AbstractControl, FormGroup, FormArray } from '@angular/forms';
9
9
  import { SIGNAL } from '@angular/core/primitives/signals';
10
10
 
11
- class CompatValidationError {
12
- kind = 'compat';
13
- control;
14
- fieldTree;
15
- context;
16
- message;
17
- constructor({
18
- context,
19
- kind,
20
- control
21
- }) {
22
- this.context = context;
23
- this.kind = kind;
24
- this.control = control;
25
- }
26
- }
27
- function signalErrorsToValidationErrors(errors) {
28
- if (errors.length === 0) {
29
- return null;
30
- }
31
- const errObj = {};
32
- for (const error of errors) {
33
- errObj[error.kind] = error instanceof CompatValidationError ? error.context : error;
34
- }
35
- return errObj;
36
- }
37
- function reactiveErrorsToSignalErrors(errors, control) {
38
- if (errors === null) {
39
- return [];
40
- }
41
- return Object.entries(errors).map(([kind, context]) => {
42
- return new CompatValidationError({
43
- context,
44
- kind,
45
- control
46
- });
47
- });
48
- }
49
- function extractNestedReactiveErrors(control) {
50
- const errors = [];
51
- if (control.errors) {
52
- errors.push(...reactiveErrorsToSignalErrors(control.errors, control));
53
- }
54
- if (control instanceof FormGroup || control instanceof FormArray) {
55
- for (const c of Object.values(control.controls)) {
56
- errors.push(...extractNestedReactiveErrors(c));
57
- }
58
- }
59
- return errors;
60
- }
61
-
62
11
  let boundPathDepth = 0;
63
12
  function getBoundPathDepth() {
64
13
  return boundPathDepth;
@@ -679,7 +628,7 @@ class FieldValidationState {
679
628
  }, ...(ngDevMode ? [{
680
629
  debugName: "syncValid"
681
630
  }] : []));
682
- syncTreeErrors = computed(() => this.rawSyncTreeErrors().filter(err => err.fieldTree === this.node.fieldProxy), ...(ngDevMode ? [{
631
+ syncTreeErrors = computed(() => this.rawSyncTreeErrors().filter(err => err.fieldTree === this.node.fieldTree), ...(ngDevMode ? [{
683
632
  debugName: "syncTreeErrors"
684
633
  }] : []));
685
634
  rawAsyncErrors = computed(() => {
@@ -694,7 +643,7 @@ class FieldValidationState {
694
643
  if (this.shouldSkipValidation()) {
695
644
  return [];
696
645
  }
697
- return this.rawAsyncErrors().filter(err => err === 'pending' || err.fieldTree === this.node.fieldProxy);
646
+ return this.rawAsyncErrors().filter(err => err === 'pending' || err.fieldTree === this.node.fieldTree);
698
647
  }, ...(ngDevMode ? [{
699
648
  debugName: "asyncErrors"
700
649
  }] : []));
@@ -803,7 +752,7 @@ class FieldNodeContext {
803
752
  throw new _RuntimeError(1901, ngDevMode && `Cannot resolve path .${targetPathNode.keys.join('.')} relative to field ${['<root>', ...this.node.structure.pathKeys()].join('.')}.`);
804
753
  }
805
754
  }
806
- return field.fieldProxy;
755
+ return field.fieldTree;
807
756
  }, ...(ngDevMode ? [{
808
757
  debugName: "resolver"
809
758
  }] : []));
@@ -881,7 +830,7 @@ const FIELD_PROXY_HANDLER = {
881
830
  const tgt = getTgt();
882
831
  const child = tgt.structure.getChild(p);
883
832
  if (child !== undefined) {
884
- return child.fieldProxy;
833
+ return child.fieldTree;
885
834
  }
886
835
  const value = untracked(tgt.value);
887
836
  if (isArray(value)) {
@@ -891,7 +840,7 @@ const FIELD_PROXY_HANDLER = {
891
840
  if (p === Symbol.iterator) {
892
841
  return () => {
893
842
  tgt.value();
894
- return Array.prototype[Symbol.iterator].apply(tgt.fieldProxy);
843
+ return Array.prototype[Symbol.iterator].apply(tgt.fieldTree);
895
844
  };
896
845
  }
897
846
  }
@@ -1272,6 +1221,9 @@ class FieldNode {
1272
1221
  return undefined;
1273
1222
  }
1274
1223
  });
1224
+ get fieldTree() {
1225
+ return this.fieldProxy;
1226
+ }
1275
1227
  get logicNode() {
1276
1228
  return this.structure.logic;
1277
1229
  }
@@ -1626,7 +1578,7 @@ function form(...args) {
1626
1578
  const adapter = options?.adapter ?? new BasicFieldAdapter();
1627
1579
  const fieldRoot = FieldNode.newRoot(fieldManager, model, pathNode, adapter);
1628
1580
  fieldManager.createFieldManagementEffect(fieldRoot.structure);
1629
- return fieldRoot.fieldProxy;
1581
+ return fieldRoot.fieldTree;
1630
1582
  }
1631
1583
  function applyEach(path, schema) {
1632
1584
  assertPathIsCurrent(path);
@@ -1652,19 +1604,21 @@ function applyWhenValue(path, predicate, schema) {
1652
1604
  }) => predicate(value()), schema);
1653
1605
  }
1654
1606
  async function submit(form, options) {
1655
- const node = form();
1656
- const opts = typeof options === 'function' ? {
1657
- action: options
1658
- } : {
1659
- ...(node.structure.fieldManager.submitOptions ?? {}),
1660
- ...(options ?? {})
1607
+ const node = untracked(form);
1608
+ const field = options === undefined ? node.structure.root.fieldProxy : form;
1609
+ const detail = {
1610
+ root: node.structure.root.fieldProxy,
1611
+ submitted: form
1661
1612
  };
1662
- const action = opts?.action;
1613
+ options = typeof options === 'function' ? {
1614
+ action: options
1615
+ } : options ?? node.structure.fieldManager.submitOptions;
1616
+ const action = options?.action;
1663
1617
  if (!action) {
1664
- throw new _RuntimeError(1915, ngDevMode && 'Cannot submit form with no submit action. Specify the action when creating the form, or as an additional argument to `submit()`.');
1618
+ throw new _RuntimeError(1915, (typeof ngDevMode === 'undefined' || ngDevMode) && 'Cannot submit form with no submit action. Specify the action when creating the form, or as an additional argument to `submit()`.');
1665
1619
  }
1666
- const onInvalid = opts?.onInvalid;
1667
- const ignoreValidators = opts?.ignoreValidators ?? 'pending';
1620
+ const onInvalid = options?.onInvalid;
1621
+ const ignoreValidators = options?.ignoreValidators ?? 'pending';
1668
1622
  let shouldRunAction = true;
1669
1623
  untracked(() => {
1670
1624
  markAllAsTouched(node);
@@ -1677,24 +1631,36 @@ async function submit(form, options) {
1677
1631
  try {
1678
1632
  if (shouldRunAction) {
1679
1633
  node.submitState.selfSubmitting.set(true);
1680
- const errors = await untracked(() => action?.(form));
1634
+ const errors = await untracked(() => action?.(field, detail));
1681
1635
  errors && setSubmissionErrors(node, errors);
1682
1636
  return !errors || isArray(errors) && errors.length === 0;
1683
1637
  } else {
1684
- untracked(() => onInvalid?.(form));
1638
+ untracked(() => onInvalid?.(field, detail));
1685
1639
  }
1686
1640
  return false;
1687
1641
  } finally {
1688
1642
  node.submitState.selfSubmitting.set(false);
1689
1643
  }
1690
1644
  }
1645
+ function schema(fn) {
1646
+ return SchemaImpl.create(fn);
1647
+ }
1648
+ function markAllAsTouched(node) {
1649
+ if (node.validationState.shouldSkipValidation()) {
1650
+ return;
1651
+ }
1652
+ node.markAsTouched();
1653
+ for (const child of node.structure.children()) {
1654
+ markAllAsTouched(child);
1655
+ }
1656
+ }
1691
1657
  function setSubmissionErrors(submittedField, errors) {
1692
1658
  if (!isArray(errors)) {
1693
1659
  errors = [errors];
1694
1660
  }
1695
1661
  const errorsByField = new Map();
1696
1662
  for (const error of errors) {
1697
- const errorWithField = addDefaultField(error, submittedField.fieldProxy);
1663
+ const errorWithField = addDefaultField(error, submittedField.fieldTree);
1698
1664
  const field = errorWithField.fieldTree();
1699
1665
  let fieldErrors = errorsByField.get(field);
1700
1666
  if (!fieldErrors) {
@@ -1707,18 +1673,57 @@ function setSubmissionErrors(submittedField, errors) {
1707
1673
  field.submitState.submissionErrors.set(fieldErrors);
1708
1674
  }
1709
1675
  }
1710
- function schema(fn) {
1711
- return SchemaImpl.create(fn);
1676
+
1677
+ class CompatValidationError {
1678
+ kind = 'compat';
1679
+ control;
1680
+ fieldTree;
1681
+ context;
1682
+ message;
1683
+ constructor({
1684
+ context,
1685
+ kind,
1686
+ control
1687
+ }) {
1688
+ this.context = context;
1689
+ this.kind = kind;
1690
+ this.control = control;
1691
+ }
1712
1692
  }
1713
- function markAllAsTouched(node) {
1714
- if (node.validationState.shouldSkipValidation()) {
1715
- return;
1693
+ function signalErrorsToValidationErrors(errors) {
1694
+ if (errors.length === 0) {
1695
+ return null;
1716
1696
  }
1717
- node.markAsTouched();
1718
- for (const child of node.structure.children()) {
1719
- markAllAsTouched(child);
1697
+ const errObj = {};
1698
+ for (const error of errors) {
1699
+ errObj[error.kind] = error instanceof CompatValidationError ? error.context : error;
1700
+ }
1701
+ return errObj;
1702
+ }
1703
+ function reactiveErrorsToSignalErrors(errors, control) {
1704
+ if (errors === null) {
1705
+ return [];
1706
+ }
1707
+ return Object.entries(errors).map(([kind, context]) => {
1708
+ return new CompatValidationError({
1709
+ context,
1710
+ kind,
1711
+ control
1712
+ });
1713
+ });
1714
+ }
1715
+ function extractNestedReactiveErrors(control) {
1716
+ const errors = [];
1717
+ if (control.errors) {
1718
+ errors.push(...reactiveErrorsToSignalErrors(control.errors, control));
1720
1719
  }
1720
+ if (control instanceof FormGroup || control instanceof FormArray) {
1721
+ for (const c of Object.values(control.controls)) {
1722
+ errors.push(...extractNestedReactiveErrors(c));
1723
+ }
1724
+ }
1725
+ return errors;
1721
1726
  }
1722
1727
 
1723
1728
  export { BasicFieldAdapter, CompatValidationError, DEBOUNCER, FieldNode, FieldNodeState, FieldNodeStructure, FieldPathNode, MAX, MAX_LENGTH, MIN, MIN_LENGTH, MetadataKey, MetadataReducer, PATTERN, REQUIRED, addDefaultField, apply, applyEach, applyWhen, applyWhenValue, assertPathIsCurrent, calculateValidationSelfStatus, createManagedMetadataKey, createMetadataKey, extractNestedReactiveErrors, form, getInjectorFromOptions, metadata, normalizeFormArgs, schema, signalErrorsToValidationErrors, submit };
1724
- //# sourceMappingURL=_structure-chunk.mjs.map
1729
+ //# sourceMappingURL=_validation_errors-chunk.mjs.map