@juantroconisf/lib 5.2.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 +12 -5
- package/dist/index.d.ts +12 -5
- package/dist/index.js +121 -117
- package/dist/index.mjs +121 -117
- package/package.json +1 -1
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
|
|
85
|
-
type ErrorsType
|
|
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> {
|
|
@@ -130,6 +130,10 @@ interface OnMethods<O extends StateType> {
|
|
|
130
130
|
type ArrayKeys<O extends StateType> = {
|
|
131
131
|
[K in keyof O]: O[K] extends any[] ? K : never;
|
|
132
132
|
}[keyof O];
|
|
133
|
+
/** Keys whose values are arrays of objects (not primitives). */
|
|
134
|
+
type ObjectArrayKeys<O extends StateType> = {
|
|
135
|
+
[K in keyof O]: O[K] extends Record<string, any>[] ? K : never;
|
|
136
|
+
}[keyof O];
|
|
133
137
|
type ArrayElement<T> = T extends (infer E)[] ? E : never;
|
|
134
138
|
/** Resolves the type of the identifier field for an array element (defaults to "id"). */
|
|
135
139
|
type ItemIdType<O extends StateType, K extends keyof O> = "id" extends keyof ArrayElement<O[K]> ? ArrayElement<O[K]>["id"] : string | number;
|
|
@@ -170,12 +174,15 @@ interface HelpersFunc<O extends StateType> {
|
|
|
170
174
|
*/
|
|
171
175
|
interface UseFormResponse<O extends StateType> {
|
|
172
176
|
onBlur: BlurFunc<O>;
|
|
173
|
-
|
|
177
|
+
/** Updates an object array element's field by ID. */
|
|
178
|
+
onValueChange<K extends ObjectArrayKeys<O>, F extends keyof ArrayElement<O[K]> & string>(arrayKey: K, itemId: ItemIdType<O, K>, field: F, value: ArrayElement<O[K]>[F]): void;
|
|
179
|
+
/** Updates a scalar or nested object field. */
|
|
180
|
+
onValueChange<P extends AllPaths<O>>(id: P, value: NestedFieldValue<O, P & string>): void;
|
|
174
181
|
onSelectionChange: ValueChangeFunc<O, keyof O>;
|
|
175
182
|
state: O;
|
|
176
183
|
setState: React.Dispatch<React.SetStateAction<O>>;
|
|
177
|
-
touched: TouchedType
|
|
178
|
-
errors: ErrorsType
|
|
184
|
+
touched: TouchedType;
|
|
185
|
+
errors: ErrorsType;
|
|
179
186
|
/** Main object to bind form elements to the state. */
|
|
180
187
|
on: OnMethods<O>;
|
|
181
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
|
|
85
|
-
type ErrorsType
|
|
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> {
|
|
@@ -130,6 +130,10 @@ interface OnMethods<O extends StateType> {
|
|
|
130
130
|
type ArrayKeys<O extends StateType> = {
|
|
131
131
|
[K in keyof O]: O[K] extends any[] ? K : never;
|
|
132
132
|
}[keyof O];
|
|
133
|
+
/** Keys whose values are arrays of objects (not primitives). */
|
|
134
|
+
type ObjectArrayKeys<O extends StateType> = {
|
|
135
|
+
[K in keyof O]: O[K] extends Record<string, any>[] ? K : never;
|
|
136
|
+
}[keyof O];
|
|
133
137
|
type ArrayElement<T> = T extends (infer E)[] ? E : never;
|
|
134
138
|
/** Resolves the type of the identifier field for an array element (defaults to "id"). */
|
|
135
139
|
type ItemIdType<O extends StateType, K extends keyof O> = "id" extends keyof ArrayElement<O[K]> ? ArrayElement<O[K]>["id"] : string | number;
|
|
@@ -170,12 +174,15 @@ interface HelpersFunc<O extends StateType> {
|
|
|
170
174
|
*/
|
|
171
175
|
interface UseFormResponse<O extends StateType> {
|
|
172
176
|
onBlur: BlurFunc<O>;
|
|
173
|
-
|
|
177
|
+
/** Updates an object array element's field by ID. */
|
|
178
|
+
onValueChange<K extends ObjectArrayKeys<O>, F extends keyof ArrayElement<O[K]> & string>(arrayKey: K, itemId: ItemIdType<O, K>, field: F, value: ArrayElement<O[K]>[F]): void;
|
|
179
|
+
/** Updates a scalar or nested object field. */
|
|
180
|
+
onValueChange<P extends AllPaths<O>>(id: P, value: NestedFieldValue<O, P & string>): void;
|
|
174
181
|
onSelectionChange: ValueChangeFunc<O, keyof O>;
|
|
175
182
|
state: O;
|
|
176
183
|
setState: React.Dispatch<React.SetStateAction<O>>;
|
|
177
|
-
touched: TouchedType
|
|
178
|
-
errors: ErrorsType
|
|
184
|
+
touched: TouchedType;
|
|
185
|
+
errors: ErrorsType;
|
|
179
186
|
/** Main object to bind form elements to the state. */
|
|
180
187
|
on: OnMethods<O>;
|
|
181
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
|
|
87
|
-
if (
|
|
88
|
-
result
|
|
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
|
|
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,38 +252,71 @@ function useForm(initialState, {
|
|
|
266
252
|
},
|
|
267
253
|
[indexMap]
|
|
268
254
|
);
|
|
269
|
-
const validateInput = (
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
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
|
-
(
|
|
278
|
-
const inputError = errors2
|
|
279
|
-
const isTouched = touched
|
|
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
|
|
272
|
+
[errors2, touched]
|
|
286
273
|
);
|
|
287
274
|
const onBlur = (id) => {
|
|
288
|
-
validateInput(id, state[id]);
|
|
289
|
-
if (touched
|
|
290
|
-
setTouched(
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
275
|
+
validateInput(String(id), state[id], id);
|
|
276
|
+
if (touched.get(String(id))) return;
|
|
277
|
+
setTouched((prev) => new Map(prev).set(String(id), true));
|
|
278
|
+
}, onValueChange = ((...args) => {
|
|
279
|
+
if (args.length === 2) {
|
|
280
|
+
const [id, value] = args;
|
|
281
|
+
setState((prev) => handleNestedChange({ state: prev, id, value }));
|
|
282
|
+
validateInput(String(id), value, id);
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
if (args.length === 3) {
|
|
286
|
+
const [arrayKey, index, value] = args;
|
|
287
|
+
setState((prev) => {
|
|
288
|
+
const arr = [...prev[arrayKey]];
|
|
289
|
+
arr[index] = value;
|
|
290
|
+
return { ...prev, [arrayKey]: arr };
|
|
291
|
+
});
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
if (args.length === 4) {
|
|
295
|
+
const [arrayKey, itemId, field, value] = args;
|
|
296
|
+
const index = getIndex(String(arrayKey), itemId);
|
|
297
|
+
if (index === void 0) return;
|
|
298
|
+
setState(
|
|
299
|
+
(prev) => handleArrayItemChange({ state: prev, arrayKey, index, field, value })
|
|
300
|
+
);
|
|
301
|
+
validateItemInput(arrayKey, itemId, field, value);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
if (args.length === 5) {
|
|
305
|
+
const [parentKey, parentId, field, index, value] = args;
|
|
306
|
+
const parentIndex = getIndex(String(parentKey), parentId);
|
|
307
|
+
if (parentIndex === void 0) return;
|
|
308
|
+
setState((prev) => {
|
|
309
|
+
const parentArr = [...prev[parentKey]];
|
|
310
|
+
const item = { ...parentArr[parentIndex] };
|
|
311
|
+
const nestedArr = [...getNestedValue(item, field) || []];
|
|
312
|
+
nestedArr[index] = value;
|
|
313
|
+
const updatedItem = setNestedValue(item, field, nestedArr);
|
|
314
|
+
parentArr[parentIndex] = updatedItem;
|
|
315
|
+
return { ...prev, [parentKey]: parentArr };
|
|
316
|
+
});
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
}), onSelectionChange = (id, value) => {
|
|
301
320
|
const fixedValue = typeof value === "string" || value === null ? value : Array.from(value);
|
|
302
321
|
setState(
|
|
303
322
|
(prev) => handleNestedChange({
|
|
@@ -306,7 +325,7 @@ function useForm(initialState, {
|
|
|
306
325
|
value: fixedValue
|
|
307
326
|
})
|
|
308
327
|
);
|
|
309
|
-
validateInput(id, fixedValue);
|
|
328
|
+
validateInput(String(id), fixedValue, id);
|
|
310
329
|
};
|
|
311
330
|
const getItemCompositeKey = (arrayKey, itemId, field) => `${arrayKey}.${itemId}.${field}`;
|
|
312
331
|
const getPrimitiveCompositeKey = (arrayKey, index) => `${arrayKey}.@${index}`;
|
|
@@ -319,22 +338,24 @@ function useForm(initialState, {
|
|
|
319
338
|
const fieldRules = typeof arrayRuleDef === "function" ? arrayRuleDef(item, index) : arrayRuleDef;
|
|
320
339
|
const fieldMessages = arrayMessages?.[arrayKey]?.[field];
|
|
321
340
|
const compositeKey = getItemCompositeKey(String(arrayKey), itemId, field);
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
341
|
+
setErrors(
|
|
342
|
+
(prev) => new Map(prev).set(
|
|
343
|
+
compositeKey,
|
|
344
|
+
performValidations(value, fieldRules, fieldMessages)
|
|
345
|
+
)
|
|
346
|
+
);
|
|
326
347
|
};
|
|
327
348
|
const getItemUXProps = (0, import_react.useCallback)(
|
|
328
349
|
(arrayKey, itemId, field) => {
|
|
329
350
|
const compositeKey = getItemCompositeKey(arrayKey, itemId, field);
|
|
330
|
-
const inputError =
|
|
331
|
-
const isTouched =
|
|
351
|
+
const inputError = errors2.get(compositeKey);
|
|
352
|
+
const isTouched = touched.get(compositeKey);
|
|
332
353
|
return {
|
|
333
354
|
isInvalid: Boolean(isTouched && inputError?.isInvalid),
|
|
334
355
|
errorMessage: isTouched ? inputError?.errorMessage || "" : ""
|
|
335
356
|
};
|
|
336
357
|
},
|
|
337
|
-
[
|
|
358
|
+
[errors2, touched]
|
|
338
359
|
);
|
|
339
360
|
const onItemBlur = (arrayKey, itemId, field) => {
|
|
340
361
|
const index = getIndex(String(arrayKey), itemId);
|
|
@@ -343,8 +364,8 @@ function useForm(initialState, {
|
|
|
343
364
|
const value = getNestedValue(arr[index], field);
|
|
344
365
|
validateItemInput(arrayKey, itemId, field, value);
|
|
345
366
|
const compositeKey = getItemCompositeKey(String(arrayKey), itemId, field);
|
|
346
|
-
if (
|
|
347
|
-
|
|
367
|
+
if (touched.get(compositeKey)) return;
|
|
368
|
+
setTouched((prev) => new Map(prev).set(compositeKey, true));
|
|
348
369
|
};
|
|
349
370
|
const onItemValueChange = (arrayKey, itemId, field, value) => {
|
|
350
371
|
const index = getIndex(String(arrayKey), itemId);
|
|
@@ -374,16 +395,18 @@ function useForm(initialState, {
|
|
|
374
395
|
};
|
|
375
396
|
const validateNestedInput = (dotPath, value) => {
|
|
376
397
|
const topKey = dotPath.split(".")[0];
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
398
|
+
setErrors(
|
|
399
|
+
(prev) => new Map(prev).set(
|
|
400
|
+
dotPath,
|
|
401
|
+
performValidations(value, rules?.[topKey], messages?.[topKey])
|
|
402
|
+
)
|
|
403
|
+
);
|
|
381
404
|
};
|
|
382
405
|
const onNestedBlur = (dotPath) => {
|
|
383
406
|
const value = getNestedValue(state, dotPath);
|
|
384
407
|
validateNestedInput(dotPath, value);
|
|
385
|
-
if (
|
|
386
|
-
|
|
408
|
+
if (touched.get(dotPath)) return;
|
|
409
|
+
setTouched((prev) => new Map(prev).set(dotPath, true));
|
|
387
410
|
};
|
|
388
411
|
const onNestedValueChange = (dotPath, value) => {
|
|
389
412
|
setState((prev) => setNestedValue(prev, dotPath, value));
|
|
@@ -428,12 +451,8 @@ function useForm(initialState, {
|
|
|
428
451
|
...getItemUXProps(String(arrayKey2), `@${index2}`, ""),
|
|
429
452
|
id: compositeKey2,
|
|
430
453
|
onBlur: () => {
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
index2
|
|
434
|
-
);
|
|
435
|
-
if (itemTouched[compositeKey3]) return;
|
|
436
|
-
setItemTouched((prev) => ({ ...prev, [compositeKey3]: true }));
|
|
454
|
+
if (touched.get(compositeKey2)) return;
|
|
455
|
+
setTouched((prev) => new Map(prev).set(compositeKey2, true));
|
|
437
456
|
},
|
|
438
457
|
onValueChange: (v) => {
|
|
439
458
|
setState((prev) => {
|
|
@@ -441,6 +460,7 @@ function useForm(initialState, {
|
|
|
441
460
|
arr3[index2] = v;
|
|
442
461
|
return { ...prev, [arrayKey2]: arr3 };
|
|
443
462
|
});
|
|
463
|
+
validateItemInput(arrayKey2, `@${index2}`, "", v);
|
|
444
464
|
},
|
|
445
465
|
value: value2
|
|
446
466
|
};
|
|
@@ -461,8 +481,8 @@ function useForm(initialState, {
|
|
|
461
481
|
...getItemUXProps(String(parentKey), parentId, `${field2}.@${index2}`),
|
|
462
482
|
id: compositeKey2,
|
|
463
483
|
onBlur: () => {
|
|
464
|
-
if (
|
|
465
|
-
|
|
484
|
+
if (touched.get(compositeKey2)) return;
|
|
485
|
+
setTouched((prev) => new Map(prev).set(compositeKey2, true));
|
|
466
486
|
},
|
|
467
487
|
onValueChange: (v) => {
|
|
468
488
|
if (parentIndex === void 0) return;
|
|
@@ -474,6 +494,8 @@ function useForm(initialState, {
|
|
|
474
494
|
parentArr[parentIndex] = setNestedValue(item, field2, nestedArr2);
|
|
475
495
|
return { ...prev, [parentKey]: parentArr };
|
|
476
496
|
});
|
|
497
|
+
const fieldPath = `${field2}.@${index2}`;
|
|
498
|
+
validateItemInput(parentKey, parentId, fieldPath, v);
|
|
477
499
|
},
|
|
478
500
|
value: value2
|
|
479
501
|
};
|
|
@@ -528,8 +550,8 @@ function useForm(initialState, {
|
|
|
528
550
|
...getItemUXProps(String(arrayKey2), `@${index2}`, ""),
|
|
529
551
|
id: compositeKey2,
|
|
530
552
|
onBlur: () => {
|
|
531
|
-
if (
|
|
532
|
-
|
|
553
|
+
if (touched.get(compositeKey2)) return;
|
|
554
|
+
setTouched((prev) => new Map(prev).set(compositeKey2, true));
|
|
533
555
|
},
|
|
534
556
|
onSelectionChange: (v) => {
|
|
535
557
|
const fixedValue = typeof v === "string" || v === null ? v : Array.from(v)[0] || null;
|
|
@@ -538,6 +560,7 @@ function useForm(initialState, {
|
|
|
538
560
|
arr3[index2] = fixedValue;
|
|
539
561
|
return { ...prev, [arrayKey2]: arr3 };
|
|
540
562
|
});
|
|
563
|
+
validateItemInput(arrayKey2, `@${index2}`, "", fixedValue);
|
|
541
564
|
},
|
|
542
565
|
selectedKeys: value2 === null ? [] : [value2]
|
|
543
566
|
};
|
|
@@ -558,8 +581,8 @@ function useForm(initialState, {
|
|
|
558
581
|
...getItemUXProps(String(parentKey), parentId, `${field2}.@${index2}`),
|
|
559
582
|
id: compositeKey2,
|
|
560
583
|
onBlur: () => {
|
|
561
|
-
if (
|
|
562
|
-
|
|
584
|
+
if (touched.get(compositeKey2)) return;
|
|
585
|
+
setTouched((prev) => new Map(prev).set(compositeKey2, true));
|
|
563
586
|
},
|
|
564
587
|
onSelectionChange: (v) => {
|
|
565
588
|
if (parentIndex === void 0) return;
|
|
@@ -572,6 +595,8 @@ function useForm(initialState, {
|
|
|
572
595
|
parentArr[parentIndex] = setNestedValue(item, field2, nestedArr2);
|
|
573
596
|
return { ...prev, [parentKey]: parentArr };
|
|
574
597
|
});
|
|
598
|
+
const fieldPath = `${field2}.@${index2}`;
|
|
599
|
+
validateItemInput(parentKey, parentId, fieldPath, fixedValue);
|
|
575
600
|
},
|
|
576
601
|
selectedKeys: value2 === null ? [] : [value2]
|
|
577
602
|
};
|
|
@@ -621,15 +646,17 @@ function useForm(initialState, {
|
|
|
621
646
|
...getItemUXProps(String(arrayKey2), `@${index2}`, ""),
|
|
622
647
|
id: compositeKey2,
|
|
623
648
|
onBlur: () => {
|
|
624
|
-
if (
|
|
625
|
-
|
|
649
|
+
if (touched.get(compositeKey2)) return;
|
|
650
|
+
setTouched((prev) => new Map(prev).set(compositeKey2, true));
|
|
626
651
|
},
|
|
627
652
|
onSelectionChange: (v) => {
|
|
653
|
+
const fixedValue = typeof v === "string" || v === null ? v : String(v);
|
|
628
654
|
setState((prev) => {
|
|
629
655
|
const arr3 = [...prev[arrayKey2]];
|
|
630
|
-
arr3[index2] =
|
|
656
|
+
arr3[index2] = fixedValue;
|
|
631
657
|
return { ...prev, [arrayKey2]: arr3 };
|
|
632
658
|
});
|
|
659
|
+
validateItemInput(arrayKey2, `@${index2}`, "", fixedValue);
|
|
633
660
|
},
|
|
634
661
|
selectedKey: value2
|
|
635
662
|
};
|
|
@@ -650,19 +677,22 @@ function useForm(initialState, {
|
|
|
650
677
|
...getItemUXProps(String(parentKey), parentId, `${field2}.@${index2}`),
|
|
651
678
|
id: compositeKey2,
|
|
652
679
|
onBlur: () => {
|
|
653
|
-
if (
|
|
654
|
-
|
|
680
|
+
if (touched.get(compositeKey2)) return;
|
|
681
|
+
setTouched((prev) => new Map(prev).set(compositeKey2, true));
|
|
655
682
|
},
|
|
656
683
|
onSelectionChange: (v) => {
|
|
657
684
|
if (parentIndex === void 0) return;
|
|
685
|
+
const fixedValue = typeof v === "string" || v === null ? v : String(v);
|
|
658
686
|
setState((prev) => {
|
|
659
687
|
const parentArr = [...prev[parentKey]];
|
|
660
688
|
const item = { ...parentArr[parentIndex] };
|
|
661
689
|
const nestedArr2 = [...getNestedValue(item, field2) || []];
|
|
662
|
-
nestedArr2[index2] =
|
|
690
|
+
nestedArr2[index2] = fixedValue;
|
|
663
691
|
parentArr[parentIndex] = setNestedValue(item, field2, nestedArr2);
|
|
664
692
|
return { ...prev, [parentKey]: parentArr };
|
|
665
693
|
});
|
|
694
|
+
const fieldPath = `${field2}.@${index2}`;
|
|
695
|
+
validateItemInput(parentKey, parentId, fieldPath, fixedValue);
|
|
666
696
|
},
|
|
667
697
|
selectedKey: value2
|
|
668
698
|
};
|
|
@@ -713,8 +743,8 @@ function useForm(initialState, {
|
|
|
713
743
|
});
|
|
714
744
|
if (itemId !== void 0) {
|
|
715
745
|
const prefix = `${String(arrayKey)}.${itemId}.`;
|
|
716
|
-
|
|
717
|
-
|
|
746
|
+
setTouched((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
747
|
+
setErrors((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
718
748
|
}
|
|
719
749
|
},
|
|
720
750
|
removeById: (arrayKey, itemId) => {
|
|
@@ -724,8 +754,8 @@ function useForm(initialState, {
|
|
|
724
754
|
arr.splice(index, 1);
|
|
725
755
|
setState((prev) => ({ ...prev, [arrayKey]: arr }));
|
|
726
756
|
const prefix = `${String(arrayKey)}.${itemId}.`;
|
|
727
|
-
|
|
728
|
-
|
|
757
|
+
setTouched((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
758
|
+
setErrors((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
729
759
|
}
|
|
730
760
|
},
|
|
731
761
|
moveItem: (arrayKey, from, to) => {
|
|
@@ -765,35 +795,12 @@ function useForm(initialState, {
|
|
|
765
795
|
},
|
|
766
796
|
isDirty: JSON.stringify(state) !== JSON.stringify(initialState),
|
|
767
797
|
hasInvalidValues: () => {
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
(prev) => Object.keys(prev).reduce(
|
|
771
|
-
(acc, key) => ({ ...acc, [key]: true }),
|
|
772
|
-
{}
|
|
773
|
-
)
|
|
774
|
-
);
|
|
775
|
-
setNestedTouched(
|
|
776
|
-
(prev) => Object.keys(prev).reduce(
|
|
777
|
-
(acc, key) => ({ ...acc, [key]: true }),
|
|
778
|
-
{}
|
|
779
|
-
)
|
|
780
|
-
);
|
|
781
|
-
const topLevelInvalid = JSON.stringify(errors2).includes(":true");
|
|
782
|
-
const itemLevelInvalid = Object.values(itemErrors).some(
|
|
783
|
-
(e) => e?.isInvalid
|
|
784
|
-
);
|
|
785
|
-
const nestedLevelInvalid = Object.values(nestedErrors).some(
|
|
786
|
-
(e) => e?.isInvalid
|
|
787
|
-
);
|
|
788
|
-
return topLevelInvalid || itemLevelInvalid || nestedLevelInvalid;
|
|
798
|
+
const isInvalid = Array.from(errors2.values()).some((e) => e?.isInvalid);
|
|
799
|
+
return isInvalid;
|
|
789
800
|
},
|
|
790
801
|
resetForm: (preservedKeys) => {
|
|
791
|
-
setTouched(
|
|
792
|
-
setErrors(
|
|
793
|
-
setItemTouched({});
|
|
794
|
-
setItemErrors({});
|
|
795
|
-
setNestedTouched({});
|
|
796
|
-
setNestedErrors({});
|
|
802
|
+
setTouched(/* @__PURE__ */ new Map());
|
|
803
|
+
setErrors(/* @__PURE__ */ new Map());
|
|
797
804
|
setState(
|
|
798
805
|
(prev) => preservedKeys === void 0 ? initialState : preservedKeys.reduce(
|
|
799
806
|
(acc, key) => ({
|
|
@@ -805,16 +812,13 @@ function useForm(initialState, {
|
|
|
805
812
|
);
|
|
806
813
|
},
|
|
807
814
|
resetTouched: (preservedKeys) => {
|
|
808
|
-
setItemTouched({});
|
|
809
|
-
setNestedTouched({});
|
|
810
815
|
setTouched(
|
|
811
|
-
(prev) => preservedKeys === void 0 ?
|
|
812
|
-
(
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
)
|
|
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())
|
|
818
822
|
);
|
|
819
823
|
}
|
|
820
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
|
|
68
|
-
if (
|
|
69
|
-
result
|
|
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
|
|
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,38 +233,71 @@ function useForm(initialState, {
|
|
|
247
233
|
},
|
|
248
234
|
[indexMap]
|
|
249
235
|
);
|
|
250
|
-
const validateInput = (
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
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
|
-
(
|
|
259
|
-
const inputError = errors2
|
|
260
|
-
const isTouched = touched
|
|
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
|
|
253
|
+
[errors2, touched]
|
|
267
254
|
);
|
|
268
255
|
const onBlur = (id) => {
|
|
269
|
-
validateInput(id, state[id]);
|
|
270
|
-
if (touched
|
|
271
|
-
setTouched(
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
256
|
+
validateInput(String(id), state[id], id);
|
|
257
|
+
if (touched.get(String(id))) return;
|
|
258
|
+
setTouched((prev) => new Map(prev).set(String(id), true));
|
|
259
|
+
}, onValueChange = ((...args) => {
|
|
260
|
+
if (args.length === 2) {
|
|
261
|
+
const [id, value] = args;
|
|
262
|
+
setState((prev) => handleNestedChange({ state: prev, id, value }));
|
|
263
|
+
validateInput(String(id), value, id);
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
if (args.length === 3) {
|
|
267
|
+
const [arrayKey, index, value] = args;
|
|
268
|
+
setState((prev) => {
|
|
269
|
+
const arr = [...prev[arrayKey]];
|
|
270
|
+
arr[index] = value;
|
|
271
|
+
return { ...prev, [arrayKey]: arr };
|
|
272
|
+
});
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
if (args.length === 4) {
|
|
276
|
+
const [arrayKey, itemId, field, value] = args;
|
|
277
|
+
const index = getIndex(String(arrayKey), itemId);
|
|
278
|
+
if (index === void 0) return;
|
|
279
|
+
setState(
|
|
280
|
+
(prev) => handleArrayItemChange({ state: prev, arrayKey, index, field, value })
|
|
281
|
+
);
|
|
282
|
+
validateItemInput(arrayKey, itemId, field, value);
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
if (args.length === 5) {
|
|
286
|
+
const [parentKey, parentId, field, index, value] = args;
|
|
287
|
+
const parentIndex = getIndex(String(parentKey), parentId);
|
|
288
|
+
if (parentIndex === void 0) return;
|
|
289
|
+
setState((prev) => {
|
|
290
|
+
const parentArr = [...prev[parentKey]];
|
|
291
|
+
const item = { ...parentArr[parentIndex] };
|
|
292
|
+
const nestedArr = [...getNestedValue(item, field) || []];
|
|
293
|
+
nestedArr[index] = value;
|
|
294
|
+
const updatedItem = setNestedValue(item, field, nestedArr);
|
|
295
|
+
parentArr[parentIndex] = updatedItem;
|
|
296
|
+
return { ...prev, [parentKey]: parentArr };
|
|
297
|
+
});
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
}), onSelectionChange = (id, value) => {
|
|
282
301
|
const fixedValue = typeof value === "string" || value === null ? value : Array.from(value);
|
|
283
302
|
setState(
|
|
284
303
|
(prev) => handleNestedChange({
|
|
@@ -287,7 +306,7 @@ function useForm(initialState, {
|
|
|
287
306
|
value: fixedValue
|
|
288
307
|
})
|
|
289
308
|
);
|
|
290
|
-
validateInput(id, fixedValue);
|
|
309
|
+
validateInput(String(id), fixedValue, id);
|
|
291
310
|
};
|
|
292
311
|
const getItemCompositeKey = (arrayKey, itemId, field) => `${arrayKey}.${itemId}.${field}`;
|
|
293
312
|
const getPrimitiveCompositeKey = (arrayKey, index) => `${arrayKey}.@${index}`;
|
|
@@ -300,22 +319,24 @@ function useForm(initialState, {
|
|
|
300
319
|
const fieldRules = typeof arrayRuleDef === "function" ? arrayRuleDef(item, index) : arrayRuleDef;
|
|
301
320
|
const fieldMessages = arrayMessages?.[arrayKey]?.[field];
|
|
302
321
|
const compositeKey = getItemCompositeKey(String(arrayKey), itemId, field);
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
322
|
+
setErrors(
|
|
323
|
+
(prev) => new Map(prev).set(
|
|
324
|
+
compositeKey,
|
|
325
|
+
performValidations(value, fieldRules, fieldMessages)
|
|
326
|
+
)
|
|
327
|
+
);
|
|
307
328
|
};
|
|
308
329
|
const getItemUXProps = useCallback(
|
|
309
330
|
(arrayKey, itemId, field) => {
|
|
310
331
|
const compositeKey = getItemCompositeKey(arrayKey, itemId, field);
|
|
311
|
-
const inputError =
|
|
312
|
-
const isTouched =
|
|
332
|
+
const inputError = errors2.get(compositeKey);
|
|
333
|
+
const isTouched = touched.get(compositeKey);
|
|
313
334
|
return {
|
|
314
335
|
isInvalid: Boolean(isTouched && inputError?.isInvalid),
|
|
315
336
|
errorMessage: isTouched ? inputError?.errorMessage || "" : ""
|
|
316
337
|
};
|
|
317
338
|
},
|
|
318
|
-
[
|
|
339
|
+
[errors2, touched]
|
|
319
340
|
);
|
|
320
341
|
const onItemBlur = (arrayKey, itemId, field) => {
|
|
321
342
|
const index = getIndex(String(arrayKey), itemId);
|
|
@@ -324,8 +345,8 @@ function useForm(initialState, {
|
|
|
324
345
|
const value = getNestedValue(arr[index], field);
|
|
325
346
|
validateItemInput(arrayKey, itemId, field, value);
|
|
326
347
|
const compositeKey = getItemCompositeKey(String(arrayKey), itemId, field);
|
|
327
|
-
if (
|
|
328
|
-
|
|
348
|
+
if (touched.get(compositeKey)) return;
|
|
349
|
+
setTouched((prev) => new Map(prev).set(compositeKey, true));
|
|
329
350
|
};
|
|
330
351
|
const onItemValueChange = (arrayKey, itemId, field, value) => {
|
|
331
352
|
const index = getIndex(String(arrayKey), itemId);
|
|
@@ -355,16 +376,18 @@ function useForm(initialState, {
|
|
|
355
376
|
};
|
|
356
377
|
const validateNestedInput = (dotPath, value) => {
|
|
357
378
|
const topKey = dotPath.split(".")[0];
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
379
|
+
setErrors(
|
|
380
|
+
(prev) => new Map(prev).set(
|
|
381
|
+
dotPath,
|
|
382
|
+
performValidations(value, rules?.[topKey], messages?.[topKey])
|
|
383
|
+
)
|
|
384
|
+
);
|
|
362
385
|
};
|
|
363
386
|
const onNestedBlur = (dotPath) => {
|
|
364
387
|
const value = getNestedValue(state, dotPath);
|
|
365
388
|
validateNestedInput(dotPath, value);
|
|
366
|
-
if (
|
|
367
|
-
|
|
389
|
+
if (touched.get(dotPath)) return;
|
|
390
|
+
setTouched((prev) => new Map(prev).set(dotPath, true));
|
|
368
391
|
};
|
|
369
392
|
const onNestedValueChange = (dotPath, value) => {
|
|
370
393
|
setState((prev) => setNestedValue(prev, dotPath, value));
|
|
@@ -409,12 +432,8 @@ function useForm(initialState, {
|
|
|
409
432
|
...getItemUXProps(String(arrayKey2), `@${index2}`, ""),
|
|
410
433
|
id: compositeKey2,
|
|
411
434
|
onBlur: () => {
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
index2
|
|
415
|
-
);
|
|
416
|
-
if (itemTouched[compositeKey3]) return;
|
|
417
|
-
setItemTouched((prev) => ({ ...prev, [compositeKey3]: true }));
|
|
435
|
+
if (touched.get(compositeKey2)) return;
|
|
436
|
+
setTouched((prev) => new Map(prev).set(compositeKey2, true));
|
|
418
437
|
},
|
|
419
438
|
onValueChange: (v) => {
|
|
420
439
|
setState((prev) => {
|
|
@@ -422,6 +441,7 @@ function useForm(initialState, {
|
|
|
422
441
|
arr3[index2] = v;
|
|
423
442
|
return { ...prev, [arrayKey2]: arr3 };
|
|
424
443
|
});
|
|
444
|
+
validateItemInput(arrayKey2, `@${index2}`, "", v);
|
|
425
445
|
},
|
|
426
446
|
value: value2
|
|
427
447
|
};
|
|
@@ -442,8 +462,8 @@ function useForm(initialState, {
|
|
|
442
462
|
...getItemUXProps(String(parentKey), parentId, `${field2}.@${index2}`),
|
|
443
463
|
id: compositeKey2,
|
|
444
464
|
onBlur: () => {
|
|
445
|
-
if (
|
|
446
|
-
|
|
465
|
+
if (touched.get(compositeKey2)) return;
|
|
466
|
+
setTouched((prev) => new Map(prev).set(compositeKey2, true));
|
|
447
467
|
},
|
|
448
468
|
onValueChange: (v) => {
|
|
449
469
|
if (parentIndex === void 0) return;
|
|
@@ -455,6 +475,8 @@ function useForm(initialState, {
|
|
|
455
475
|
parentArr[parentIndex] = setNestedValue(item, field2, nestedArr2);
|
|
456
476
|
return { ...prev, [parentKey]: parentArr };
|
|
457
477
|
});
|
|
478
|
+
const fieldPath = `${field2}.@${index2}`;
|
|
479
|
+
validateItemInput(parentKey, parentId, fieldPath, v);
|
|
458
480
|
},
|
|
459
481
|
value: value2
|
|
460
482
|
};
|
|
@@ -509,8 +531,8 @@ function useForm(initialState, {
|
|
|
509
531
|
...getItemUXProps(String(arrayKey2), `@${index2}`, ""),
|
|
510
532
|
id: compositeKey2,
|
|
511
533
|
onBlur: () => {
|
|
512
|
-
if (
|
|
513
|
-
|
|
534
|
+
if (touched.get(compositeKey2)) return;
|
|
535
|
+
setTouched((prev) => new Map(prev).set(compositeKey2, true));
|
|
514
536
|
},
|
|
515
537
|
onSelectionChange: (v) => {
|
|
516
538
|
const fixedValue = typeof v === "string" || v === null ? v : Array.from(v)[0] || null;
|
|
@@ -519,6 +541,7 @@ function useForm(initialState, {
|
|
|
519
541
|
arr3[index2] = fixedValue;
|
|
520
542
|
return { ...prev, [arrayKey2]: arr3 };
|
|
521
543
|
});
|
|
544
|
+
validateItemInput(arrayKey2, `@${index2}`, "", fixedValue);
|
|
522
545
|
},
|
|
523
546
|
selectedKeys: value2 === null ? [] : [value2]
|
|
524
547
|
};
|
|
@@ -539,8 +562,8 @@ function useForm(initialState, {
|
|
|
539
562
|
...getItemUXProps(String(parentKey), parentId, `${field2}.@${index2}`),
|
|
540
563
|
id: compositeKey2,
|
|
541
564
|
onBlur: () => {
|
|
542
|
-
if (
|
|
543
|
-
|
|
565
|
+
if (touched.get(compositeKey2)) return;
|
|
566
|
+
setTouched((prev) => new Map(prev).set(compositeKey2, true));
|
|
544
567
|
},
|
|
545
568
|
onSelectionChange: (v) => {
|
|
546
569
|
if (parentIndex === void 0) return;
|
|
@@ -553,6 +576,8 @@ function useForm(initialState, {
|
|
|
553
576
|
parentArr[parentIndex] = setNestedValue(item, field2, nestedArr2);
|
|
554
577
|
return { ...prev, [parentKey]: parentArr };
|
|
555
578
|
});
|
|
579
|
+
const fieldPath = `${field2}.@${index2}`;
|
|
580
|
+
validateItemInput(parentKey, parentId, fieldPath, fixedValue);
|
|
556
581
|
},
|
|
557
582
|
selectedKeys: value2 === null ? [] : [value2]
|
|
558
583
|
};
|
|
@@ -602,15 +627,17 @@ function useForm(initialState, {
|
|
|
602
627
|
...getItemUXProps(String(arrayKey2), `@${index2}`, ""),
|
|
603
628
|
id: compositeKey2,
|
|
604
629
|
onBlur: () => {
|
|
605
|
-
if (
|
|
606
|
-
|
|
630
|
+
if (touched.get(compositeKey2)) return;
|
|
631
|
+
setTouched((prev) => new Map(prev).set(compositeKey2, true));
|
|
607
632
|
},
|
|
608
633
|
onSelectionChange: (v) => {
|
|
634
|
+
const fixedValue = typeof v === "string" || v === null ? v : String(v);
|
|
609
635
|
setState((prev) => {
|
|
610
636
|
const arr3 = [...prev[arrayKey2]];
|
|
611
|
-
arr3[index2] =
|
|
637
|
+
arr3[index2] = fixedValue;
|
|
612
638
|
return { ...prev, [arrayKey2]: arr3 };
|
|
613
639
|
});
|
|
640
|
+
validateItemInput(arrayKey2, `@${index2}`, "", fixedValue);
|
|
614
641
|
},
|
|
615
642
|
selectedKey: value2
|
|
616
643
|
};
|
|
@@ -631,19 +658,22 @@ function useForm(initialState, {
|
|
|
631
658
|
...getItemUXProps(String(parentKey), parentId, `${field2}.@${index2}`),
|
|
632
659
|
id: compositeKey2,
|
|
633
660
|
onBlur: () => {
|
|
634
|
-
if (
|
|
635
|
-
|
|
661
|
+
if (touched.get(compositeKey2)) return;
|
|
662
|
+
setTouched((prev) => new Map(prev).set(compositeKey2, true));
|
|
636
663
|
},
|
|
637
664
|
onSelectionChange: (v) => {
|
|
638
665
|
if (parentIndex === void 0) return;
|
|
666
|
+
const fixedValue = typeof v === "string" || v === null ? v : String(v);
|
|
639
667
|
setState((prev) => {
|
|
640
668
|
const parentArr = [...prev[parentKey]];
|
|
641
669
|
const item = { ...parentArr[parentIndex] };
|
|
642
670
|
const nestedArr2 = [...getNestedValue(item, field2) || []];
|
|
643
|
-
nestedArr2[index2] =
|
|
671
|
+
nestedArr2[index2] = fixedValue;
|
|
644
672
|
parentArr[parentIndex] = setNestedValue(item, field2, nestedArr2);
|
|
645
673
|
return { ...prev, [parentKey]: parentArr };
|
|
646
674
|
});
|
|
675
|
+
const fieldPath = `${field2}.@${index2}`;
|
|
676
|
+
validateItemInput(parentKey, parentId, fieldPath, fixedValue);
|
|
647
677
|
},
|
|
648
678
|
selectedKey: value2
|
|
649
679
|
};
|
|
@@ -694,8 +724,8 @@ function useForm(initialState, {
|
|
|
694
724
|
});
|
|
695
725
|
if (itemId !== void 0) {
|
|
696
726
|
const prefix = `${String(arrayKey)}.${itemId}.`;
|
|
697
|
-
|
|
698
|
-
|
|
727
|
+
setTouched((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
728
|
+
setErrors((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
699
729
|
}
|
|
700
730
|
},
|
|
701
731
|
removeById: (arrayKey, itemId) => {
|
|
@@ -705,8 +735,8 @@ function useForm(initialState, {
|
|
|
705
735
|
arr.splice(index, 1);
|
|
706
736
|
setState((prev) => ({ ...prev, [arrayKey]: arr }));
|
|
707
737
|
const prefix = `${String(arrayKey)}.${itemId}.`;
|
|
708
|
-
|
|
709
|
-
|
|
738
|
+
setTouched((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
739
|
+
setErrors((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
710
740
|
}
|
|
711
741
|
},
|
|
712
742
|
moveItem: (arrayKey, from, to) => {
|
|
@@ -746,35 +776,12 @@ function useForm(initialState, {
|
|
|
746
776
|
},
|
|
747
777
|
isDirty: JSON.stringify(state) !== JSON.stringify(initialState),
|
|
748
778
|
hasInvalidValues: () => {
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
(prev) => Object.keys(prev).reduce(
|
|
752
|
-
(acc, key) => ({ ...acc, [key]: true }),
|
|
753
|
-
{}
|
|
754
|
-
)
|
|
755
|
-
);
|
|
756
|
-
setNestedTouched(
|
|
757
|
-
(prev) => Object.keys(prev).reduce(
|
|
758
|
-
(acc, key) => ({ ...acc, [key]: true }),
|
|
759
|
-
{}
|
|
760
|
-
)
|
|
761
|
-
);
|
|
762
|
-
const topLevelInvalid = JSON.stringify(errors2).includes(":true");
|
|
763
|
-
const itemLevelInvalid = Object.values(itemErrors).some(
|
|
764
|
-
(e) => e?.isInvalid
|
|
765
|
-
);
|
|
766
|
-
const nestedLevelInvalid = Object.values(nestedErrors).some(
|
|
767
|
-
(e) => e?.isInvalid
|
|
768
|
-
);
|
|
769
|
-
return topLevelInvalid || itemLevelInvalid || nestedLevelInvalid;
|
|
779
|
+
const isInvalid = Array.from(errors2.values()).some((e) => e?.isInvalid);
|
|
780
|
+
return isInvalid;
|
|
770
781
|
},
|
|
771
782
|
resetForm: (preservedKeys) => {
|
|
772
|
-
setTouched(
|
|
773
|
-
setErrors(
|
|
774
|
-
setItemTouched({});
|
|
775
|
-
setItemErrors({});
|
|
776
|
-
setNestedTouched({});
|
|
777
|
-
setNestedErrors({});
|
|
783
|
+
setTouched(/* @__PURE__ */ new Map());
|
|
784
|
+
setErrors(/* @__PURE__ */ new Map());
|
|
778
785
|
setState(
|
|
779
786
|
(prev) => preservedKeys === void 0 ? initialState : preservedKeys.reduce(
|
|
780
787
|
(acc, key) => ({
|
|
@@ -786,16 +793,13 @@ function useForm(initialState, {
|
|
|
786
793
|
);
|
|
787
794
|
},
|
|
788
795
|
resetTouched: (preservedKeys) => {
|
|
789
|
-
setItemTouched({});
|
|
790
|
-
setNestedTouched({});
|
|
791
796
|
setTouched(
|
|
792
|
-
(prev) => preservedKeys === void 0 ?
|
|
793
|
-
(
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
)
|
|
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())
|
|
799
803
|
);
|
|
800
804
|
}
|
|
801
805
|
};
|