@angular/forms 21.1.0-next.3 → 21.1.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/fesm2022/_structure-chunk.mjs +34 -34
- package/fesm2022/_structure-chunk.mjs.map +1 -1
- package/fesm2022/forms.mjs +133 -132
- package/fesm2022/forms.mjs.map +1 -1
- package/fesm2022/signals-compat.mjs +26 -12
- package/fesm2022/signals-compat.mjs.map +1 -1
- package/fesm2022/signals.mjs +159 -78
- package/fesm2022/signals.mjs.map +1 -1
- package/package.json +12 -6
- package/resources/code-examples.db +0 -0
- package/types/_structure-chunk.d.ts +129 -73
- package/types/forms.d.ts +26 -9
- package/types/signals-compat.d.ts +3 -3
- package/types/signals.d.ts +155 -145
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
The MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2010-
|
|
3
|
+
Copyright (c) 2010-2026 Google LLC. https://angular.dev/license
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v21.1.0-
|
|
3
|
-
* (c) 2010-
|
|
2
|
+
* @license Angular v21.1.0-rc.0
|
|
3
|
+
* (c) 2010-2026 Google LLC. https://angular.dev/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { untracked, computed, runInInjectionContext, Injector, linkedSignal, signal, APP_ID, effect, inject } from '@angular/core';
|
|
7
|
+
import { untracked, ɵRuntimeError as _RuntimeError, computed, runInInjectionContext, Injector, linkedSignal, signal, APP_ID, effect, inject } from '@angular/core';
|
|
8
8
|
import { AbstractControl } from '@angular/forms';
|
|
9
9
|
import { SIGNAL } from '@angular/core/primitives/signals';
|
|
10
10
|
|
|
@@ -384,7 +384,7 @@ function getAllChildBuilders(builder, key) {
|
|
|
384
384
|
predicates: []
|
|
385
385
|
}] : [])];
|
|
386
386
|
} else {
|
|
387
|
-
throw new
|
|
387
|
+
throw new _RuntimeError(1909, ngDevMode && 'Unknown LogicNodeBuilder type');
|
|
388
388
|
}
|
|
389
389
|
}
|
|
390
390
|
function createLogic(builder, predicates, depth) {
|
|
@@ -400,7 +400,7 @@ function createLogic(builder, predicates, depth) {
|
|
|
400
400
|
} else if (builder instanceof NonMergeableLogicNodeBuilder) {
|
|
401
401
|
logic.mergeIn(builder.logic);
|
|
402
402
|
} else {
|
|
403
|
-
throw new
|
|
403
|
+
throw new _RuntimeError(1909, ngDevMode && 'Unknown LogicNodeBuilder type');
|
|
404
404
|
}
|
|
405
405
|
return logic;
|
|
406
406
|
}
|
|
@@ -509,7 +509,7 @@ function isSchemaOrSchemaFn(value) {
|
|
|
509
509
|
}
|
|
510
510
|
function assertPathIsCurrent(path) {
|
|
511
511
|
if (currentCompilingNode !== FieldPathNode.unwrapFieldPath(path).root) {
|
|
512
|
-
throw new
|
|
512
|
+
throw new _RuntimeError(1908, ngDevMode && `A FieldPath can only be used directly within the Schema that owns it, **not** outside of it or within a sub-schema.`);
|
|
513
513
|
}
|
|
514
514
|
}
|
|
515
515
|
|
|
@@ -616,7 +616,7 @@ class FieldValidationState {
|
|
|
616
616
|
if (this.shouldSkipValidation()) {
|
|
617
617
|
return [];
|
|
618
618
|
}
|
|
619
|
-
return [...this.node.logicNode.logic.syncErrors.compute(this.node.context), ...this.syncTreeErrors(), ...normalizeErrors(this.node.submitState.
|
|
619
|
+
return [...this.node.logicNode.logic.syncErrors.compute(this.node.context), ...this.syncTreeErrors(), ...normalizeErrors(this.node.submitState.submissionErrors())];
|
|
620
620
|
}, ...(ngDevMode ? [{
|
|
621
621
|
debugName: "syncErrors"
|
|
622
622
|
}] : []));
|
|
@@ -628,7 +628,7 @@ class FieldValidationState {
|
|
|
628
628
|
}, ...(ngDevMode ? [{
|
|
629
629
|
debugName: "syncValid"
|
|
630
630
|
}] : []));
|
|
631
|
-
syncTreeErrors = computed(() => this.rawSyncTreeErrors().filter(err => err.
|
|
631
|
+
syncTreeErrors = computed(() => this.rawSyncTreeErrors().filter(err => err.fieldTree === this.node.fieldProxy), ...(ngDevMode ? [{
|
|
632
632
|
debugName: "syncTreeErrors"
|
|
633
633
|
}] : []));
|
|
634
634
|
rawAsyncErrors = computed(() => {
|
|
@@ -643,7 +643,7 @@ class FieldValidationState {
|
|
|
643
643
|
if (this.shouldSkipValidation()) {
|
|
644
644
|
return [];
|
|
645
645
|
}
|
|
646
|
-
return this.rawAsyncErrors().filter(err => err === 'pending' || err.
|
|
646
|
+
return this.rawAsyncErrors().filter(err => err === 'pending' || err.fieldTree === this.node.fieldProxy);
|
|
647
647
|
}, ...(ngDevMode ? [{
|
|
648
648
|
debugName: "asyncErrors"
|
|
649
649
|
}] : []));
|
|
@@ -691,13 +691,13 @@ function normalizeErrors(error) {
|
|
|
691
691
|
}
|
|
692
692
|
return [error];
|
|
693
693
|
}
|
|
694
|
-
function addDefaultField(errors,
|
|
694
|
+
function addDefaultField(errors, fieldTree) {
|
|
695
695
|
if (isArray(errors)) {
|
|
696
696
|
for (const error of errors) {
|
|
697
|
-
error.
|
|
697
|
+
error.fieldTree ??= fieldTree;
|
|
698
698
|
}
|
|
699
699
|
} else if (errors) {
|
|
700
|
-
errors.
|
|
700
|
+
errors.fieldTree ??= fieldTree;
|
|
701
701
|
}
|
|
702
702
|
return errors;
|
|
703
703
|
}
|
|
@@ -720,13 +720,13 @@ class FieldNodeContext {
|
|
|
720
720
|
stepsRemaining--;
|
|
721
721
|
field = field.structure.parent;
|
|
722
722
|
if (field === undefined) {
|
|
723
|
-
throw new
|
|
723
|
+
throw new _RuntimeError(1900, ngDevMode && 'Path is not part of this field tree.');
|
|
724
724
|
}
|
|
725
725
|
}
|
|
726
726
|
for (let key of targetPathNode.keys) {
|
|
727
727
|
field = field.structure.getChild(key);
|
|
728
728
|
if (field === undefined) {
|
|
729
|
-
throw new
|
|
729
|
+
throw new _RuntimeError(1901, ngDevMode && `Cannot resolve path .${targetPathNode.keys.join('.')} relative to field ${['<root>', ...this.node.structure.pathKeys()].join('.')}.`);
|
|
730
730
|
}
|
|
731
731
|
}
|
|
732
732
|
return field.fieldProxy;
|
|
@@ -737,7 +737,7 @@ class FieldNodeContext {
|
|
|
737
737
|
}
|
|
738
738
|
return this.cache.get(target)();
|
|
739
739
|
}
|
|
740
|
-
get
|
|
740
|
+
get fieldTree() {
|
|
741
741
|
return this.node.fieldProxy;
|
|
742
742
|
}
|
|
743
743
|
get state() {
|
|
@@ -755,7 +755,7 @@ class FieldNodeContext {
|
|
|
755
755
|
index = computed(() => {
|
|
756
756
|
const key = this.key();
|
|
757
757
|
if (!isArray(untracked(this.node.structure.parent.value))) {
|
|
758
|
-
throw new
|
|
758
|
+
throw new _RuntimeError(1906, ngDevMode && 'Cannot access index, parent field is not an array.');
|
|
759
759
|
}
|
|
760
760
|
return Number(key);
|
|
761
761
|
}, ...(ngDevMode ? [{
|
|
@@ -766,7 +766,7 @@ class FieldNodeContext {
|
|
|
766
766
|
valueOf = p => {
|
|
767
767
|
const result = this.resolve(p)().value();
|
|
768
768
|
if (result instanceof AbstractControl) {
|
|
769
|
-
throw new
|
|
769
|
+
throw new _RuntimeError(1907, ngDevMode && `Tried to read an 'AbstractControl' value from a 'form()'. Did you mean to use 'compatForm()' instead?`);
|
|
770
770
|
}
|
|
771
771
|
return result;
|
|
772
772
|
};
|
|
@@ -789,7 +789,7 @@ class FieldMetadataState {
|
|
|
789
789
|
if (this.has(key)) {
|
|
790
790
|
if (!this.metadata.has(key)) {
|
|
791
791
|
if (key.create) {
|
|
792
|
-
throw
|
|
792
|
+
throw new _RuntimeError(1912, ngDevMode && 'Managed metadata cannot be created lazily');
|
|
793
793
|
}
|
|
794
794
|
const logic = this.node.logicNode.logic.getMetadata(key);
|
|
795
795
|
this.metadata.set(key, computed(() => logic.compute(this.node.context)));
|
|
@@ -929,7 +929,7 @@ class FieldNodeStructure {
|
|
|
929
929
|
const key = initialKeyInParent;
|
|
930
930
|
return computed(() => {
|
|
931
931
|
if (this.parent.structure.getChild(key) !== this.node) {
|
|
932
|
-
throw new
|
|
932
|
+
throw new _RuntimeError(1902, ngDevMode && `Orphan field, looking for property '${key}' of ${getDebugName(this.parent)}`);
|
|
933
933
|
}
|
|
934
934
|
return key;
|
|
935
935
|
});
|
|
@@ -938,7 +938,7 @@ class FieldNodeStructure {
|
|
|
938
938
|
return computed(() => {
|
|
939
939
|
const parentValue = this.parent.structure.value();
|
|
940
940
|
if (!isArray(parentValue)) {
|
|
941
|
-
throw new
|
|
941
|
+
throw new _RuntimeError(1903, ngDevMode && `Orphan field, expected ${getDebugName(this.parent)} to be an array`);
|
|
942
942
|
}
|
|
943
943
|
const data = parentValue[lastKnownKey];
|
|
944
944
|
if (isObject(data) && data.hasOwnProperty(this.parent.structure.identitySymbol) && data[this.parent.structure.identitySymbol] === identityInParent) {
|
|
@@ -950,7 +950,7 @@ class FieldNodeStructure {
|
|
|
950
950
|
return lastKnownKey = i.toString();
|
|
951
951
|
}
|
|
952
952
|
}
|
|
953
|
-
throw new
|
|
953
|
+
throw new _RuntimeError(1904, ngDevMode && `Orphan field, can't find element in array ${getDebugName(this.parent)}`);
|
|
954
954
|
});
|
|
955
955
|
}
|
|
956
956
|
}
|
|
@@ -1084,7 +1084,7 @@ const ROOT_PATH_KEYS = computed(() => [], ...(ngDevMode ? [{
|
|
|
1084
1084
|
debugName: "ROOT_PATH_KEYS"
|
|
1085
1085
|
}] : []));
|
|
1086
1086
|
const ROOT_KEY_IN_PARENT = computed(() => {
|
|
1087
|
-
throw new
|
|
1087
|
+
throw new _RuntimeError(1905, ngDevMode && 'The top-level field in the form has no parent.');
|
|
1088
1088
|
}, ...(ngDevMode ? [{
|
|
1089
1089
|
debugName: "ROOT_KEY_IN_PARENT"
|
|
1090
1090
|
}] : []));
|
|
@@ -1138,12 +1138,12 @@ class FieldSubmitState {
|
|
|
1138
1138
|
selfSubmitting = signal(false, ...(ngDevMode ? [{
|
|
1139
1139
|
debugName: "selfSubmitting"
|
|
1140
1140
|
}] : []));
|
|
1141
|
-
|
|
1141
|
+
submissionErrors;
|
|
1142
1142
|
constructor(node) {
|
|
1143
1143
|
this.node = node;
|
|
1144
|
-
this.
|
|
1144
|
+
this.submissionErrors = linkedSignal({
|
|
1145
1145
|
...(ngDevMode ? {
|
|
1146
|
-
debugName: "
|
|
1146
|
+
debugName: "submissionErrors"
|
|
1147
1147
|
} : {}),
|
|
1148
1148
|
source: this.node.structure.value,
|
|
1149
1149
|
computation: () => []
|
|
@@ -1236,8 +1236,8 @@ class FieldNode {
|
|
|
1236
1236
|
get readonly() {
|
|
1237
1237
|
return this.nodeState.readonly;
|
|
1238
1238
|
}
|
|
1239
|
-
get
|
|
1240
|
-
return this.nodeState.
|
|
1239
|
+
get formFieldBindings() {
|
|
1240
|
+
return this.nodeState.formFieldBindings;
|
|
1241
1241
|
}
|
|
1242
1242
|
get submitting() {
|
|
1243
1243
|
return this.submitState.submitting;
|
|
@@ -1368,8 +1368,8 @@ class FieldNodeState {
|
|
|
1368
1368
|
markAsUntouched() {
|
|
1369
1369
|
this.selfTouched.set(false);
|
|
1370
1370
|
}
|
|
1371
|
-
|
|
1372
|
-
debugName: "
|
|
1371
|
+
formFieldBindings = signal([], ...(ngDevMode ? [{
|
|
1372
|
+
debugName: "formFieldBindings"
|
|
1373
1373
|
}] : []));
|
|
1374
1374
|
constructor(node) {
|
|
1375
1375
|
this.node = node;
|
|
@@ -1540,19 +1540,19 @@ async function submit(form, action) {
|
|
|
1540
1540
|
node.submitState.selfSubmitting.set(true);
|
|
1541
1541
|
try {
|
|
1542
1542
|
const errors = await action(form);
|
|
1543
|
-
errors &&
|
|
1543
|
+
errors && setSubmissionErrors(node, errors);
|
|
1544
1544
|
} finally {
|
|
1545
1545
|
node.submitState.selfSubmitting.set(false);
|
|
1546
1546
|
}
|
|
1547
1547
|
}
|
|
1548
|
-
function
|
|
1548
|
+
function setSubmissionErrors(submittedField, errors) {
|
|
1549
1549
|
if (!isArray(errors)) {
|
|
1550
1550
|
errors = [errors];
|
|
1551
1551
|
}
|
|
1552
1552
|
const errorsByField = new Map();
|
|
1553
1553
|
for (const error of errors) {
|
|
1554
1554
|
const errorWithField = addDefaultField(error, submittedField.fieldProxy);
|
|
1555
|
-
const field = errorWithField.
|
|
1555
|
+
const field = errorWithField.fieldTree();
|
|
1556
1556
|
let fieldErrors = errorsByField.get(field);
|
|
1557
1557
|
if (!fieldErrors) {
|
|
1558
1558
|
fieldErrors = [];
|
|
@@ -1561,7 +1561,7 @@ function setServerErrors(submittedField, errors) {
|
|
|
1561
1561
|
fieldErrors.push(errorWithField);
|
|
1562
1562
|
}
|
|
1563
1563
|
for (const [field, fieldErrors] of errorsByField) {
|
|
1564
|
-
field.submitState.
|
|
1564
|
+
field.submitState.submissionErrors.set(fieldErrors);
|
|
1565
1565
|
}
|
|
1566
1566
|
}
|
|
1567
1567
|
function schema(fn) {
|
|
@@ -1574,5 +1574,5 @@ function markAllAsTouched(node) {
|
|
|
1574
1574
|
}
|
|
1575
1575
|
}
|
|
1576
1576
|
|
|
1577
|
-
export { BasicFieldAdapter, DEBOUNCER, FieldNode, FieldNodeState, FieldNodeStructure, FieldPathNode, MAX, MAX_LENGTH, MIN, MIN_LENGTH, MetadataKey, MetadataReducer, PATTERN, REQUIRED, addDefaultField, apply, applyEach, applyWhen, applyWhenValue, assertPathIsCurrent, calculateValidationSelfStatus, createManagedMetadataKey, createMetadataKey, form, getInjectorFromOptions,
|
|
1577
|
+
export { BasicFieldAdapter, DEBOUNCER, FieldNode, FieldNodeState, FieldNodeStructure, FieldPathNode, MAX, MAX_LENGTH, MIN, MIN_LENGTH, MetadataKey, MetadataReducer, PATTERN, REQUIRED, addDefaultField, apply, applyEach, applyWhen, applyWhenValue, assertPathIsCurrent, calculateValidationSelfStatus, createManagedMetadataKey, createMetadataKey, form, getInjectorFromOptions, metadata, normalizeFormArgs, schema, submit };
|
|
1578
1578
|
//# sourceMappingURL=_structure-chunk.mjs.map
|