@rolster/react-forms 19.0.0 → 19.1.1

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/dist/cjs/index.js CHANGED
@@ -10,8 +10,8 @@ var react = require('react');
10
10
  class RolsterArrayControl {
11
11
  constructor(options) {
12
12
  this.uuid = options.uuid;
13
+ this.defaultValue = options.defaultValue;
13
14
  this.value = options.value;
14
- this.initialValue = options.initialValue;
15
15
  this.focused = !!options.focused;
16
16
  this.unfocused = !this.focused;
17
17
  this.touched = !!options.touched;
@@ -42,17 +42,20 @@ class RolsterArrayControl {
42
42
  touch() {
43
43
  this.untouched && this.refresh('touched', { touched: true });
44
44
  }
45
- setInitialValue(value) {
46
- if (value !== this.initialValue) {
45
+ setDefaultValue(value) {
46
+ if (value !== this.defaultValue) {
47
47
  const errors = this.validators
48
48
  ? helpers.controlIsValid({ value, validators: this.validators })
49
49
  : [];
50
- this.refresh('value', {
51
- dirty: false,
52
- errors,
53
- initialValue: value,
54
- value
55
- });
50
+ this.refresh('value', { errors, defaultValue: value, value });
51
+ }
52
+ }
53
+ setStartValue(value) {
54
+ if (value !== this.value) {
55
+ const errors = this.validators
56
+ ? helpers.controlIsValid({ value, validators: this.validators })
57
+ : [];
58
+ this.refresh('value', { errors, value });
56
59
  }
57
60
  }
58
61
  setValue(value) {
@@ -60,11 +63,7 @@ class RolsterArrayControl {
60
63
  const errors = this.validators
61
64
  ? helpers.controlIsValid({ value, validators: this.validators })
62
65
  : [];
63
- this.refresh('value', {
64
- dirty: true,
65
- errors,
66
- value
67
- });
66
+ this.refresh('value', { dirty: true, errors, value });
68
67
  }
69
68
  }
70
69
  setValidators(validators) {
@@ -85,7 +84,7 @@ class RolsterArrayControl {
85
84
  reset() {
86
85
  const errors = this.validators
87
86
  ? helpers.controlIsValid({
88
- value: this.initialValue,
87
+ value: this.defaultValue,
89
88
  validators: this.validators
90
89
  })
91
90
  : [];
@@ -93,7 +92,7 @@ class RolsterArrayControl {
93
92
  dirty: false,
94
93
  errors,
95
94
  touched: false,
96
- value: this.initialValue
95
+ value: this.defaultValue
97
96
  });
98
97
  }
99
98
  isValid(errors) {
@@ -117,7 +116,7 @@ function rolsterArrayControl(options, validators) {
117
116
  const formControl = _arguments.createFormControlOptions(options, validators);
118
117
  return new ReactRolsterArrayControl({
119
118
  ...formControl,
120
- initialValue: formControl.value,
119
+ defaultValue: formControl.value,
121
120
  uuid: uuid.v4()
122
121
  });
123
122
  }
@@ -233,12 +232,12 @@ class ReactRolsterArrayGroup extends RolsterArrayGroup {
233
232
  super({
234
233
  ...options,
235
234
  errors,
236
- value: helpers.controlsToValue(controls),
237
235
  dirties: helpers.controlsAllChecked(controls, 'dirty'),
238
236
  dirty: helpers.controlsPartialChecked(controls, 'dirty'),
239
237
  touched: helpers.controlsPartialChecked(controls, 'touched'),
240
238
  toucheds: helpers.controlsAllChecked(controls, 'touched'),
241
- valid: errors.length === 0 && helpers.controlsAllChecked(controls, 'valid')
239
+ valid: errors.length === 0 && helpers.controlsAllChecked(controls, 'valid'),
240
+ value: helpers.controlsToValue(controls)
242
241
  });
243
242
  }
244
243
  }
@@ -256,7 +255,7 @@ function formArrayGroup(options, validators) {
256
255
  class RolsterArrayList extends RolsterArrayControl {
257
256
  constructor(options) {
258
257
  const { controls, valueToControls, validators } = options;
259
- const value = controls.map((controls) => helpers.controlsToValue(controls));
258
+ const value = controls.map(helpers.controlsToValue);
260
259
  const errors = validators ? helpers.controlIsValid({ value, validators }) : [];
261
260
  super({ ...options, errors, value });
262
261
  this.valueToControls = valueToControls;
@@ -270,20 +269,28 @@ class RolsterArrayList extends RolsterArrayControl {
270
269
  this._subscribe(reactControls);
271
270
  });
272
271
  }
273
- setInitialValue(value) {
272
+ setDefaultValue(value) {
273
+ this.refresh('list', {
274
+ controls: value.map(this.valueToControls),
275
+ defaultValue: value
276
+ });
277
+ }
278
+ setStartValue(value) {
274
279
  this.refresh('list', {
275
- controls: value.map((value) => this.valueToControls(value)),
276
- initialValue: value
280
+ controls: value.map(this.valueToControls)
277
281
  });
278
282
  }
279
283
  setValue(value) {
280
284
  this.refresh('list', {
281
- controls: value.map((value) => this.valueToControls(value))
285
+ controls: value.map(this.valueToControls),
286
+ dirty: true
282
287
  });
283
288
  }
284
289
  reset() {
285
290
  this.refresh('list', {
286
- controls: this.initialValue.map((value) => this.valueToControls(value))
291
+ controls: this.defaultValue.map(this.valueToControls),
292
+ dirty: false,
293
+ touched: false
287
294
  });
288
295
  }
289
296
  push(controls) {
@@ -322,7 +329,7 @@ function formArrayList(options) {
322
329
  return new RolsterArrayList({
323
330
  ...options,
324
331
  controls: value.map((value) => options.valueToControls(value)),
325
- initialValue: value,
332
+ defaultValue: value,
326
333
  uuid: uuid.v4()
327
334
  });
328
335
  }
@@ -356,20 +363,21 @@ function refactorForControls(action, state, groups) {
356
363
  }
357
364
  function useFormArray(options, validators) {
358
365
  const formArray = _arguments.createFormArrayOptions(options, validators);
359
- const groups = formArray.groups || [];
360
- const value = react.useRef(groups);
366
+ const defaultValue = react.useRef(formArray.groups || []);
361
367
  const formGroups = react.useRef(new Map());
362
- const [state, setState] = react.useState({
363
- ...refactorForValid$1(groups, formArray.validators),
364
- controls: groups.map(({ controls }) => controls),
365
- dirty: false,
366
- dirties: false,
367
- disabled: false,
368
- groups,
369
- touched: false,
370
- toucheds: false,
371
- value: groups.map(({ controls }) => helpers.controlsToValue(controls)),
372
- validators: formArray.validators
368
+ const [state, setState] = react.useState(() => {
369
+ return {
370
+ ...refactorForValid$1(defaultValue.current, formArray.validators),
371
+ controls: defaultValue.current.map(({ controls }) => controls),
372
+ dirty: false,
373
+ dirties: false,
374
+ disabled: false,
375
+ groups: defaultValue.current,
376
+ touched: false,
377
+ toucheds: false,
378
+ value: defaultValue.current.map(({ controls }) => helpers.controlsToValue(controls)),
379
+ validators: formArray.validators
380
+ };
373
381
  });
374
382
  react.useEffect(() => {
375
383
  formGroups.current.clear();
@@ -380,8 +388,8 @@ function useFormArray(options, validators) {
380
388
  }, [state.groups]);
381
389
  const subscriber = react.useCallback((action, group) => {
382
390
  setState((state) => {
383
- const groups = state.groups.map((_group) => {
384
- return _group.uuid === group.uuid ? group : _group;
391
+ const groups = state.groups.map((currentGroup) => {
392
+ return currentGroup.uuid === group.uuid ? group : currentGroup;
385
393
  });
386
394
  return {
387
395
  ...state,
@@ -401,12 +409,12 @@ function useFormArray(options, validators) {
401
409
  ...refactorForGroups(groups, state.validators)
402
410
  }));
403
411
  }, []);
404
- const setInitialValue = react.useCallback((groups) => {
412
+ const setDefaultValue = react.useCallback((groups) => {
405
413
  setState((state) => ({
406
414
  ...state,
407
415
  ...refactorForGroups(groups, state.validators)
408
416
  }));
409
- value.current = groups;
417
+ defaultValue.current = groups;
410
418
  }, []);
411
419
  const push = react.useCallback((group) => {
412
420
  setState((state) => ({
@@ -436,12 +444,16 @@ function useFormArray(options, validators) {
436
444
  validators
437
445
  }));
438
446
  }, []);
439
- const hasError = react.useCallback((key) => helpers.hasError(state.errors, key), [state.errors]);
440
- const someErrors = react.useCallback((keys) => helpers.someErrors(state.errors, keys), [state.errors]);
447
+ const hasError = react.useCallback((key) => {
448
+ return helpers.hasError(state.errors, key);
449
+ }, [state.errors]);
450
+ const someErrors = react.useCallback((keys) => {
451
+ return helpers.someErrors(state.errors, keys);
452
+ }, [state.errors]);
441
453
  const reset = react.useCallback(() => {
442
454
  setState((state) => ({
443
455
  ...state,
444
- ...refactorForGroups(value.current, state.validators)
456
+ ...refactorForGroups(defaultValue.current, state.validators)
445
457
  }));
446
458
  }, []);
447
459
  return {
@@ -459,7 +471,7 @@ function useFormArray(options, validators) {
459
471
  push,
460
472
  remove,
461
473
  reset,
462
- setInitialValue,
474
+ setDefaultValue,
463
475
  setValidators,
464
476
  setValue,
465
477
  someErrors,
@@ -474,15 +486,17 @@ function errorsInControl(value, validators) {
474
486
  }
475
487
  function useControl(options, validators) {
476
488
  const formControl = _arguments.createFormControlOptions(options, validators);
477
- const initialValue = react.useRef(formControl.value);
478
- const [state, setState] = react.useState({
479
- dirty: false,
480
- disabled: false,
481
- errors: errorsInControl(formControl.value, formControl.validators),
482
- focused: false,
483
- touched: !!formControl.touched,
484
- value: formControl.value,
485
- validators: formControl.validators
489
+ const defaultValue = react.useRef(formControl.value);
490
+ const [state, setState] = react.useState(() => {
491
+ return {
492
+ dirty: false,
493
+ disabled: false,
494
+ errors: errorsInControl(formControl.value, formControl.validators),
495
+ focused: false,
496
+ touched: !!formControl.touched,
497
+ value: formControl.value,
498
+ validators: formControl.validators
499
+ };
486
500
  });
487
501
  const elementRef = react.useRef(null);
488
502
  const focus = react.useCallback(() => {
@@ -500,11 +514,17 @@ function useControl(options, validators) {
500
514
  const touch = react.useCallback(() => {
501
515
  setState((state) => ({ ...state, touched: true }));
502
516
  }, []);
503
- const setInitialValue = react.useCallback((value) => {
504
- initialValue.current = value;
517
+ const setDefaultValue = react.useCallback((value) => {
518
+ defaultValue.current = value;
519
+ setState((state) => ({
520
+ ...state,
521
+ errors: errorsInControl(value, state.validators),
522
+ value
523
+ }));
524
+ }, []);
525
+ const setStartValue = react.useCallback((value) => {
505
526
  setState((state) => ({
506
527
  ...state,
507
- dirty: true,
508
528
  errors: errorsInControl(value, state.validators),
509
529
  value
510
530
  }));
@@ -528,13 +548,17 @@ function useControl(options, validators) {
528
548
  setState((state) => ({
529
549
  ...state,
530
550
  dirty: false,
531
- errors: errorsInControl(initialValue.current, state.validators),
532
- value: initialValue.current,
551
+ errors: errorsInControl(defaultValue.current, state.validators),
552
+ value: defaultValue.current,
533
553
  touched: false
534
554
  }));
535
555
  }, []);
536
- const hasError = react.useCallback((key) => helpers.hasError(state.errors, key), [state.errors]);
537
- const someErrors = react.useCallback((keys) => helpers.someErrors(state.errors, keys), [state.errors]);
556
+ const hasError = react.useCallback((key) => {
557
+ return helpers.hasError(state.errors, key);
558
+ }, [state.errors]);
559
+ const someErrors = react.useCallback((keys) => {
560
+ return helpers.someErrors(state.errors, keys);
561
+ }, [state.errors]);
538
562
  const valid = state.errors.length === 0;
539
563
  return {
540
564
  ...state,
@@ -549,7 +573,8 @@ function useControl(options, validators) {
549
573
  invalid: !valid,
550
574
  pristine: !state.dirty,
551
575
  reset,
552
- setInitialValue,
576
+ setDefaultValue,
577
+ setStartValue,
553
578
  setValidators,
554
579
  setValue,
555
580
  someErrors,
@@ -577,26 +602,53 @@ function refactorForValid(controls, validators) {
577
602
  valid: errors.length === 0 && helpers.controlsAllChecked(controls, 'valid')
578
603
  };
579
604
  }
605
+ function checkAllSuccess(status) {
606
+ return status.reduce((success, status) => success && status, true);
607
+ }
608
+ function checkPartialSuccess(status) {
609
+ return status.reduce((success, status) => success || status, false);
610
+ }
580
611
  function useFormGroup(options, validators) {
581
612
  const formGroup = _arguments.createFormGroupOptions(options, validators);
582
- const firstEffects = react.useRef({
583
- dirty: true,
584
- disabledFocused: true,
585
- touched: true,
586
- value: true
613
+ const formInitialized = react.useRef({
614
+ dirty: false,
615
+ touched: false,
616
+ value: false,
617
+ visual: false
587
618
  });
588
- const [state, setState] = react.useState({
589
- ...refactorForValid(formGroup.controls, formGroup.validators),
590
- controls: formGroup.controls,
591
- dirties: helpers.controlsAllChecked(formGroup.controls, 'dirty'),
592
- dirty: helpers.controlsPartialChecked(formGroup.controls, 'dirty'),
593
- touched: helpers.controlsPartialChecked(formGroup.controls, 'touched'),
594
- toucheds: helpers.controlsAllChecked(formGroup.controls, 'touched'),
595
- value: helpers.controlsToValue(formGroup.controls),
596
- validators: formGroup.validators
619
+ const formGroupStatus = react.useMemo(() => {
620
+ const dirty = [];
621
+ const touched = [];
622
+ const value = [];
623
+ const visual = [];
624
+ Object.values(formGroup.controls).forEach((control) => {
625
+ dirty.push(control.dirty);
626
+ touched.push(control.touched);
627
+ value.push(control.value);
628
+ visual.push(control.disabled);
629
+ visual.push(control.focused);
630
+ });
631
+ return {
632
+ dirty,
633
+ touched,
634
+ value,
635
+ visual
636
+ };
637
+ }, [formGroup.controls]);
638
+ const [state, setState] = react.useState(() => {
639
+ return {
640
+ ...refactorForValid(formGroup.controls, formGroup.validators),
641
+ controls: formGroup.controls,
642
+ dirties: checkAllSuccess(formGroupStatus.dirty),
643
+ dirty: checkPartialSuccess(formGroupStatus.dirty),
644
+ touched: checkPartialSuccess(formGroupStatus.touched),
645
+ toucheds: checkAllSuccess(formGroupStatus.touched),
646
+ validators: formGroup.validators,
647
+ value: helpers.controlsToValue(formGroup.controls)
648
+ };
597
649
  });
598
650
  react.useEffect(() => {
599
- if (!firstEffects.current.value) {
651
+ if (formInitialized.current.value) {
600
652
  setState((state) => ({
601
653
  ...state,
602
654
  ...refactorForValid(formGroup.controls, state.validators),
@@ -605,49 +657,46 @@ function useFormGroup(options, validators) {
605
657
  }));
606
658
  }
607
659
  else {
608
- firstEffects.current.value = false;
660
+ formInitialized.current.value = true;
609
661
  }
610
- }, helpers.reduceControlsToArray(formGroup.controls, 'value'));
662
+ }, formGroupStatus.value);
611
663
  react.useEffect(() => {
612
- if (!firstEffects.current.disabledFocused) {
664
+ if (formInitialized.current.dirty) {
613
665
  setState((state) => ({
614
666
  ...state,
615
- controls: formGroup.controls
667
+ controls: formGroup.controls,
668
+ dirty: checkPartialSuccess(formGroupStatus.dirty),
669
+ dirties: checkAllSuccess(formGroupStatus.dirty)
616
670
  }));
617
671
  }
618
672
  else {
619
- firstEffects.current.disabledFocused = false;
673
+ formInitialized.current.dirty = true;
620
674
  }
621
- }, [
622
- ...helpers.reduceControlsToArray(formGroup.controls, 'disabled'),
623
- ...helpers.reduceControlsToArray(formGroup.controls, 'focused')
624
- ]);
675
+ }, formGroupStatus.dirty);
625
676
  react.useEffect(() => {
626
- if (!firstEffects.current.dirty) {
677
+ if (formInitialized.current.touched) {
627
678
  setState((state) => ({
628
679
  ...state,
629
680
  controls: formGroup.controls,
630
- dirty: helpers.controlsPartialChecked(formGroup.controls, 'dirty'),
631
- dirties: helpers.controlsAllChecked(formGroup.controls, 'dirty')
681
+ touched: checkPartialSuccess(formGroupStatus.touched),
682
+ toucheds: checkAllSuccess(formGroupStatus.touched)
632
683
  }));
633
684
  }
634
685
  else {
635
- firstEffects.current.dirty = false;
686
+ formInitialized.current.touched = true;
636
687
  }
637
- }, helpers.reduceControlsToArray(formGroup.controls, 'dirty'));
688
+ }, formGroupStatus.touched);
638
689
  react.useEffect(() => {
639
- if (!firstEffects.current.touched) {
690
+ if (formInitialized.current.visual) {
640
691
  setState((state) => ({
641
692
  ...state,
642
- controls: formGroup.controls,
643
- touched: helpers.controlsPartialChecked(formGroup.controls, 'touched'),
644
- toucheds: helpers.controlsAllChecked(formGroup.controls, 'touched')
693
+ controls: formGroup.controls
645
694
  }));
646
695
  }
647
696
  else {
648
- firstEffects.current.touched = false;
697
+ formInitialized.current.visual = true;
649
698
  }
650
- }, helpers.reduceControlsToArray(formGroup.controls, 'touched'));
699
+ }, formGroupStatus.visual);
651
700
  const setValidators = react.useCallback((validators) => {
652
701
  setState((state) => ({
653
702
  ...state,