@angular/forms 22.0.0-next.4 → 22.0.0-next.5
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/fesm2022/_validation_errors-chunk.mjs +158 -67
- package/fesm2022/_validation_errors-chunk.mjs.map +1 -1
- package/fesm2022/forms.mjs +128 -128
- package/fesm2022/forms.mjs.map +1 -1
- package/fesm2022/signals-compat.mjs +1 -1
- package/fesm2022/signals.mjs +177 -17
- package/fesm2022/signals.mjs.map +1 -1
- package/package.json +4 -4
- package/resources/code-examples.db +0 -0
- package/types/_structure-chunk.d.ts +33 -11
- package/types/forms.d.ts +1 -1
- package/types/signals-compat.d.ts +1 -1
- package/types/signals.d.ts +14 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v22.0.0-next.
|
|
2
|
+
* @license Angular v22.0.0-next.5
|
|
3
3
|
* (c) 2010-2026 Google LLC. https://angular.dev/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -58,6 +58,9 @@ class AbstractLogic {
|
|
|
58
58
|
const fns = this.predicates ? other.fns.map(fn => wrapWithPredicates(this.predicates, fn)) : other.fns;
|
|
59
59
|
this.fns.push(...fns);
|
|
60
60
|
}
|
|
61
|
+
hasRules() {
|
|
62
|
+
return this.fns.length > 0;
|
|
63
|
+
}
|
|
61
64
|
}
|
|
62
65
|
class BooleanOrLogic extends AbstractLogic {
|
|
63
66
|
get defaultValue() {
|
|
@@ -162,9 +165,15 @@ class LogicContainer {
|
|
|
162
165
|
this.syncTreeErrors = ArrayMergeIgnoreLogic.ignoreNull(predicates);
|
|
163
166
|
this.asyncErrors = ArrayMergeIgnoreLogic.ignoreNull(predicates);
|
|
164
167
|
}
|
|
168
|
+
hasAnyLogic() {
|
|
169
|
+
return this.hidden.hasRules() || this.disabledReasons.hasRules() || this.readonly.hasRules() || this.syncErrors.hasRules() || this.syncTreeErrors.hasRules() || this.asyncErrors.hasRules() || this.metadata.size > 0;
|
|
170
|
+
}
|
|
165
171
|
hasMetadata(key) {
|
|
166
172
|
return this.metadata.has(key);
|
|
167
173
|
}
|
|
174
|
+
hasMetadataKeys() {
|
|
175
|
+
return this.metadata.size > 0;
|
|
176
|
+
}
|
|
168
177
|
getMetadataKeys() {
|
|
169
178
|
return this.metadata.keys();
|
|
170
179
|
}
|
|
@@ -241,6 +250,14 @@ class LogicNodeBuilder extends AbstractLogicNodeBuilder {
|
|
|
241
250
|
builder: subBuilder
|
|
242
251
|
}) => subBuilder.hasLogic(builder));
|
|
243
252
|
}
|
|
253
|
+
hasRules() {
|
|
254
|
+
return this.all.length > 0;
|
|
255
|
+
}
|
|
256
|
+
anyChildHasLogic() {
|
|
257
|
+
return this.all.some(({
|
|
258
|
+
builder
|
|
259
|
+
}) => builder.anyChildHasLogic());
|
|
260
|
+
}
|
|
244
261
|
mergeIn(other, predicate) {
|
|
245
262
|
if (predicate) {
|
|
246
263
|
this.all.push({
|
|
@@ -306,6 +323,17 @@ class NonMergeableLogicNodeBuilder extends AbstractLogicNodeBuilder {
|
|
|
306
323
|
hasLogic(builder) {
|
|
307
324
|
return this === builder;
|
|
308
325
|
}
|
|
326
|
+
hasRules() {
|
|
327
|
+
return this.logic.hasAnyLogic() || this.children.size > 0;
|
|
328
|
+
}
|
|
329
|
+
anyChildHasLogic() {
|
|
330
|
+
for (const child of this.children.values()) {
|
|
331
|
+
if (child.hasRules()) {
|
|
332
|
+
return true;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
309
337
|
}
|
|
310
338
|
class LeafLogicNode {
|
|
311
339
|
builder;
|
|
@@ -337,7 +365,16 @@ class LeafLogicNode {
|
|
|
337
365
|
}
|
|
338
366
|
}
|
|
339
367
|
hasLogic(builder) {
|
|
340
|
-
|
|
368
|
+
if (!this.builder) {
|
|
369
|
+
return false;
|
|
370
|
+
}
|
|
371
|
+
return this.builder.hasLogic(builder);
|
|
372
|
+
}
|
|
373
|
+
hasRules() {
|
|
374
|
+
return this.builder ? this.builder.hasRules() : false;
|
|
375
|
+
}
|
|
376
|
+
anyChildHasLogic() {
|
|
377
|
+
return this.builder ? this.builder.anyChildHasLogic() : false;
|
|
341
378
|
}
|
|
342
379
|
}
|
|
343
380
|
class CompositeLogicNode {
|
|
@@ -356,6 +393,12 @@ class CompositeLogicNode {
|
|
|
356
393
|
hasLogic(builder) {
|
|
357
394
|
return this.all.some(node => node.hasLogic(builder));
|
|
358
395
|
}
|
|
396
|
+
hasRules() {
|
|
397
|
+
return this.all.some(node => node.hasRules());
|
|
398
|
+
}
|
|
399
|
+
anyChildHasLogic() {
|
|
400
|
+
return this.all.some(child => child.anyChildHasLogic());
|
|
401
|
+
}
|
|
359
402
|
}
|
|
360
403
|
function getAllChildBuilders(builder, key) {
|
|
361
404
|
if (builder instanceof LogicNodeBuilder) {
|
|
@@ -568,10 +611,12 @@ function override(getInitial) {
|
|
|
568
611
|
getInitial: () => getInitial?.()
|
|
569
612
|
};
|
|
570
613
|
}
|
|
614
|
+
const IS_ASYNC_VALIDATION_RESOURCE = Symbol('IS_ASYNC_VALIDATION_RESOURCE');
|
|
571
615
|
class MetadataKey {
|
|
572
616
|
reducer;
|
|
573
617
|
create;
|
|
574
618
|
brand;
|
|
619
|
+
[IS_ASYNC_VALIDATION_RESOURCE];
|
|
575
620
|
constructor(reducer, create) {
|
|
576
621
|
this.reducer = reducer;
|
|
577
622
|
this.create = create;
|
|
@@ -806,13 +851,20 @@ class FieldMetadataState {
|
|
|
806
851
|
metadata = new Map();
|
|
807
852
|
constructor(node) {
|
|
808
853
|
this.node = node;
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
this.metadata.set(key, result);
|
|
814
|
-
}
|
|
854
|
+
}
|
|
855
|
+
runMetadataCreateLifecycle() {
|
|
856
|
+
if (!this.node.logicNode.logic.hasMetadataKeys()) {
|
|
857
|
+
return;
|
|
815
858
|
}
|
|
859
|
+
untracked(() => runInInjectionContext(this.node.structure.injector, () => {
|
|
860
|
+
for (const key of this.node.logicNode.logic.getMetadataKeys()) {
|
|
861
|
+
if (key.create) {
|
|
862
|
+
const logic = this.node.logicNode.logic.getMetadata(key);
|
|
863
|
+
const result = key.create(this.node, computed(() => logic.compute(this.node.context)));
|
|
864
|
+
this.metadata.set(key, result);
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
}));
|
|
816
868
|
}
|
|
817
869
|
get(key) {
|
|
818
870
|
if (this.has(key)) {
|
|
@@ -906,6 +958,7 @@ class FieldNodeStructure {
|
|
|
906
958
|
createChildNode;
|
|
907
959
|
identitySymbol = Symbol();
|
|
908
960
|
_injector = undefined;
|
|
961
|
+
_anyChildHasLogic;
|
|
909
962
|
get injector() {
|
|
910
963
|
this._injector ??= Injector.create({
|
|
911
964
|
providers: [],
|
|
@@ -919,13 +972,26 @@ class FieldNodeStructure {
|
|
|
919
972
|
this.createChildNode = createChildNode;
|
|
920
973
|
}
|
|
921
974
|
children() {
|
|
975
|
+
this.ensureChildrenMap();
|
|
922
976
|
const map = this.childrenMap();
|
|
923
977
|
if (map === undefined) {
|
|
924
978
|
return [];
|
|
925
979
|
}
|
|
926
980
|
return Array.from(map.byPropertyKey.values()).map(child => untracked(child.reader));
|
|
927
981
|
}
|
|
982
|
+
_areChildrenMaterialized() {
|
|
983
|
+
return untracked(this.childrenMap) !== undefined;
|
|
984
|
+
}
|
|
985
|
+
ensureChildrenMap() {
|
|
986
|
+
if (this._areChildrenMaterialized()) {
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
989
|
+
untracked(() => {
|
|
990
|
+
this.childrenMap.update(current => this.computeChildrenMap(this.value(), current, true));
|
|
991
|
+
});
|
|
992
|
+
}
|
|
928
993
|
getChild(key) {
|
|
994
|
+
this.ensureChildrenMap();
|
|
929
995
|
const strKey = key.toString();
|
|
930
996
|
let reader = untracked(this.childrenMap)?.byPropertyKey.get(strKey)?.reader;
|
|
931
997
|
if (!reader) {
|
|
@@ -986,67 +1052,73 @@ class FieldNodeStructure {
|
|
|
986
1052
|
createChildrenMap() {
|
|
987
1053
|
return linkedSignal({
|
|
988
1054
|
source: this.value,
|
|
989
|
-
computation: (value, previous) =>
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1055
|
+
computation: (value, previous) => this.computeChildrenMap(value, previous?.value, false)
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
computeChildrenMap(value, prevData, forceMaterialize) {
|
|
1059
|
+
if (!isObject(value)) {
|
|
1060
|
+
return undefined;
|
|
1061
|
+
}
|
|
1062
|
+
if (!forceMaterialize && prevData === undefined) {
|
|
1063
|
+
if (!(this._anyChildHasLogic ??= this.logic.anyChildHasLogic())) {
|
|
1064
|
+
return undefined;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
prevData ??= {
|
|
1068
|
+
byPropertyKey: new Map()
|
|
1069
|
+
};
|
|
1070
|
+
let materializedChildren;
|
|
1071
|
+
const parentIsArray = isArray(value);
|
|
1072
|
+
if (prevData !== undefined) {
|
|
1073
|
+
if (parentIsArray) {
|
|
1074
|
+
materializedChildren = maybeRemoveStaleArrayFields(prevData, value, this.identitySymbol);
|
|
1075
|
+
} else {
|
|
1076
|
+
materializedChildren = maybeRemoveStaleObjectFields(prevData, value);
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
for (const key of Object.keys(value)) {
|
|
1080
|
+
let trackingKey = undefined;
|
|
1081
|
+
const childValue = value[key];
|
|
1082
|
+
if (childValue === undefined) {
|
|
1083
|
+
if (prevData.byPropertyKey.has(key)) {
|
|
1084
|
+
materializedChildren ??= {
|
|
1085
|
+
...prevData
|
|
1086
|
+
};
|
|
1087
|
+
materializedChildren.byPropertyKey.delete(key);
|
|
1004
1088
|
}
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
trackingKey = childValue[this.identitySymbol] ??= Symbol(ngDevMode ? `id:${globalId++}` : '');
|
|
1019
|
-
}
|
|
1020
|
-
let childNode;
|
|
1021
|
-
if (trackingKey) {
|
|
1022
|
-
if (!prevData.byTrackingKey?.has(trackingKey)) {
|
|
1023
|
-
data ??= {
|
|
1024
|
-
...prevData
|
|
1025
|
-
};
|
|
1026
|
-
data.byTrackingKey ??= new Map();
|
|
1027
|
-
data.byTrackingKey.set(trackingKey, this.createChildNode(key, trackingKey, parentIsArray));
|
|
1028
|
-
}
|
|
1029
|
-
childNode = (data ?? prevData).byTrackingKey.get(trackingKey);
|
|
1030
|
-
}
|
|
1031
|
-
const child = prevData.byPropertyKey.get(key);
|
|
1032
|
-
if (child === undefined) {
|
|
1033
|
-
data ??= {
|
|
1034
|
-
...prevData
|
|
1035
|
-
};
|
|
1036
|
-
data.byPropertyKey.set(key, {
|
|
1037
|
-
reader: this.createReader(key),
|
|
1038
|
-
node: childNode ?? this.createChildNode(key, trackingKey, parentIsArray)
|
|
1039
|
-
});
|
|
1040
|
-
} else if (childNode && childNode !== child.node) {
|
|
1041
|
-
data ??= {
|
|
1042
|
-
...prevData
|
|
1043
|
-
};
|
|
1044
|
-
child.node = childNode;
|
|
1045
|
-
}
|
|
1089
|
+
continue;
|
|
1090
|
+
}
|
|
1091
|
+
if (parentIsArray && isObject(childValue) && !isArray(childValue)) {
|
|
1092
|
+
trackingKey = childValue[this.identitySymbol] ??= Symbol(ngDevMode ? `id:${globalId++}` : '');
|
|
1093
|
+
}
|
|
1094
|
+
let childNode;
|
|
1095
|
+
if (trackingKey) {
|
|
1096
|
+
if (!prevData.byTrackingKey?.has(trackingKey)) {
|
|
1097
|
+
materializedChildren ??= {
|
|
1098
|
+
...prevData
|
|
1099
|
+
};
|
|
1100
|
+
materializedChildren.byTrackingKey ??= new Map();
|
|
1101
|
+
materializedChildren.byTrackingKey.set(trackingKey, this.createChildNode(key, trackingKey, parentIsArray));
|
|
1046
1102
|
}
|
|
1047
|
-
|
|
1103
|
+
childNode = (materializedChildren ?? prevData).byTrackingKey.get(trackingKey);
|
|
1048
1104
|
}
|
|
1049
|
-
|
|
1105
|
+
const child = prevData.byPropertyKey.get(key);
|
|
1106
|
+
if (child === undefined) {
|
|
1107
|
+
materializedChildren ??= {
|
|
1108
|
+
...prevData
|
|
1109
|
+
};
|
|
1110
|
+
materializedChildren.byPropertyKey.set(key, {
|
|
1111
|
+
reader: this.createReader(key),
|
|
1112
|
+
node: childNode ?? this.createChildNode(key, trackingKey, parentIsArray)
|
|
1113
|
+
});
|
|
1114
|
+
} else if (childNode && childNode !== child.node) {
|
|
1115
|
+
materializedChildren ??= {
|
|
1116
|
+
...prevData
|
|
1117
|
+
};
|
|
1118
|
+
child.node = childNode;
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
return materializedChildren ?? prevData;
|
|
1050
1122
|
}
|
|
1051
1123
|
createReader(key) {
|
|
1052
1124
|
return computed(() => this.childrenMap()?.byPropertyKey.get(key)?.node);
|
|
@@ -1208,6 +1280,7 @@ class FieldNode {
|
|
|
1208
1280
|
this.metadataState = new FieldMetadataState(this);
|
|
1209
1281
|
this.submitState = new FieldSubmitState(this);
|
|
1210
1282
|
this.controlValue = this.controlValueSignal();
|
|
1283
|
+
this.metadataState.runMetadataCreateLifecycle();
|
|
1211
1284
|
}
|
|
1212
1285
|
focusBoundControl(options) {
|
|
1213
1286
|
this.getBindingForFocus()?.focus(options);
|
|
@@ -1305,6 +1378,9 @@ class FieldNode {
|
|
|
1305
1378
|
metadata(key) {
|
|
1306
1379
|
return this.metadataState.get(key);
|
|
1307
1380
|
}
|
|
1381
|
+
getError(kind) {
|
|
1382
|
+
return this.errors().find(e => e.kind === kind);
|
|
1383
|
+
}
|
|
1308
1384
|
hasMetadata(key) {
|
|
1309
1385
|
return this.metadataState.has(key);
|
|
1310
1386
|
}
|
|
@@ -1348,6 +1424,21 @@ class FieldNode {
|
|
|
1348
1424
|
child._reset();
|
|
1349
1425
|
}
|
|
1350
1426
|
}
|
|
1427
|
+
reloadValidation() {
|
|
1428
|
+
untracked(() => this._reloadValidation());
|
|
1429
|
+
}
|
|
1430
|
+
_reloadValidation() {
|
|
1431
|
+
const keys = this.logicNode.logic.getMetadataKeys();
|
|
1432
|
+
for (const key of keys) {
|
|
1433
|
+
if (key[IS_ASYNC_VALIDATION_RESOURCE]) {
|
|
1434
|
+
const resource = this.metadata(key);
|
|
1435
|
+
resource.reload?.();
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
for (const child of this.structure.children()) {
|
|
1439
|
+
child._reloadValidation();
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1351
1442
|
controlValueSignal() {
|
|
1352
1443
|
const controlValue = linkedSignal(this.value, ...(ngDevMode ? [{
|
|
1353
1444
|
debugName: "controlValue"
|
|
@@ -1736,5 +1827,5 @@ function extractNestedReactiveErrors(control) {
|
|
|
1736
1827
|
return errors;
|
|
1737
1828
|
}
|
|
1738
1829
|
|
|
1739
|
-
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, isArray, isObject, metadata, normalizeFormArgs, schema, signalErrorsToValidationErrors, submit };
|
|
1830
|
+
export { BasicFieldAdapter, CompatValidationError, DEBOUNCER, FieldNode, FieldNodeState, FieldNodeStructure, FieldPathNode, IS_ASYNC_VALIDATION_RESOURCE, MAX, MAX_LENGTH, MIN, MIN_LENGTH, MetadataKey, MetadataReducer, PATTERN, REQUIRED, addDefaultField, apply, applyEach, applyWhen, applyWhenValue, assertPathIsCurrent, calculateValidationSelfStatus, createManagedMetadataKey, createMetadataKey, extractNestedReactiveErrors, form, getInjectorFromOptions, isArray, isObject, metadata, normalizeFormArgs, schema, signalErrorsToValidationErrors, submit };
|
|
1740
1831
|
//# sourceMappingURL=_validation_errors-chunk.mjs.map
|