@juantroconisf/lib 5.3.0 → 6.0.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/dist/index.d.mts CHANGED
@@ -81,8 +81,8 @@ interface FormOptions<O extends StateType> {
81
81
  */
82
82
  arrayIdentifiers?: Partial<Record<ArrayKeys<O>, string>>;
83
83
  }
84
- type TouchedType<O extends StateType> = Record<keyof O, boolean>;
85
- type ErrorsType<O extends StateType> = Record<keyof O, NextUIError>;
84
+ type TouchedType = Map<string, boolean>;
85
+ type ErrorsType = Map<string, NextUIError>;
86
86
  type ValueChangeFunc<O extends StateType, K extends keyof O> = (id: K, value: O[K]) => void;
87
87
  type BlurFunc<O extends StateType> = (id: keyof O) => void;
88
88
  interface ComponentInputProps<O extends StateType> {
@@ -181,8 +181,8 @@ interface UseFormResponse<O extends StateType> {
181
181
  onSelectionChange: ValueChangeFunc<O, keyof O>;
182
182
  state: O;
183
183
  setState: React.Dispatch<React.SetStateAction<O>>;
184
- touched: TouchedType<O>;
185
- errors: ErrorsType<O>;
184
+ touched: TouchedType;
185
+ errors: ErrorsType;
186
186
  /** Main object to bind form elements to the state. */
187
187
  on: OnMethods<O>;
188
188
  /** Array manipulation helpers. */
package/dist/index.d.ts CHANGED
@@ -81,8 +81,8 @@ interface FormOptions<O extends StateType> {
81
81
  */
82
82
  arrayIdentifiers?: Partial<Record<ArrayKeys<O>, string>>;
83
83
  }
84
- type TouchedType<O extends StateType> = Record<keyof O, boolean>;
85
- type ErrorsType<O extends StateType> = Record<keyof O, NextUIError>;
84
+ type TouchedType = Map<string, boolean>;
85
+ type ErrorsType = Map<string, NextUIError>;
86
86
  type ValueChangeFunc<O extends StateType, K extends keyof O> = (id: K, value: O[K]) => void;
87
87
  type BlurFunc<O extends StateType> = (id: keyof O) => void;
88
88
  interface ComponentInputProps<O extends StateType> {
@@ -181,8 +181,8 @@ interface UseFormResponse<O extends StateType> {
181
181
  onSelectionChange: ValueChangeFunc<O, keyof O>;
182
182
  state: O;
183
183
  setState: React.Dispatch<React.SetStateAction<O>>;
184
- touched: TouchedType<O>;
185
- errors: ErrorsType<O>;
184
+ touched: TouchedType;
185
+ errors: ErrorsType;
186
186
  /** Main object to bind form elements to the state. */
187
187
  on: OnMethods<O>;
188
188
  /** Array manipulation helpers. */
package/dist/index.js CHANGED
@@ -82,10 +82,10 @@ function getNestedValue(obj, path) {
82
82
  return path.split(".").reduce((acc, key) => acc?.[key], obj);
83
83
  }
84
84
  function removeCompositeKeysByPrefix(map2, prefix) {
85
- const result = {};
86
- for (const [key, value] of Object.entries(map2)) {
87
- if (!key.startsWith(prefix)) {
88
- result[key] = value;
85
+ const result = new Map(map2);
86
+ for (const key of map2.keys()) {
87
+ if (key.startsWith(prefix)) {
88
+ result.delete(key);
89
89
  }
90
90
  }
91
91
  return result;
@@ -101,13 +101,6 @@ function setNestedValue(state, dotPath, value) {
101
101
  current[keys[keys.length - 1]] = value;
102
102
  return copy;
103
103
  }
104
- var allToValue = (obj, value) => Object.keys(obj).reduce(
105
- (acc, key) => {
106
- acc[key] = value;
107
- return acc;
108
- },
109
- {}
110
- );
111
104
  var regex = {
112
105
  email: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
113
106
  password: /^(?!.*\s)(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[~`!@#$%^&*()--+={}[\]|:;"'<>,.?/_₹]).{8,24}$/
@@ -233,14 +226,7 @@ function useForm(initialState, {
233
226
  arrayMessages,
234
227
  arrayIdentifiers
235
228
  } = {}) {
236
- const initial = {
237
- touched: allToValue(initialState, false),
238
- errors: allToValue(initialState, {
239
- isInvalid: false,
240
- errorMessage: ""
241
- })
242
- };
243
- const [state, setState] = (0, import_react.useState)(initialState), [touched, setTouched] = (0, import_react.useState)(initial.touched), [errors2, setErrors] = (0, import_react.useState)(initial.errors), [itemTouched, setItemTouched] = (0, import_react.useState)({}), [itemErrors, setItemErrors] = (0, import_react.useState)({}), [nestedTouched, setNestedTouched] = (0, import_react.useState)({}), [nestedErrors, setNestedErrors] = (0, import_react.useState)({}), { performValidations } = useValidate();
229
+ const [state, setState] = (0, import_react.useState)(initialState), [touched, setTouched] = (0, import_react.useState)(/* @__PURE__ */ new Map()), [errors2, setErrors] = (0, import_react.useState)(/* @__PURE__ */ new Map()), { performValidations } = useValidate();
244
230
  const indexMap = (0, import_react.useMemo)(() => {
245
231
  const map2 = /* @__PURE__ */ new Map();
246
232
  for (const key in state) {
@@ -266,39 +252,34 @@ function useForm(initialState, {
266
252
  },
267
253
  [indexMap]
268
254
  );
269
- const validateInput = (id, value) => setErrors(
270
- (prev) => handleNestedChange({
271
- state: prev,
272
- id,
273
- value: performValidations(value, rules?.[id], messages?.[id])
274
- })
275
- );
255
+ const validateInput = (compositeKey, value, ruleKey) => {
256
+ const error = performValidations(
257
+ value,
258
+ rules?.[ruleKey],
259
+ messages?.[ruleKey]
260
+ );
261
+ setErrors((prev) => new Map(prev).set(compositeKey, error));
262
+ };
276
263
  const getUXProps = (0, import_react.useCallback)(
277
- (id) => {
278
- const inputError = errors2[id] || nestedErrors[id];
279
- const isTouched = touched[id] || nestedTouched[id];
264
+ (compositeKey) => {
265
+ const inputError = errors2.get(compositeKey);
266
+ const isTouched = touched.get(compositeKey);
280
267
  return {
281
268
  isInvalid: Boolean(isTouched && inputError?.isInvalid),
282
269
  errorMessage: isTouched ? inputError?.errorMessage || "" : ""
283
270
  };
284
271
  },
285
- [errors2, touched, nestedErrors, nestedTouched]
272
+ [errors2, touched]
286
273
  );
287
274
  const onBlur = (id) => {
288
- validateInput(id, state[id]);
289
- if (touched[id]) return;
290
- setTouched(
291
- (prev) => handleNestedChange({
292
- state: prev,
293
- id,
294
- value: true
295
- })
296
- );
275
+ validateInput(String(id), state[id], id);
276
+ if (touched.get(String(id))) return;
277
+ setTouched((prev) => new Map(prev).set(String(id), true));
297
278
  }, onValueChange = ((...args) => {
298
279
  if (args.length === 2) {
299
280
  const [id, value] = args;
300
281
  setState((prev) => handleNestedChange({ state: prev, id, value }));
301
- validateInput(id, value);
282
+ validateInput(String(id), value, id);
302
283
  return;
303
284
  }
304
285
  if (args.length === 3) {
@@ -344,7 +325,7 @@ function useForm(initialState, {
344
325
  value: fixedValue
345
326
  })
346
327
  );
347
- validateInput(id, fixedValue);
328
+ validateInput(String(id), fixedValue, id);
348
329
  };
349
330
  const getItemCompositeKey = (arrayKey, itemId, field) => `${arrayKey}.${itemId}.${field}`;
350
331
  const getPrimitiveCompositeKey = (arrayKey, index) => `${arrayKey}.@${index}`;
@@ -357,22 +338,24 @@ function useForm(initialState, {
357
338
  const fieldRules = typeof arrayRuleDef === "function" ? arrayRuleDef(item, index) : arrayRuleDef;
358
339
  const fieldMessages = arrayMessages?.[arrayKey]?.[field];
359
340
  const compositeKey = getItemCompositeKey(String(arrayKey), itemId, field);
360
- setItemErrors((prev) => ({
361
- ...prev,
362
- [compositeKey]: performValidations(value, fieldRules, fieldMessages)
363
- }));
341
+ setErrors(
342
+ (prev) => new Map(prev).set(
343
+ compositeKey,
344
+ performValidations(value, fieldRules, fieldMessages)
345
+ )
346
+ );
364
347
  };
365
348
  const getItemUXProps = (0, import_react.useCallback)(
366
349
  (arrayKey, itemId, field) => {
367
350
  const compositeKey = getItemCompositeKey(arrayKey, itemId, field);
368
- const inputError = itemErrors[compositeKey];
369
- const isTouched = itemTouched[compositeKey];
351
+ const inputError = errors2.get(compositeKey);
352
+ const isTouched = touched.get(compositeKey);
370
353
  return {
371
354
  isInvalid: Boolean(isTouched && inputError?.isInvalid),
372
355
  errorMessage: isTouched ? inputError?.errorMessage || "" : ""
373
356
  };
374
357
  },
375
- [itemErrors, itemTouched]
358
+ [errors2, touched]
376
359
  );
377
360
  const onItemBlur = (arrayKey, itemId, field) => {
378
361
  const index = getIndex(String(arrayKey), itemId);
@@ -381,8 +364,8 @@ function useForm(initialState, {
381
364
  const value = getNestedValue(arr[index], field);
382
365
  validateItemInput(arrayKey, itemId, field, value);
383
366
  const compositeKey = getItemCompositeKey(String(arrayKey), itemId, field);
384
- if (itemTouched[compositeKey]) return;
385
- setItemTouched((prev) => ({ ...prev, [compositeKey]: true }));
367
+ if (touched.get(compositeKey)) return;
368
+ setTouched((prev) => new Map(prev).set(compositeKey, true));
386
369
  };
387
370
  const onItemValueChange = (arrayKey, itemId, field, value) => {
388
371
  const index = getIndex(String(arrayKey), itemId);
@@ -412,16 +395,18 @@ function useForm(initialState, {
412
395
  };
413
396
  const validateNestedInput = (dotPath, value) => {
414
397
  const topKey = dotPath.split(".")[0];
415
- setNestedErrors((prev) => ({
416
- ...prev,
417
- [dotPath]: performValidations(value, rules?.[topKey], messages?.[topKey])
418
- }));
398
+ setErrors(
399
+ (prev) => new Map(prev).set(
400
+ dotPath,
401
+ performValidations(value, rules?.[topKey], messages?.[topKey])
402
+ )
403
+ );
419
404
  };
420
405
  const onNestedBlur = (dotPath) => {
421
406
  const value = getNestedValue(state, dotPath);
422
407
  validateNestedInput(dotPath, value);
423
- if (nestedTouched[dotPath]) return;
424
- setNestedTouched((prev) => ({ ...prev, [dotPath]: true }));
408
+ if (touched.get(dotPath)) return;
409
+ setTouched((prev) => new Map(prev).set(dotPath, true));
425
410
  };
426
411
  const onNestedValueChange = (dotPath, value) => {
427
412
  setState((prev) => setNestedValue(prev, dotPath, value));
@@ -466,12 +451,8 @@ function useForm(initialState, {
466
451
  ...getItemUXProps(String(arrayKey2), `@${index2}`, ""),
467
452
  id: compositeKey2,
468
453
  onBlur: () => {
469
- const compositeKey3 = getPrimitiveCompositeKey(
470
- String(arrayKey2),
471
- index2
472
- );
473
- if (itemTouched[compositeKey3]) return;
474
- setItemTouched((prev) => ({ ...prev, [compositeKey3]: true }));
454
+ if (touched.get(compositeKey2)) return;
455
+ setTouched((prev) => new Map(prev).set(compositeKey2, true));
475
456
  },
476
457
  onValueChange: (v) => {
477
458
  setState((prev) => {
@@ -479,6 +460,7 @@ function useForm(initialState, {
479
460
  arr3[index2] = v;
480
461
  return { ...prev, [arrayKey2]: arr3 };
481
462
  });
463
+ validateItemInput(arrayKey2, `@${index2}`, "", v);
482
464
  },
483
465
  value: value2
484
466
  };
@@ -499,8 +481,8 @@ function useForm(initialState, {
499
481
  ...getItemUXProps(String(parentKey), parentId, `${field2}.@${index2}`),
500
482
  id: compositeKey2,
501
483
  onBlur: () => {
502
- if (itemTouched[compositeKey2]) return;
503
- setItemTouched((prev) => ({ ...prev, [compositeKey2]: true }));
484
+ if (touched.get(compositeKey2)) return;
485
+ setTouched((prev) => new Map(prev).set(compositeKey2, true));
504
486
  },
505
487
  onValueChange: (v) => {
506
488
  if (parentIndex === void 0) return;
@@ -512,6 +494,8 @@ function useForm(initialState, {
512
494
  parentArr[parentIndex] = setNestedValue(item, field2, nestedArr2);
513
495
  return { ...prev, [parentKey]: parentArr };
514
496
  });
497
+ const fieldPath = `${field2}.@${index2}`;
498
+ validateItemInput(parentKey, parentId, fieldPath, v);
515
499
  },
516
500
  value: value2
517
501
  };
@@ -566,8 +550,8 @@ function useForm(initialState, {
566
550
  ...getItemUXProps(String(arrayKey2), `@${index2}`, ""),
567
551
  id: compositeKey2,
568
552
  onBlur: () => {
569
- if (itemTouched[compositeKey2]) return;
570
- setItemTouched((prev) => ({ ...prev, [compositeKey2]: true }));
553
+ if (touched.get(compositeKey2)) return;
554
+ setTouched((prev) => new Map(prev).set(compositeKey2, true));
571
555
  },
572
556
  onSelectionChange: (v) => {
573
557
  const fixedValue = typeof v === "string" || v === null ? v : Array.from(v)[0] || null;
@@ -576,6 +560,7 @@ function useForm(initialState, {
576
560
  arr3[index2] = fixedValue;
577
561
  return { ...prev, [arrayKey2]: arr3 };
578
562
  });
563
+ validateItemInput(arrayKey2, `@${index2}`, "", fixedValue);
579
564
  },
580
565
  selectedKeys: value2 === null ? [] : [value2]
581
566
  };
@@ -596,8 +581,8 @@ function useForm(initialState, {
596
581
  ...getItemUXProps(String(parentKey), parentId, `${field2}.@${index2}`),
597
582
  id: compositeKey2,
598
583
  onBlur: () => {
599
- if (itemTouched[compositeKey2]) return;
600
- setItemTouched((prev) => ({ ...prev, [compositeKey2]: true }));
584
+ if (touched.get(compositeKey2)) return;
585
+ setTouched((prev) => new Map(prev).set(compositeKey2, true));
601
586
  },
602
587
  onSelectionChange: (v) => {
603
588
  if (parentIndex === void 0) return;
@@ -610,6 +595,8 @@ function useForm(initialState, {
610
595
  parentArr[parentIndex] = setNestedValue(item, field2, nestedArr2);
611
596
  return { ...prev, [parentKey]: parentArr };
612
597
  });
598
+ const fieldPath = `${field2}.@${index2}`;
599
+ validateItemInput(parentKey, parentId, fieldPath, fixedValue);
613
600
  },
614
601
  selectedKeys: value2 === null ? [] : [value2]
615
602
  };
@@ -659,15 +646,17 @@ function useForm(initialState, {
659
646
  ...getItemUXProps(String(arrayKey2), `@${index2}`, ""),
660
647
  id: compositeKey2,
661
648
  onBlur: () => {
662
- if (itemTouched[compositeKey2]) return;
663
- setItemTouched((prev) => ({ ...prev, [compositeKey2]: true }));
649
+ if (touched.get(compositeKey2)) return;
650
+ setTouched((prev) => new Map(prev).set(compositeKey2, true));
664
651
  },
665
652
  onSelectionChange: (v) => {
653
+ const fixedValue = typeof v === "string" || v === null ? v : String(v);
666
654
  setState((prev) => {
667
655
  const arr3 = [...prev[arrayKey2]];
668
- arr3[index2] = typeof v === "string" || v === null ? v : String(v);
656
+ arr3[index2] = fixedValue;
669
657
  return { ...prev, [arrayKey2]: arr3 };
670
658
  });
659
+ validateItemInput(arrayKey2, `@${index2}`, "", fixedValue);
671
660
  },
672
661
  selectedKey: value2
673
662
  };
@@ -688,19 +677,22 @@ function useForm(initialState, {
688
677
  ...getItemUXProps(String(parentKey), parentId, `${field2}.@${index2}`),
689
678
  id: compositeKey2,
690
679
  onBlur: () => {
691
- if (itemTouched[compositeKey2]) return;
692
- setItemTouched((prev) => ({ ...prev, [compositeKey2]: true }));
680
+ if (touched.get(compositeKey2)) return;
681
+ setTouched((prev) => new Map(prev).set(compositeKey2, true));
693
682
  },
694
683
  onSelectionChange: (v) => {
695
684
  if (parentIndex === void 0) return;
685
+ const fixedValue = typeof v === "string" || v === null ? v : String(v);
696
686
  setState((prev) => {
697
687
  const parentArr = [...prev[parentKey]];
698
688
  const item = { ...parentArr[parentIndex] };
699
689
  const nestedArr2 = [...getNestedValue(item, field2) || []];
700
- nestedArr2[index2] = typeof v === "string" || v === null ? v : String(v);
690
+ nestedArr2[index2] = fixedValue;
701
691
  parentArr[parentIndex] = setNestedValue(item, field2, nestedArr2);
702
692
  return { ...prev, [parentKey]: parentArr };
703
693
  });
694
+ const fieldPath = `${field2}.@${index2}`;
695
+ validateItemInput(parentKey, parentId, fieldPath, fixedValue);
704
696
  },
705
697
  selectedKey: value2
706
698
  };
@@ -751,8 +743,8 @@ function useForm(initialState, {
751
743
  });
752
744
  if (itemId !== void 0) {
753
745
  const prefix = `${String(arrayKey)}.${itemId}.`;
754
- setItemTouched((prev) => removeCompositeKeysByPrefix(prev, prefix));
755
- setItemErrors((prev) => removeCompositeKeysByPrefix(prev, prefix));
746
+ setTouched((prev) => removeCompositeKeysByPrefix(prev, prefix));
747
+ setErrors((prev) => removeCompositeKeysByPrefix(prev, prefix));
756
748
  }
757
749
  },
758
750
  removeById: (arrayKey, itemId) => {
@@ -762,8 +754,8 @@ function useForm(initialState, {
762
754
  arr.splice(index, 1);
763
755
  setState((prev) => ({ ...prev, [arrayKey]: arr }));
764
756
  const prefix = `${String(arrayKey)}.${itemId}.`;
765
- setItemTouched((prev) => removeCompositeKeysByPrefix(prev, prefix));
766
- setItemErrors((prev) => removeCompositeKeysByPrefix(prev, prefix));
757
+ setTouched((prev) => removeCompositeKeysByPrefix(prev, prefix));
758
+ setErrors((prev) => removeCompositeKeysByPrefix(prev, prefix));
767
759
  }
768
760
  },
769
761
  moveItem: (arrayKey, from, to) => {
@@ -803,35 +795,12 @@ function useForm(initialState, {
803
795
  },
804
796
  isDirty: JSON.stringify(state) !== JSON.stringify(initialState),
805
797
  hasInvalidValues: () => {
806
- setTouched((prev) => allToValue(prev, true));
807
- setItemTouched(
808
- (prev) => Object.keys(prev).reduce(
809
- (acc, key) => ({ ...acc, [key]: true }),
810
- {}
811
- )
812
- );
813
- setNestedTouched(
814
- (prev) => Object.keys(prev).reduce(
815
- (acc, key) => ({ ...acc, [key]: true }),
816
- {}
817
- )
818
- );
819
- const topLevelInvalid = JSON.stringify(errors2).includes(":true");
820
- const itemLevelInvalid = Object.values(itemErrors).some(
821
- (e) => e?.isInvalid
822
- );
823
- const nestedLevelInvalid = Object.values(nestedErrors).some(
824
- (e) => e?.isInvalid
825
- );
826
- return topLevelInvalid || itemLevelInvalid || nestedLevelInvalid;
798
+ const isInvalid = Array.from(errors2.values()).some((e) => e?.isInvalid);
799
+ return isInvalid;
827
800
  },
828
801
  resetForm: (preservedKeys) => {
829
- setTouched(initial.touched);
830
- setErrors(initial.errors);
831
- setItemTouched({});
832
- setItemErrors({});
833
- setNestedTouched({});
834
- setNestedErrors({});
802
+ setTouched(/* @__PURE__ */ new Map());
803
+ setErrors(/* @__PURE__ */ new Map());
835
804
  setState(
836
805
  (prev) => preservedKeys === void 0 ? initialState : preservedKeys.reduce(
837
806
  (acc, key) => ({
@@ -843,16 +812,13 @@ function useForm(initialState, {
843
812
  );
844
813
  },
845
814
  resetTouched: (preservedKeys) => {
846
- setItemTouched({});
847
- setNestedTouched({});
848
815
  setTouched(
849
- (prev) => preservedKeys === void 0 ? initialState : preservedKeys.reduce(
850
- (acc, key) => ({
851
- ...acc,
852
- [key]: prev[key]
853
- }),
854
- initial.touched
855
- )
816
+ (prev) => preservedKeys === void 0 ? /* @__PURE__ */ new Map() : preservedKeys.reduce((acc, key) => {
817
+ if (prev.has(String(key))) {
818
+ acc.set(String(key), prev.get(String(key)));
819
+ }
820
+ return acc;
821
+ }, /* @__PURE__ */ new Map())
856
822
  );
857
823
  }
858
824
  };
package/dist/index.mjs CHANGED
@@ -63,10 +63,10 @@ function getNestedValue(obj, path) {
63
63
  return path.split(".").reduce((acc, key) => acc?.[key], obj);
64
64
  }
65
65
  function removeCompositeKeysByPrefix(map2, prefix) {
66
- const result = {};
67
- for (const [key, value] of Object.entries(map2)) {
68
- if (!key.startsWith(prefix)) {
69
- result[key] = value;
66
+ const result = new Map(map2);
67
+ for (const key of map2.keys()) {
68
+ if (key.startsWith(prefix)) {
69
+ result.delete(key);
70
70
  }
71
71
  }
72
72
  return result;
@@ -82,13 +82,6 @@ function setNestedValue(state, dotPath, value) {
82
82
  current[keys[keys.length - 1]] = value;
83
83
  return copy;
84
84
  }
85
- var allToValue = (obj, value) => Object.keys(obj).reduce(
86
- (acc, key) => {
87
- acc[key] = value;
88
- return acc;
89
- },
90
- {}
91
- );
92
85
  var regex = {
93
86
  email: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
94
87
  password: /^(?!.*\s)(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[~`!@#$%^&*()--+={}[\]|:;"'<>,.?/_₹]).{8,24}$/
@@ -214,14 +207,7 @@ function useForm(initialState, {
214
207
  arrayMessages,
215
208
  arrayIdentifiers
216
209
  } = {}) {
217
- const initial = {
218
- touched: allToValue(initialState, false),
219
- errors: allToValue(initialState, {
220
- isInvalid: false,
221
- errorMessage: ""
222
- })
223
- };
224
- const [state, setState] = useState(initialState), [touched, setTouched] = useState(initial.touched), [errors2, setErrors] = useState(initial.errors), [itemTouched, setItemTouched] = useState({}), [itemErrors, setItemErrors] = useState({}), [nestedTouched, setNestedTouched] = useState({}), [nestedErrors, setNestedErrors] = useState({}), { performValidations } = useValidate();
210
+ const [state, setState] = useState(initialState), [touched, setTouched] = useState(/* @__PURE__ */ new Map()), [errors2, setErrors] = useState(/* @__PURE__ */ new Map()), { performValidations } = useValidate();
225
211
  const indexMap = useMemo(() => {
226
212
  const map2 = /* @__PURE__ */ new Map();
227
213
  for (const key in state) {
@@ -247,39 +233,34 @@ function useForm(initialState, {
247
233
  },
248
234
  [indexMap]
249
235
  );
250
- const validateInput = (id, value) => setErrors(
251
- (prev) => handleNestedChange({
252
- state: prev,
253
- id,
254
- value: performValidations(value, rules?.[id], messages?.[id])
255
- })
256
- );
236
+ const validateInput = (compositeKey, value, ruleKey) => {
237
+ const error = performValidations(
238
+ value,
239
+ rules?.[ruleKey],
240
+ messages?.[ruleKey]
241
+ );
242
+ setErrors((prev) => new Map(prev).set(compositeKey, error));
243
+ };
257
244
  const getUXProps = useCallback(
258
- (id) => {
259
- const inputError = errors2[id] || nestedErrors[id];
260
- const isTouched = touched[id] || nestedTouched[id];
245
+ (compositeKey) => {
246
+ const inputError = errors2.get(compositeKey);
247
+ const isTouched = touched.get(compositeKey);
261
248
  return {
262
249
  isInvalid: Boolean(isTouched && inputError?.isInvalid),
263
250
  errorMessage: isTouched ? inputError?.errorMessage || "" : ""
264
251
  };
265
252
  },
266
- [errors2, touched, nestedErrors, nestedTouched]
253
+ [errors2, touched]
267
254
  );
268
255
  const onBlur = (id) => {
269
- validateInput(id, state[id]);
270
- if (touched[id]) return;
271
- setTouched(
272
- (prev) => handleNestedChange({
273
- state: prev,
274
- id,
275
- value: true
276
- })
277
- );
256
+ validateInput(String(id), state[id], id);
257
+ if (touched.get(String(id))) return;
258
+ setTouched((prev) => new Map(prev).set(String(id), true));
278
259
  }, onValueChange = ((...args) => {
279
260
  if (args.length === 2) {
280
261
  const [id, value] = args;
281
262
  setState((prev) => handleNestedChange({ state: prev, id, value }));
282
- validateInput(id, value);
263
+ validateInput(String(id), value, id);
283
264
  return;
284
265
  }
285
266
  if (args.length === 3) {
@@ -325,7 +306,7 @@ function useForm(initialState, {
325
306
  value: fixedValue
326
307
  })
327
308
  );
328
- validateInput(id, fixedValue);
309
+ validateInput(String(id), fixedValue, id);
329
310
  };
330
311
  const getItemCompositeKey = (arrayKey, itemId, field) => `${arrayKey}.${itemId}.${field}`;
331
312
  const getPrimitiveCompositeKey = (arrayKey, index) => `${arrayKey}.@${index}`;
@@ -338,22 +319,24 @@ function useForm(initialState, {
338
319
  const fieldRules = typeof arrayRuleDef === "function" ? arrayRuleDef(item, index) : arrayRuleDef;
339
320
  const fieldMessages = arrayMessages?.[arrayKey]?.[field];
340
321
  const compositeKey = getItemCompositeKey(String(arrayKey), itemId, field);
341
- setItemErrors((prev) => ({
342
- ...prev,
343
- [compositeKey]: performValidations(value, fieldRules, fieldMessages)
344
- }));
322
+ setErrors(
323
+ (prev) => new Map(prev).set(
324
+ compositeKey,
325
+ performValidations(value, fieldRules, fieldMessages)
326
+ )
327
+ );
345
328
  };
346
329
  const getItemUXProps = useCallback(
347
330
  (arrayKey, itemId, field) => {
348
331
  const compositeKey = getItemCompositeKey(arrayKey, itemId, field);
349
- const inputError = itemErrors[compositeKey];
350
- const isTouched = itemTouched[compositeKey];
332
+ const inputError = errors2.get(compositeKey);
333
+ const isTouched = touched.get(compositeKey);
351
334
  return {
352
335
  isInvalid: Boolean(isTouched && inputError?.isInvalid),
353
336
  errorMessage: isTouched ? inputError?.errorMessage || "" : ""
354
337
  };
355
338
  },
356
- [itemErrors, itemTouched]
339
+ [errors2, touched]
357
340
  );
358
341
  const onItemBlur = (arrayKey, itemId, field) => {
359
342
  const index = getIndex(String(arrayKey), itemId);
@@ -362,8 +345,8 @@ function useForm(initialState, {
362
345
  const value = getNestedValue(arr[index], field);
363
346
  validateItemInput(arrayKey, itemId, field, value);
364
347
  const compositeKey = getItemCompositeKey(String(arrayKey), itemId, field);
365
- if (itemTouched[compositeKey]) return;
366
- setItemTouched((prev) => ({ ...prev, [compositeKey]: true }));
348
+ if (touched.get(compositeKey)) return;
349
+ setTouched((prev) => new Map(prev).set(compositeKey, true));
367
350
  };
368
351
  const onItemValueChange = (arrayKey, itemId, field, value) => {
369
352
  const index = getIndex(String(arrayKey), itemId);
@@ -393,16 +376,18 @@ function useForm(initialState, {
393
376
  };
394
377
  const validateNestedInput = (dotPath, value) => {
395
378
  const topKey = dotPath.split(".")[0];
396
- setNestedErrors((prev) => ({
397
- ...prev,
398
- [dotPath]: performValidations(value, rules?.[topKey], messages?.[topKey])
399
- }));
379
+ setErrors(
380
+ (prev) => new Map(prev).set(
381
+ dotPath,
382
+ performValidations(value, rules?.[topKey], messages?.[topKey])
383
+ )
384
+ );
400
385
  };
401
386
  const onNestedBlur = (dotPath) => {
402
387
  const value = getNestedValue(state, dotPath);
403
388
  validateNestedInput(dotPath, value);
404
- if (nestedTouched[dotPath]) return;
405
- setNestedTouched((prev) => ({ ...prev, [dotPath]: true }));
389
+ if (touched.get(dotPath)) return;
390
+ setTouched((prev) => new Map(prev).set(dotPath, true));
406
391
  };
407
392
  const onNestedValueChange = (dotPath, value) => {
408
393
  setState((prev) => setNestedValue(prev, dotPath, value));
@@ -447,12 +432,8 @@ function useForm(initialState, {
447
432
  ...getItemUXProps(String(arrayKey2), `@${index2}`, ""),
448
433
  id: compositeKey2,
449
434
  onBlur: () => {
450
- const compositeKey3 = getPrimitiveCompositeKey(
451
- String(arrayKey2),
452
- index2
453
- );
454
- if (itemTouched[compositeKey3]) return;
455
- setItemTouched((prev) => ({ ...prev, [compositeKey3]: true }));
435
+ if (touched.get(compositeKey2)) return;
436
+ setTouched((prev) => new Map(prev).set(compositeKey2, true));
456
437
  },
457
438
  onValueChange: (v) => {
458
439
  setState((prev) => {
@@ -460,6 +441,7 @@ function useForm(initialState, {
460
441
  arr3[index2] = v;
461
442
  return { ...prev, [arrayKey2]: arr3 };
462
443
  });
444
+ validateItemInput(arrayKey2, `@${index2}`, "", v);
463
445
  },
464
446
  value: value2
465
447
  };
@@ -480,8 +462,8 @@ function useForm(initialState, {
480
462
  ...getItemUXProps(String(parentKey), parentId, `${field2}.@${index2}`),
481
463
  id: compositeKey2,
482
464
  onBlur: () => {
483
- if (itemTouched[compositeKey2]) return;
484
- setItemTouched((prev) => ({ ...prev, [compositeKey2]: true }));
465
+ if (touched.get(compositeKey2)) return;
466
+ setTouched((prev) => new Map(prev).set(compositeKey2, true));
485
467
  },
486
468
  onValueChange: (v) => {
487
469
  if (parentIndex === void 0) return;
@@ -493,6 +475,8 @@ function useForm(initialState, {
493
475
  parentArr[parentIndex] = setNestedValue(item, field2, nestedArr2);
494
476
  return { ...prev, [parentKey]: parentArr };
495
477
  });
478
+ const fieldPath = `${field2}.@${index2}`;
479
+ validateItemInput(parentKey, parentId, fieldPath, v);
496
480
  },
497
481
  value: value2
498
482
  };
@@ -547,8 +531,8 @@ function useForm(initialState, {
547
531
  ...getItemUXProps(String(arrayKey2), `@${index2}`, ""),
548
532
  id: compositeKey2,
549
533
  onBlur: () => {
550
- if (itemTouched[compositeKey2]) return;
551
- setItemTouched((prev) => ({ ...prev, [compositeKey2]: true }));
534
+ if (touched.get(compositeKey2)) return;
535
+ setTouched((prev) => new Map(prev).set(compositeKey2, true));
552
536
  },
553
537
  onSelectionChange: (v) => {
554
538
  const fixedValue = typeof v === "string" || v === null ? v : Array.from(v)[0] || null;
@@ -557,6 +541,7 @@ function useForm(initialState, {
557
541
  arr3[index2] = fixedValue;
558
542
  return { ...prev, [arrayKey2]: arr3 };
559
543
  });
544
+ validateItemInput(arrayKey2, `@${index2}`, "", fixedValue);
560
545
  },
561
546
  selectedKeys: value2 === null ? [] : [value2]
562
547
  };
@@ -577,8 +562,8 @@ function useForm(initialState, {
577
562
  ...getItemUXProps(String(parentKey), parentId, `${field2}.@${index2}`),
578
563
  id: compositeKey2,
579
564
  onBlur: () => {
580
- if (itemTouched[compositeKey2]) return;
581
- setItemTouched((prev) => ({ ...prev, [compositeKey2]: true }));
565
+ if (touched.get(compositeKey2)) return;
566
+ setTouched((prev) => new Map(prev).set(compositeKey2, true));
582
567
  },
583
568
  onSelectionChange: (v) => {
584
569
  if (parentIndex === void 0) return;
@@ -591,6 +576,8 @@ function useForm(initialState, {
591
576
  parentArr[parentIndex] = setNestedValue(item, field2, nestedArr2);
592
577
  return { ...prev, [parentKey]: parentArr };
593
578
  });
579
+ const fieldPath = `${field2}.@${index2}`;
580
+ validateItemInput(parentKey, parentId, fieldPath, fixedValue);
594
581
  },
595
582
  selectedKeys: value2 === null ? [] : [value2]
596
583
  };
@@ -640,15 +627,17 @@ function useForm(initialState, {
640
627
  ...getItemUXProps(String(arrayKey2), `@${index2}`, ""),
641
628
  id: compositeKey2,
642
629
  onBlur: () => {
643
- if (itemTouched[compositeKey2]) return;
644
- setItemTouched((prev) => ({ ...prev, [compositeKey2]: true }));
630
+ if (touched.get(compositeKey2)) return;
631
+ setTouched((prev) => new Map(prev).set(compositeKey2, true));
645
632
  },
646
633
  onSelectionChange: (v) => {
634
+ const fixedValue = typeof v === "string" || v === null ? v : String(v);
647
635
  setState((prev) => {
648
636
  const arr3 = [...prev[arrayKey2]];
649
- arr3[index2] = typeof v === "string" || v === null ? v : String(v);
637
+ arr3[index2] = fixedValue;
650
638
  return { ...prev, [arrayKey2]: arr3 };
651
639
  });
640
+ validateItemInput(arrayKey2, `@${index2}`, "", fixedValue);
652
641
  },
653
642
  selectedKey: value2
654
643
  };
@@ -669,19 +658,22 @@ function useForm(initialState, {
669
658
  ...getItemUXProps(String(parentKey), parentId, `${field2}.@${index2}`),
670
659
  id: compositeKey2,
671
660
  onBlur: () => {
672
- if (itemTouched[compositeKey2]) return;
673
- setItemTouched((prev) => ({ ...prev, [compositeKey2]: true }));
661
+ if (touched.get(compositeKey2)) return;
662
+ setTouched((prev) => new Map(prev).set(compositeKey2, true));
674
663
  },
675
664
  onSelectionChange: (v) => {
676
665
  if (parentIndex === void 0) return;
666
+ const fixedValue = typeof v === "string" || v === null ? v : String(v);
677
667
  setState((prev) => {
678
668
  const parentArr = [...prev[parentKey]];
679
669
  const item = { ...parentArr[parentIndex] };
680
670
  const nestedArr2 = [...getNestedValue(item, field2) || []];
681
- nestedArr2[index2] = typeof v === "string" || v === null ? v : String(v);
671
+ nestedArr2[index2] = fixedValue;
682
672
  parentArr[parentIndex] = setNestedValue(item, field2, nestedArr2);
683
673
  return { ...prev, [parentKey]: parentArr };
684
674
  });
675
+ const fieldPath = `${field2}.@${index2}`;
676
+ validateItemInput(parentKey, parentId, fieldPath, fixedValue);
685
677
  },
686
678
  selectedKey: value2
687
679
  };
@@ -732,8 +724,8 @@ function useForm(initialState, {
732
724
  });
733
725
  if (itemId !== void 0) {
734
726
  const prefix = `${String(arrayKey)}.${itemId}.`;
735
- setItemTouched((prev) => removeCompositeKeysByPrefix(prev, prefix));
736
- setItemErrors((prev) => removeCompositeKeysByPrefix(prev, prefix));
727
+ setTouched((prev) => removeCompositeKeysByPrefix(prev, prefix));
728
+ setErrors((prev) => removeCompositeKeysByPrefix(prev, prefix));
737
729
  }
738
730
  },
739
731
  removeById: (arrayKey, itemId) => {
@@ -743,8 +735,8 @@ function useForm(initialState, {
743
735
  arr.splice(index, 1);
744
736
  setState((prev) => ({ ...prev, [arrayKey]: arr }));
745
737
  const prefix = `${String(arrayKey)}.${itemId}.`;
746
- setItemTouched((prev) => removeCompositeKeysByPrefix(prev, prefix));
747
- setItemErrors((prev) => removeCompositeKeysByPrefix(prev, prefix));
738
+ setTouched((prev) => removeCompositeKeysByPrefix(prev, prefix));
739
+ setErrors((prev) => removeCompositeKeysByPrefix(prev, prefix));
748
740
  }
749
741
  },
750
742
  moveItem: (arrayKey, from, to) => {
@@ -784,35 +776,12 @@ function useForm(initialState, {
784
776
  },
785
777
  isDirty: JSON.stringify(state) !== JSON.stringify(initialState),
786
778
  hasInvalidValues: () => {
787
- setTouched((prev) => allToValue(prev, true));
788
- setItemTouched(
789
- (prev) => Object.keys(prev).reduce(
790
- (acc, key) => ({ ...acc, [key]: true }),
791
- {}
792
- )
793
- );
794
- setNestedTouched(
795
- (prev) => Object.keys(prev).reduce(
796
- (acc, key) => ({ ...acc, [key]: true }),
797
- {}
798
- )
799
- );
800
- const topLevelInvalid = JSON.stringify(errors2).includes(":true");
801
- const itemLevelInvalid = Object.values(itemErrors).some(
802
- (e) => e?.isInvalid
803
- );
804
- const nestedLevelInvalid = Object.values(nestedErrors).some(
805
- (e) => e?.isInvalid
806
- );
807
- return topLevelInvalid || itemLevelInvalid || nestedLevelInvalid;
779
+ const isInvalid = Array.from(errors2.values()).some((e) => e?.isInvalid);
780
+ return isInvalid;
808
781
  },
809
782
  resetForm: (preservedKeys) => {
810
- setTouched(initial.touched);
811
- setErrors(initial.errors);
812
- setItemTouched({});
813
- setItemErrors({});
814
- setNestedTouched({});
815
- setNestedErrors({});
783
+ setTouched(/* @__PURE__ */ new Map());
784
+ setErrors(/* @__PURE__ */ new Map());
816
785
  setState(
817
786
  (prev) => preservedKeys === void 0 ? initialState : preservedKeys.reduce(
818
787
  (acc, key) => ({
@@ -824,16 +793,13 @@ function useForm(initialState, {
824
793
  );
825
794
  },
826
795
  resetTouched: (preservedKeys) => {
827
- setItemTouched({});
828
- setNestedTouched({});
829
796
  setTouched(
830
- (prev) => preservedKeys === void 0 ? initialState : preservedKeys.reduce(
831
- (acc, key) => ({
832
- ...acc,
833
- [key]: prev[key]
834
- }),
835
- initial.touched
836
- )
797
+ (prev) => preservedKeys === void 0 ? /* @__PURE__ */ new Map() : preservedKeys.reduce((acc, key) => {
798
+ if (prev.has(String(key))) {
799
+ acc.set(String(key), prev.get(String(key)));
800
+ }
801
+ return acc;
802
+ }, /* @__PURE__ */ new Map())
837
803
  );
838
804
  }
839
805
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juantroconisf/lib",
3
- "version": "5.3.0",
3
+ "version": "6.0.0",
4
4
  "description": "A form validation library for HeroUI.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",