@reactables/forms 0.4.3-alpha.0 → 0.4.4-alpha.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.
@@ -9,12 +9,10 @@ export interface BaseControl<T> {
9
9
  dirty: boolean;
10
10
  touched: boolean;
11
11
  validatorErrors: FormErrors;
12
- validatorsValid: boolean;
13
12
  config: AbstractControlConfig;
14
13
  key: string;
15
14
  }
16
15
  interface AsyncFields {
17
- asyncValidatorsValid: boolean;
18
16
  asyncValidatorErrors: FormErrors;
19
17
  asyncValidateInProgress: {
20
18
  [key: string | number]: boolean;
@@ -38,7 +36,7 @@ export interface BaseForm<T> {
38
36
  [key: string]: BaseControl<unknown>;
39
37
  }
40
38
  export interface Form<T> {
41
- root: FormControl<T>;
39
+ root?: FormControl<T>;
42
40
  [key: string]: FormControl<unknown>;
43
41
  }
44
42
  export {};
@@ -0,0 +1,3 @@
1
+ import { BaseControl } from '../../Models/Controls';
2
+ import { FormErrors } from '../../Models';
3
+ export declare const getErrors: <T>(control: BaseControl<T>, value: T) => FormErrors;
@@ -1,5 +1,5 @@
1
1
  import { Action } from '@reactables/core';
2
2
  import { BaseForm } from '../../Models/Controls';
3
- import { ControlRef } from '../../Models/ControlRef';
3
+ import { ControlChange } from '../../Models/Payloads';
4
4
  export declare const UPDATE_ANCESTOR_VALUES = "UPDATE_ANCESTOR_VALUES";
5
- export declare const updateAncestorValues: <T>(form: BaseForm<T>, { payload: controlRef }: Action<ControlRef>) => BaseForm<T>;
5
+ export declare const updateAncestorValues: <T>(form: BaseForm<T>, { payload: { controlRef, value } }: Action<ControlChange<unknown>>) => BaseForm<T>;
@@ -0,0 +1,5 @@
1
+ import { Action } from '@reactables/core';
2
+ import { BaseForm } from '../../Models/Controls';
3
+ import { ControlChange } from '../../Models/Payloads';
4
+ export declare const UPDATE_ANCESTOR_VALUES_ADD_CONTROL = "UPDATE_ANCESTOR_VALUES_ADD_CONTROL";
5
+ export declare const updateAncestorValuesAddControl: <T>(form: BaseForm<T>, { payload: { controlRef, value } }: Action<ControlChange<unknown>>) => BaseForm<T>;
@@ -0,0 +1,5 @@
1
+ import { Action } from '@reactables/core';
2
+ import { BaseForm } from '../../Models/Controls';
3
+ import { ControlRef } from '../../Models/ControlRef';
4
+ export declare const UPDATE_ANCESTOR_VALUES_REMOVE_CONTROL = "UPDATE_ANCESTOR_VALUES_REMOVE_CONTROL";
5
+ export declare const updateAncestorValuesRemoveControl: <T>(form: BaseForm<T>, { payload: controlRef }: Action<ControlRef>) => BaseForm<T>;
@@ -0,0 +1,3 @@
1
+ import { Form } from '../../Models/Controls';
2
+ import { ControlRef } from '../../Models';
3
+ export declare const mergeBranchErrors: <T>(form: Form<T>, controlRef: ControlRef) => Form<T>;
@@ -0,0 +1,3 @@
1
+ import { Form, BaseForm } from '../../Models/Controls';
2
+ import { ControlRef } from '../../Models/ControlRef';
3
+ export declare const mergeValueUpdated: <T>(state: Form<T>, form: BaseForm<T>, controlRef: ControlRef) => Form<T>;
package/dist/index.js CHANGED
@@ -122,44 +122,14 @@ var generateKey = function (length) {
122
122
  return result;
123
123
  };
124
124
 
125
- // Includes the original control of interest unless excludeSelf === true
126
- var getDescendantControls = function (controlRef, form, excludeSelf) {
127
- if (excludeSelf === void 0) { excludeSelf = false; }
128
- var result = Object.entries(form)
129
- .filter(function (_a) {
130
- var key = _a[0];
131
- if (!controlRef.length)
132
- return true;
133
- var childRef = key.split('.');
134
- return controlRef.every(function (refKey, index) {
135
- return refKey == childRef[index];
136
- });
137
- })
138
- .map(function (entry) { return entry[1]; });
139
- return result.filter(function (control) {
140
- return excludeSelf ? getFormKey(control.controlRef) !== getFormKey(controlRef) : true;
141
- });
142
- };
143
-
144
125
  var syncValidate = function (form) {
145
126
  // First check each control for its own validation
146
- var baseValidation = Object.entries(form).reduce(function (acc, _a) {
127
+ var validated = Object.entries(form).reduce(function (acc, _a) {
147
128
  var _b;
148
129
  var _c;
149
130
  var key = _a[0], control = _a[1];
150
131
  var validatorErrors = ((_c = control.config.validators) === null || _c === void 0 ? void 0 : _c.reduce(function (acc, validator) { return (__assign(__assign({}, acc), validator(control.value))); }, {})) || {};
151
- var validatorsValid = !Object.values(validatorErrors).some(function (err) { return err; });
152
- return __assign(__assign({}, acc), (_b = {}, _b[key] = __assign(__assign({}, control), { validatorErrors: validatorErrors, validatorsValid: validatorsValid }), _b));
153
- }, {});
154
- // Then check each controls children to see if there are errors
155
- var validated = Object.entries(baseValidation).reduce(function (acc, _a) {
156
- var _b;
157
- var key = _a[0], control = _a[1];
158
- var validatorsValid = getDescendantControls(control.controlRef, baseValidation).every(function (_a) {
159
- var validatorsValid = _a.validatorsValid;
160
- return validatorsValid;
161
- });
162
- return __assign(__assign({}, acc), (_b = {}, _b[key] = __assign(__assign({}, control), { validatorsValid: validatorsValid }), _b));
132
+ return __assign(__assign({}, acc), (_b = {}, _b[key] = __assign(__assign({}, control), { validatorErrors: validatorErrors }), _b));
163
133
  }, {});
164
134
  return validated;
165
135
  };
@@ -176,7 +146,6 @@ var buildState = function (config, form, controlRef) {
176
146
  value: value,
177
147
  controlRef: controlRef,
178
148
  validatorErrors: {},
179
- validatorsValid: null,
180
149
  config: config,
181
150
  key: generateKey(5)
182
151
  };
@@ -193,13 +162,13 @@ var buildState = function (config, form, controlRef) {
193
162
  // Adding controls for Form Array
194
163
  newForm = config.controls.reduce(function (acc, controlConfig, index) { return buildState(controlConfig, acc, controlRef.concat(index)); }, newForm);
195
164
  }
196
- return syncValidate(newForm);
165
+ return newForm;
197
166
  };
198
167
  var buildFormState = function (config, form, controlRef) {
199
168
  if (form === void 0) { form = { root: null }; }
200
169
  if (controlRef === void 0) { controlRef = []; }
201
170
  return {
202
- form: buildState(config, form, controlRef),
171
+ form: syncValidate(buildState(config, form, controlRef)),
203
172
  action: null
204
173
  };
205
174
  };
@@ -229,10 +198,39 @@ var getAncestorControls = function (controlRef, form, excludeSelf) {
229
198
  });
230
199
  };
231
200
 
201
+ // Includes the original control of interest unless excludeSelf === true
202
+ var getDescendantControls = function (controlRef, form, excludeSelf) {
203
+ if (excludeSelf === void 0) { excludeSelf = false; }
204
+ if (!controlRef.length) {
205
+ return Object.values(form).filter(function (_a) {
206
+ var controlRef = _a.controlRef;
207
+ return excludeSelf ? controlRef.length !== 0 : true;
208
+ });
209
+ }
210
+ var control = getControl(controlRef, form);
211
+ var value = control.value, config = control.config;
212
+ var descendants;
213
+ if (Array.isArray(config.controls)) {
214
+ // If control is a Form Array
215
+ descendants = value.reduce(function (acc, item, index) {
216
+ return acc.concat(getDescendantControls(controlRef.concat(index), form));
217
+ }, []);
218
+ }
219
+ else if (config.controls) {
220
+ // If control is a Form Group
221
+ descendants = Object.keys(value).reduce(function (acc, key) {
222
+ return acc.concat(getDescendantControls(controlRef.concat(key), form));
223
+ }, []);
224
+ }
225
+ if (excludeSelf)
226
+ return descendants;
227
+ return [control].concat(descendants || []);
228
+ };
229
+
232
230
  var getControlBranch = function (controlRef, form) {
233
231
  var ancestors = getAncestorControls(controlRef, form);
234
232
  var childControls = getDescendantControls(controlRef, form).slice(1);
235
- return ancestors.concat(childControls);
233
+ return ancestors.concat(childControls).sort(function (a, b) { return a.controlRef.length - b.controlRef.length; });
236
234
  };
237
235
 
238
236
  var getScopedEffectsForControl = function (formControl) {
@@ -306,49 +304,40 @@ var buildHub2Source = function (rx) {
306
304
  return sourceForHub2$;
307
305
  };
308
306
 
307
+ var getErrors = function (control, value) {
308
+ var _a;
309
+ return ((_a = control.config.validators) === null || _a === void 0 ? void 0 : _a.reduce(function (acc, validator) { return (__assign(__assign({}, acc), validator(value))); }, {})) || {};
310
+ };
311
+
309
312
  var UPDATE_ANCESTOR_VALUES = 'UPDATE_ANCESTOR_VALUES';
310
313
  var updateAncestorValues = function (form, _a) {
311
- var _b;
312
- var controlRef = _a.payload;
314
+ var _b, _c;
315
+ var _d = _a.payload, controlRef = _d.controlRef, value = _d.value;
313
316
  if (controlRef.length) {
314
317
  var parentRef = controlRef.slice(0, -1);
315
- var parentKey = getFormKey(parentRef);
316
- var siblingControls = getDescendantControls(parentRef, form).filter(
317
- // Out of descendants we only need the siblings
318
- function (control) { return control.controlRef.length === controlRef.length; });
318
+ var parentControl = getControl(parentRef, form);
319
+ var parentFormKey = getFormKey(parentControl.controlRef);
320
+ var childKey_1 = controlRef.slice(-1)[0];
319
321
  var newValue = void 0;
320
322
  // If parent is a Form Array
321
- if (Array.isArray(form[parentKey].value)) {
322
- newValue = siblingControls
323
- .slice()
324
- .sort(function (a, b) { return a.controlRef.at(-1) - b.controlRef.at(-1); })
325
- .map(function (control) { return control.value; });
323
+ if (Array.isArray(parentControl.value)) {
324
+ newValue = parentControl.value.map(function (item, index) {
325
+ return index === childKey_1 ? value : item;
326
+ });
326
327
  }
327
328
  else {
328
329
  // If parent is a Form Group
329
- newValue = siblingControls.reduce(function (acc, _a) {
330
- var _b;
331
- var controlRef = _a.controlRef, value = _a.value;
332
- return __assign(__assign({}, acc), (_b = {}, _b[controlRef.at(-1)] = value, _b));
333
- }, {});
330
+ newValue = __assign(__assign({}, parentControl.value), (_b = {}, _b[childKey_1] = value, _b));
334
331
  }
335
- var newParentControl = __assign(__assign({}, form[parentKey]), { value: newValue });
336
- return updateAncestorValues(__assign(__assign({}, form), (_b = {}, _b[parentKey] = newParentControl, _b)), {
332
+ var newParentControl = __assign(__assign({}, parentControl), { validatorErrors: getErrors(parentControl, newValue), value: newValue, dirty: !isEqual__default["default"](newValue, parentControl.pristineValue) });
333
+ return updateAncestorValues(__assign(__assign({}, form), (_c = {}, _c[parentFormKey] = newParentControl, _c)), {
337
334
  type: UPDATE_ANCESTOR_VALUES,
338
- payload: parentRef
335
+ payload: { controlRef: parentRef, value: newValue }
339
336
  });
340
337
  }
341
338
  return form;
342
339
  };
343
340
 
344
- var updateDirty = function (form) {
345
- return Object.entries(form).reduce(function (acc, _a) {
346
- var _b;
347
- var key = _a[0], control = _a[1];
348
- return __assign(__assign({}, acc), (_b = {}, _b[key] = __assign(__assign({}, control), { dirty: !isEqual__default["default"](control.value, control.pristineValue) }), _b));
349
- }, {});
350
- };
351
-
352
341
  var isChildRef = function (controlRef, parentRef) {
353
342
  return (parentRef.every(function (key, index) { return controlRef[index] === key; }) &&
354
343
  controlRef.length === parentRef.length + 1);
@@ -362,7 +351,8 @@ var updateDescendants = function (form, _a) {
362
351
  var key = _a[0], control = _a[1];
363
352
  if (isChildRef(control.controlRef, controlRef)) {
364
353
  var childValue = value[control.controlRef.at(-1)];
365
- acc = __assign(__assign({}, acc), (_b = {}, _b[key] = __assign(__assign({}, control), { value: childValue }), _b));
354
+ var validatorErrors = getErrors(control, value);
355
+ acc = __assign(__assign({}, acc), (_b = {}, _b[key] = __assign(__assign({}, control), { value: childValue, validatorErrors: validatorErrors, dirty: !isEqual__default["default"](childValue, control.pristineValue) }), _b));
366
356
  var configControls = control.config.controls;
367
357
  if (configControls) {
368
358
  acc = updateDescendants(acc, {
@@ -383,7 +373,8 @@ var updateValues = function (_a, action) {
383
373
  var _c = action.payload, controlRef = _c.controlRef, value = _c.value;
384
374
  // Update its own value
385
375
  var ctrlKey = getFormKey(controlRef);
386
- var result = __assign(__assign({}, form), (_b = {}, _b[ctrlKey] = __assign(__assign({}, form[ctrlKey]), { value: value }), _b));
376
+ var validatorErrors = getErrors(form[ctrlKey], value);
377
+ var result = __assign(__assign({}, form), (_b = {}, _b[ctrlKey] = __assign(__assign({}, form[ctrlKey]), { validatorErrors: validatorErrors, dirty: !isEqual__default["default"](value, form[ctrlKey].pristineValue), value: value }), _b));
387
378
  var configControls = form[ctrlKey].config.controls;
388
379
  // Update its children
389
380
  if (configControls) {
@@ -399,10 +390,38 @@ var updateValues = function (_a, action) {
399
390
  if (controlRef.length) {
400
391
  result = updateAncestorValues(result, {
401
392
  type: UPDATE_ANCESTOR_VALUES,
402
- payload: controlRef
393
+ payload: { controlRef: controlRef, value: value }
394
+ });
395
+ }
396
+ return { form: result, action: action };
397
+ };
398
+
399
+ var UPDATE_ANCESTOR_VALUES_REMOVE_CONTROL = 'UPDATE_ANCESTOR_VALUES_REMOVE_CONTROL';
400
+ var updateAncestorValuesRemoveControl = function (form, _a) {
401
+ var _b;
402
+ var controlRef = _a.payload;
403
+ if (controlRef.length) {
404
+ var parentRef = controlRef.slice(0, -1);
405
+ var parentControl = getControl(parentRef, form);
406
+ var parentFormKey = getFormKey(parentControl.controlRef);
407
+ var childKey_1 = controlRef.slice(-1)[0];
408
+ var newValue = void 0;
409
+ // If parent is a Form Array
410
+ if (Array.isArray(parentControl.value)) {
411
+ newValue = parentControl.value.filter(function (item, index) { return index !== childKey_1; });
412
+ }
413
+ else {
414
+ // If parent is a Form Group
415
+ newValue = __assign({}, parentControl.value);
416
+ delete newValue[childKey_1];
417
+ }
418
+ var newParentControl = __assign(__assign({}, parentControl), { value: newValue, validatorErrors: getErrors(parentControl, newValue), dirty: !isEqual__default["default"](newValue, parentControl.pristineValue) });
419
+ return updateAncestorValues(__assign(__assign({}, form), (_b = {}, _b[parentFormKey] = newParentControl, _b)), {
420
+ type: UPDATE_ANCESTOR_VALUES,
421
+ payload: { controlRef: parentRef, value: newValue }
403
422
  });
404
423
  }
405
- return { form: syncValidate(updateDirty(result)), action: action };
424
+ return form;
406
425
  };
407
426
 
408
427
  var removeControl = function (_a, action) {
@@ -446,14 +465,41 @@ var removeControl = function (_a, action) {
446
465
  return __assign(__assign({}, acc), (_c = {}, _c[key] = control, _c));
447
466
  }, {});
448
467
  return {
449
- form: syncValidate(updateDirty(updateAncestorValues(controlRemoved, {
450
- type: UPDATE_ANCESTOR_VALUES,
468
+ form: updateAncestorValuesRemoveControl(controlRemoved, {
469
+ type: UPDATE_ANCESTOR_VALUES_REMOVE_CONTROL,
451
470
  payload: controlRef
452
- }))),
471
+ }),
453
472
  action: action
454
473
  };
455
474
  };
456
475
 
476
+ var UPDATE_ANCESTOR_VALUES_ADD_CONTROL = 'UPDATE_ANCESTOR_VALUES_ADD_CONTROL';
477
+ var updateAncestorValuesAddControl = function (form, _a) {
478
+ var _b, _c;
479
+ var _d = _a.payload, controlRef = _d.controlRef, value = _d.value;
480
+ if (controlRef.length) {
481
+ var parentRef = controlRef.slice(0, -1);
482
+ var parentControl = getControl(parentRef, form);
483
+ var parentFormKey = getFormKey(parentControl.controlRef);
484
+ var childKey = controlRef.slice(-1)[0];
485
+ var newValue = void 0;
486
+ // If parent is a Form Array
487
+ if (Array.isArray(parentControl.value)) {
488
+ newValue = parentControl.value.concat(value);
489
+ }
490
+ else {
491
+ // If parent is a Form Group
492
+ newValue = __assign(__assign({}, form[parentFormKey].value), (_b = {}, _b[childKey] = value, _b));
493
+ }
494
+ var newParentControl = __assign(__assign({}, parentControl), { value: newValue, validatorErrors: getErrors(parentControl, newValue), dirty: !isEqual__default["default"](newValue, parentControl.pristineValue) });
495
+ return updateAncestorValues(__assign(__assign({}, form), (_c = {}, _c[parentFormKey] = newParentControl, _c)), {
496
+ type: UPDATE_ANCESTOR_VALUES,
497
+ payload: { controlRef: parentRef, value: newValue }
498
+ });
499
+ }
500
+ return form;
501
+ };
502
+
457
503
  var addControl = function (state, action) {
458
504
  var newControlRef;
459
505
  var _a = action.payload, config = _a.config, controlRef = _a.controlRef;
@@ -470,11 +516,12 @@ var addControl = function (state, action) {
470
516
  newControlRef = controlRef;
471
517
  }
472
518
  var newForm = buildState(config, state.form, newControlRef);
473
- var ancestorsUpdated = updateAncestorValues(newForm, {
474
- type: UPDATE_ANCESTOR_VALUES,
475
- payload: newControlRef
519
+ var newValue = getControl(newControlRef, newForm).value;
520
+ var ancestorsUpdated = updateAncestorValuesAddControl(newForm, {
521
+ type: UPDATE_ANCESTOR_VALUES_ADD_CONTROL,
522
+ payload: { controlRef: newControlRef, value: newValue }
476
523
  });
477
- return { form: syncValidate(updateDirty(ancestorsUpdated)), action: action };
524
+ return { form: ancestorsUpdated, action: action };
478
525
  };
479
526
 
480
527
  // Same implementation as updateAncestor values except updating pristine values
@@ -513,6 +560,14 @@ var updateAncestorPristineValues = function (form, _a) {
513
560
  return form;
514
561
  };
515
562
 
563
+ var updateDirty = function (form) {
564
+ return Object.entries(form).reduce(function (acc, _a) {
565
+ var _b;
566
+ var key = _a[0], control = _a[1];
567
+ return __assign(__assign({}, acc), (_b = {}, _b[key] = __assign(__assign({}, control), { dirty: !isEqual__default["default"](control.value, control.pristineValue) }), _b));
568
+ }, {});
569
+ };
570
+
516
571
  var markControlAsPristine = function (_a, action) {
517
572
  var form = _a.form;
518
573
  var controlRef = action.payload;
@@ -584,11 +639,12 @@ var resetControl = function (_a, action) {
584
639
  return __assign(__assign({}, acc), (_b = {}, _b[key] = control, _b));
585
640
  }, {});
586
641
  var restoredControls = buildState(controlToReset.config, descendantsRemoved, controlToReset.controlRef);
642
+ var restoredControlValue = getControl(controlRef, restoredControls).value;
587
643
  return {
588
- form: updateDirty(syncValidate(updateAncestorValues(restoredControls, {
644
+ form: updateAncestorValues(restoredControls, {
589
645
  type: UPDATE_ANCESTOR_VALUES,
590
- payload: controlRef
591
- }))),
646
+ payload: { controlRef: controlRef, value: restoredControlValue }
647
+ }),
592
648
  action: action
593
649
  };
594
650
  };
@@ -612,23 +668,37 @@ var asyncValidation = function (form, _a) {
612
668
  return result;
613
669
  };
614
670
 
615
- var hasErrors = function (errors) {
671
+ var hasErrors$1 = function (errors) {
616
672
  return Object.values(errors).some(function (hasError) { return hasError; });
617
673
  };
674
+ // TODO: update merge errors to not do the entire form but just a subset of it
675
+ // TODO: separation of concern to update validity of control and ancestors
618
676
  var mergeErrors = function (form) {
619
- var errorsMerged = Object.entries(form).reduce(function (acc, _a) {
677
+ var errorsMerged = Object.entries(form)
678
+ .reverse()
679
+ .reduce(function (acc, _a) {
620
680
  var _b;
621
681
  var key = _a[0], control = _a[1];
622
682
  var errors = __assign(__assign({}, control.validatorErrors), control.asyncValidatorErrors);
623
- return __assign(__assign({}, acc), (_b = {}, _b[key] = __assign(__assign({}, control), { errors: errors, valid: !hasErrors(errors) }), _b));
683
+ var selfValid = !hasErrors$1(errors);
684
+ var childrenValid = true;
685
+ if (Array.isArray(control.config.controls)) {
686
+ // If control is a FormArray
687
+ childrenValid = control.value.every(function (item, index) { return acc[getFormKey(control.controlRef.concat(index))].valid; });
688
+ }
689
+ else if (control.config.controls) {
690
+ // If control is a FormGroup
691
+ childrenValid = Object.keys(control.value).every(function (childKey) { return acc[getFormKey(control.controlRef.concat(childKey))].valid; });
692
+ }
693
+ return __assign(__assign({}, acc), (_b = {}, _b[key] = __assign(__assign({}, control), { errors: errors, valid: selfValid && childrenValid }), _b));
624
694
  }, {});
625
- var childrenErrorsChecked = Object.entries(errorsMerged).reduce(function (acc, _a) {
626
- var _b;
627
- var key = _a[0], control = _a[1];
628
- return __assign(__assign({}, acc), (_b = {}, _b[key] = __assign(__assign({}, control), { valid: control.valid &&
629
- getDescendantControls(control.controlRef, errorsMerged).every(function (control) { return control.valid; }) }), _b));
695
+ var restoredOrder = Object.keys(errorsMerged)
696
+ .reverse()
697
+ .reduce(function (acc, key) {
698
+ acc[key] = errorsMerged[key];
699
+ return acc;
630
700
  }, {});
631
- return childrenErrorsChecked;
701
+ return restoredOrder;
632
702
  };
633
703
 
634
704
  var isControlValidating = function (control) {
@@ -636,9 +706,6 @@ var isControlValidating = function (control) {
636
706
  return false;
637
707
  return Object.values(control.asyncValidateInProgress).some(function (pending) { return pending; });
638
708
  };
639
- var isControlAsyncValid = function (control) {
640
- return !Object.values(control.asyncValidatorErrors).some(function (error) { return error; });
641
- };
642
709
  var getControlByKey = function (key, form) {
643
710
  return Object.values(form).find(function (control) { return control.key === key; });
644
711
  };
@@ -656,15 +723,60 @@ var asyncValidationResponseSuccess = function (form, _a) {
656
723
  var key = _a[0], control = _a[1];
657
724
  if (ancestors.includes(control)) {
658
725
  var descendants = getDescendantControls(control.controlRef, controlUpdated);
659
- return __assign(__assign({}, acc), (_b = {}, _b[key] = __assign(__assign({}, control), { pending: descendants.some(function (control) { return isControlValidating(control); }), asyncValidatorsValid: descendants.every(function (control) { return isControlAsyncValid(control); }) }), _b));
726
+ return __assign(__assign({}, acc), (_b = {}, _b[key] = __assign(__assign({}, control), { pending: descendants.some(function (control) { return isControlValidating(control); }) }), _b));
660
727
  }
661
728
  return __assign(__assign({}, acc), (_c = {}, _c[key] = control, _c));
662
729
  }, {});
663
730
  return mergeErrors(ancestorsUpdated);
664
731
  };
665
732
 
733
+ var hasErrors = function (errors) {
734
+ return Object.values(errors).some(function (hasError) { return hasError; });
735
+ };
736
+ var mergeBranchErrors = function (form, controlRef) {
737
+ var controlBranch = getControlBranch(controlRef, form).reduce(function (acc, ctrl) {
738
+ var _a;
739
+ return __assign(__assign({}, acc), (_a = {}, _a[getFormKey(ctrl.controlRef)] = ctrl, _a));
740
+ }, {});
741
+ var errorsMerged = Object.entries(controlBranch)
742
+ .reverse()
743
+ .reduce(function (acc, _a) {
744
+ var _b;
745
+ var key = _a[0], control = _a[1];
746
+ var errors = __assign(__assign({}, control.validatorErrors), control.asyncValidatorErrors);
747
+ var selfValid = !hasErrors(errors);
748
+ var childrenValid = true;
749
+ if (Array.isArray(control.config.controls)) {
750
+ // If control is a FormArray
751
+ childrenValid = control.value.every(function (item, index) {
752
+ var formKey = getFormKey(control.controlRef.concat(index));
753
+ var valid = acc[formKey] === undefined ? form[formKey].valid : acc[formKey].valid;
754
+ return valid;
755
+ });
756
+ }
757
+ else if (control.config.controls) {
758
+ // If control is a FormGroup
759
+ childrenValid = Object.keys(control.value).every(function (childKey) {
760
+ var formKey = getFormKey(control.controlRef.concat(childKey));
761
+ var valid = acc[formKey] === undefined ? form[formKey].valid : acc[formKey].valid;
762
+ return valid;
763
+ });
764
+ }
765
+ return __assign(__assign({}, acc), (_b = {}, _b[key] = __assign(__assign({}, control), { errors: errors, valid: selfValid && childrenValid }), _b));
766
+ }, {});
767
+ return __assign(__assign({}, form), errorsMerged);
768
+ };
769
+
770
+ var mergeValueUpdated = function (state, form, controlRef) {
771
+ var controlBranch = getControlBranch(controlRef, form).reduce(function (acc, control) {
772
+ var _a;
773
+ var key = getFormKey(control.controlRef);
774
+ return __assign(__assign({}, acc), (_a = {}, _a[key] = __assign(__assign({}, state[key]), control), _a));
775
+ }, {});
776
+ return mergeBranchErrors(__assign(__assign({}, state), controlBranch), controlRef);
777
+ };
778
+
666
779
  var DEFAULT_HUB2_FIELDS = {
667
- asyncValidatorsValid: true,
668
780
  asyncValidatorErrors: {},
669
781
  asyncValidateInProgress: {},
670
782
  pending: false,
@@ -674,16 +786,28 @@ var DEFAULT_HUB2_FIELDS = {
674
786
  var formChange = function (state, _a) {
675
787
  if (state === void 0) { state = null; }
676
788
  var _b = _a.payload, form = _b.form, action = _b.action;
677
- return mergeErrors(Object.entries(form).reduce(function (acc, _a) {
678
- var _b;
679
- var dictKey = _a[0], baseControl = _a[1];
680
- var existingControl = (action === null || action === void 0 ? void 0 : action.type) === 'removeControl'
681
- ? state && Object.values(state).find(function (control) { return baseControl.key === control.key; })
682
- : state && state[dictKey];
683
- return __assign(__assign({}, acc), (_b = {}, _b[dictKey] = __assign(__assign({}, (existingControl
684
- ? existingControl
685
- : structuredClone(DEFAULT_HUB2_FIELDS))), baseControl), _b));
686
- }, {}));
789
+ if (state === null) {
790
+ return mergeErrors(Object.entries(form).reduce(function (acc, _a) {
791
+ var _b;
792
+ var dictKey = _a[0], baseControl = _a[1];
793
+ return __assign(__assign({}, acc), (_b = {}, _b[dictKey] = __assign(__assign({}, structuredClone(DEFAULT_HUB2_FIELDS)), baseControl), _b));
794
+ }, {}));
795
+ }
796
+ switch (action === null || action === void 0 ? void 0 : action.type) {
797
+ case 'updateValues':
798
+ return mergeValueUpdated(state, form, action.payload.controlRef);
799
+ default:
800
+ return mergeErrors(Object.entries(form).reduce(function (acc, _a) {
801
+ var _b;
802
+ var dictKey = _a[0], baseControl = _a[1];
803
+ var existingControl = (action === null || action === void 0 ? void 0 : action.type) === 'removeControl'
804
+ ? state && Object.values(state).find(function (control) { return baseControl.key === control.key; })
805
+ : state && state[dictKey];
806
+ return __assign(__assign({}, acc), (_b = {}, _b[dictKey] = __assign(__assign({}, (existingControl
807
+ ? existingControl
808
+ : structuredClone(DEFAULT_HUB2_FIELDS))), baseControl), _b));
809
+ }, {}));
810
+ }
687
811
  };
688
812
 
689
813
  var control = function (config) {
package/package.json CHANGED
@@ -14,12 +14,12 @@
14
14
  "author": "David Lai",
15
15
  "license": "ISC",
16
16
  "dependencies": {
17
- "@reactables/core": "^0.4.3-alpha.0",
17
+ "@reactables/core": "^0.4.4-alpha.0",
18
18
  "lodash.clonedeep": "^4.5.0",
19
19
  "lodash.isequal": "^4.5.0"
20
20
  },
21
21
  "peerDependencies": {
22
22
  "rxjs": "^6.0.0 || ^7.0.0"
23
23
  },
24
- "version": "0.4.3-alpha.0"
24
+ "version": "0.4.4-alpha.0"
25
25
  }