@juantroconisf/lib 4.2.0 → 5.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/README.md +99 -2
- package/dist/index.d.mts +122 -17
- package/dist/index.d.ts +122 -17
- package/dist/index.js +421 -49
- package/dist/index.mjs +422 -50
- package/package.json +37 -36
package/dist/index.mjs
CHANGED
|
@@ -16,7 +16,7 @@ var NextUIError = class {
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
// src/hooks/useForm.tsx
|
|
19
|
-
import { useState, useCallback } from "react";
|
|
19
|
+
import { useState, useCallback, useMemo } from "react";
|
|
20
20
|
|
|
21
21
|
// src/utils/utils.ts
|
|
22
22
|
function handleNestedChange({
|
|
@@ -36,10 +36,59 @@ function handleNestedChange({
|
|
|
36
36
|
current[propertyDepth[propertyDepth.length - 1]] = value;
|
|
37
37
|
return { ...newValues };
|
|
38
38
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
function handleArrayItemChange({
|
|
40
|
+
state,
|
|
41
|
+
arrayKey,
|
|
42
|
+
index,
|
|
43
|
+
field,
|
|
44
|
+
value
|
|
45
|
+
}) {
|
|
46
|
+
const arr = [...state[arrayKey]];
|
|
47
|
+
const item = { ...arr[index] };
|
|
48
|
+
const fieldDepth = field.split(".");
|
|
49
|
+
if (fieldDepth.length === 1) {
|
|
50
|
+
item[field] = value;
|
|
51
|
+
} else {
|
|
52
|
+
let current = item;
|
|
53
|
+
for (let i = 0; i < fieldDepth.length - 1; i++) {
|
|
54
|
+
current[fieldDepth[i]] = { ...current[fieldDepth[i]] };
|
|
55
|
+
current = current[fieldDepth[i]];
|
|
56
|
+
}
|
|
57
|
+
current[fieldDepth[fieldDepth.length - 1]] = value;
|
|
58
|
+
}
|
|
59
|
+
arr[index] = item;
|
|
60
|
+
return { ...state, [arrayKey]: arr };
|
|
61
|
+
}
|
|
62
|
+
function getNestedValue(obj, path) {
|
|
63
|
+
return path.split(".").reduce((acc, key) => acc?.[key], obj);
|
|
64
|
+
}
|
|
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;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
function setNestedValue(state, dotPath, value) {
|
|
75
|
+
const keys = dotPath.split(".");
|
|
76
|
+
const copy = { ...state };
|
|
77
|
+
let current = copy;
|
|
78
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
79
|
+
current[keys[i]] = { ...current[keys[i]] };
|
|
80
|
+
current = current[keys[i]];
|
|
81
|
+
}
|
|
82
|
+
current[keys[keys.length - 1]] = value;
|
|
83
|
+
return copy;
|
|
84
|
+
}
|
|
85
|
+
var allToValue = (obj, value) => Object.keys(obj).reduce(
|
|
86
|
+
(acc, key) => {
|
|
87
|
+
acc[key] = value;
|
|
88
|
+
return acc;
|
|
89
|
+
},
|
|
90
|
+
{}
|
|
91
|
+
);
|
|
43
92
|
var regex = {
|
|
44
93
|
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,}))$/,
|
|
45
94
|
password: /^(?!.*\s)(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[~`!@#$%^&*()--+={}[\]|:;"'<>,.?/_₹]).{8,24}$/
|
|
@@ -158,7 +207,14 @@ function useValidate() {
|
|
|
158
207
|
}
|
|
159
208
|
|
|
160
209
|
// src/hooks/useForm.tsx
|
|
161
|
-
function useForm(initialState, {
|
|
210
|
+
function useForm(initialState, {
|
|
211
|
+
rules,
|
|
212
|
+
messages,
|
|
213
|
+
arrayRules,
|
|
214
|
+
arrayMessages,
|
|
215
|
+
arrayIdentifiers,
|
|
216
|
+
config
|
|
217
|
+
} = {}) {
|
|
162
218
|
const initial = {
|
|
163
219
|
touched: allToValue(initialState, false),
|
|
164
220
|
errors: allToValue(initialState, {
|
|
@@ -166,27 +222,50 @@ function useForm(initialState, { validations, errorMessages } = {}) {
|
|
|
166
222
|
errorMessage: ""
|
|
167
223
|
})
|
|
168
224
|
};
|
|
169
|
-
const [state, setState] = useState(initialState), [touched, setTouched] = useState(initial.touched), [errors2, setErrors] = useState(initial.errors), { performValidations } = useValidate();
|
|
225
|
+
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();
|
|
226
|
+
const indexMap = useMemo(() => {
|
|
227
|
+
const map2 = /* @__PURE__ */ new Map();
|
|
228
|
+
for (const key in state) {
|
|
229
|
+
if (Array.isArray(state[key])) {
|
|
230
|
+
const itemMap = /* @__PURE__ */ new Map();
|
|
231
|
+
const idKey = arrayIdentifiers?.[key] || "id";
|
|
232
|
+
state[key].forEach((item, index) => {
|
|
233
|
+
if (item && typeof item === "object") {
|
|
234
|
+
const idValue = item[idKey];
|
|
235
|
+
if (idValue !== void 0) {
|
|
236
|
+
itemMap.set(idValue, index);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
map2.set(key, itemMap);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return map2;
|
|
244
|
+
}, [state, arrayIdentifiers]);
|
|
245
|
+
const getIndex = useCallback((arrayKey, itemId) => {
|
|
246
|
+
return indexMap.get(arrayKey)?.get(itemId);
|
|
247
|
+
}, [indexMap]);
|
|
170
248
|
const validateInput = (id, value) => setErrors(
|
|
171
249
|
(prev) => handleNestedChange({
|
|
172
250
|
state: prev,
|
|
173
251
|
id,
|
|
174
252
|
value: performValidations(
|
|
175
253
|
value,
|
|
176
|
-
|
|
177
|
-
|
|
254
|
+
rules?.[id],
|
|
255
|
+
messages?.[id]
|
|
178
256
|
)
|
|
179
257
|
})
|
|
180
258
|
);
|
|
181
259
|
const getUXProps = useCallback(
|
|
182
260
|
(id) => {
|
|
183
|
-
const inputError = errors2[id]
|
|
261
|
+
const inputError = errors2[id] || nestedErrors[id];
|
|
262
|
+
const isTouched = touched[id] || nestedTouched[id];
|
|
184
263
|
return {
|
|
185
|
-
isInvalid: isTouched && inputError
|
|
186
|
-
errorMessage: isTouched ? inputError
|
|
264
|
+
isInvalid: Boolean(isTouched && inputError?.isInvalid),
|
|
265
|
+
errorMessage: isTouched ? inputError?.errorMessage || "" : ""
|
|
187
266
|
};
|
|
188
267
|
},
|
|
189
|
-
[errors2, touched]
|
|
268
|
+
[errors2, touched, nestedErrors, nestedTouched]
|
|
190
269
|
);
|
|
191
270
|
const onBlur = (id) => {
|
|
192
271
|
validateInput(id, state[id]);
|
|
@@ -212,6 +291,214 @@ function useForm(initialState, { validations, errorMessages } = {}) {
|
|
|
212
291
|
);
|
|
213
292
|
validateInput(id, fixedValue);
|
|
214
293
|
};
|
|
294
|
+
const getItemCompositeKey = (arrayKey, itemId, field) => `${arrayKey}.${itemId}.${field}`;
|
|
295
|
+
const validateItemInput = (arrayKey, itemId, field, value) => {
|
|
296
|
+
const index = getIndex(String(arrayKey), itemId);
|
|
297
|
+
if (index === void 0) return;
|
|
298
|
+
const arrayRuleDef = arrayRules?.[arrayKey]?.[field];
|
|
299
|
+
const item = state[arrayKey][index];
|
|
300
|
+
const fieldRules = typeof arrayRuleDef === "function" ? arrayRuleDef(item, index) : arrayRuleDef;
|
|
301
|
+
const fieldMessages = arrayMessages?.[arrayKey]?.[field];
|
|
302
|
+
const compositeKey = getItemCompositeKey(String(arrayKey), itemId, field);
|
|
303
|
+
setItemErrors((prev) => ({
|
|
304
|
+
...prev,
|
|
305
|
+
[compositeKey]: performValidations(
|
|
306
|
+
value,
|
|
307
|
+
fieldRules,
|
|
308
|
+
fieldMessages
|
|
309
|
+
)
|
|
310
|
+
}));
|
|
311
|
+
};
|
|
312
|
+
const getItemUXProps = useCallback(
|
|
313
|
+
(arrayKey, itemId, field) => {
|
|
314
|
+
const compositeKey = getItemCompositeKey(arrayKey, itemId, field);
|
|
315
|
+
const inputError = itemErrors[compositeKey];
|
|
316
|
+
const isTouched = itemTouched[compositeKey];
|
|
317
|
+
return {
|
|
318
|
+
isInvalid: Boolean(isTouched && inputError?.isInvalid),
|
|
319
|
+
errorMessage: isTouched ? inputError?.errorMessage || "" : ""
|
|
320
|
+
};
|
|
321
|
+
},
|
|
322
|
+
[itemErrors, itemTouched]
|
|
323
|
+
);
|
|
324
|
+
const onItemBlur = (arrayKey, itemId, field) => {
|
|
325
|
+
const index = getIndex(String(arrayKey), itemId);
|
|
326
|
+
if (index === void 0) return;
|
|
327
|
+
const arr = state[arrayKey];
|
|
328
|
+
const value = getNestedValue(arr[index], field);
|
|
329
|
+
validateItemInput(arrayKey, itemId, field, value);
|
|
330
|
+
const compositeKey = getItemCompositeKey(String(arrayKey), itemId, field);
|
|
331
|
+
if (itemTouched[compositeKey]) return;
|
|
332
|
+
setItemTouched((prev) => ({ ...prev, [compositeKey]: true }));
|
|
333
|
+
};
|
|
334
|
+
const onItemValueChange = (arrayKey, itemId, field, value) => {
|
|
335
|
+
const index = getIndex(String(arrayKey), itemId);
|
|
336
|
+
if (index === void 0) return;
|
|
337
|
+
setState(
|
|
338
|
+
(prev) => handleArrayItemChange({ state: prev, arrayKey, index, field, value })
|
|
339
|
+
);
|
|
340
|
+
validateItemInput(arrayKey, itemId, field, value);
|
|
341
|
+
};
|
|
342
|
+
const onItemSelectionChange = (arrayKey, itemId, field, value) => {
|
|
343
|
+
const index = getIndex(String(arrayKey), itemId);
|
|
344
|
+
if (index === void 0) return;
|
|
345
|
+
const arr = state[arrayKey];
|
|
346
|
+
const currentVal = getNestedValue(arr[index], field);
|
|
347
|
+
const isString = typeof currentVal === "string" || currentVal === null;
|
|
348
|
+
const fixedValue = typeof value === "string" || value === null ? value : isString ? Array.from(value)[0] || null : Array.from(value);
|
|
349
|
+
setState(
|
|
350
|
+
(prev) => handleArrayItemChange({
|
|
351
|
+
state: prev,
|
|
352
|
+
arrayKey,
|
|
353
|
+
index,
|
|
354
|
+
field,
|
|
355
|
+
value: fixedValue
|
|
356
|
+
})
|
|
357
|
+
);
|
|
358
|
+
validateItemInput(arrayKey, itemId, field, fixedValue);
|
|
359
|
+
};
|
|
360
|
+
const validateNestedInput = (dotPath, value) => {
|
|
361
|
+
const topKey = dotPath.split(".")[0];
|
|
362
|
+
setNestedErrors((prev) => ({
|
|
363
|
+
...prev,
|
|
364
|
+
[dotPath]: performValidations(
|
|
365
|
+
value,
|
|
366
|
+
rules?.[topKey],
|
|
367
|
+
messages?.[topKey]
|
|
368
|
+
)
|
|
369
|
+
}));
|
|
370
|
+
};
|
|
371
|
+
const onNestedBlur = (dotPath) => {
|
|
372
|
+
const value = getNestedValue(state, dotPath);
|
|
373
|
+
validateNestedInput(dotPath, value);
|
|
374
|
+
if (nestedTouched[dotPath]) return;
|
|
375
|
+
setNestedTouched((prev) => ({ ...prev, [dotPath]: true }));
|
|
376
|
+
};
|
|
377
|
+
const onNestedValueChange = (dotPath, value) => {
|
|
378
|
+
setState((prev) => setNestedValue(prev, dotPath, value));
|
|
379
|
+
validateNestedInput(dotPath, value);
|
|
380
|
+
};
|
|
381
|
+
const onNestedSelectionChange = (dotPath, value) => {
|
|
382
|
+
const currentVal = getNestedValue(state, dotPath);
|
|
383
|
+
const isString = typeof currentVal === "string" || currentVal === null;
|
|
384
|
+
const fixedValue = typeof value === "string" || value === null ? value : isString ? Array.from(value)[0] || null : Array.from(value);
|
|
385
|
+
setState((prev) => setNestedValue(prev, dotPath, fixedValue));
|
|
386
|
+
validateNestedInput(dotPath, fixedValue);
|
|
387
|
+
};
|
|
388
|
+
const on2 = {
|
|
389
|
+
input: (...args) => {
|
|
390
|
+
if (args.length === 1) {
|
|
391
|
+
const id = args[0];
|
|
392
|
+
const key = String(id);
|
|
393
|
+
const isTopLevel = key in state;
|
|
394
|
+
if (isTopLevel) {
|
|
395
|
+
return {
|
|
396
|
+
...getUXProps(key),
|
|
397
|
+
id: key,
|
|
398
|
+
onBlur: () => onBlur(id),
|
|
399
|
+
onValueChange: (v) => onValueChange(id, v),
|
|
400
|
+
value: state[id]
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
return {
|
|
404
|
+
...getUXProps(key),
|
|
405
|
+
id: key,
|
|
406
|
+
onBlur: () => onNestedBlur(key),
|
|
407
|
+
onValueChange: (v) => onNestedValueChange(key, v),
|
|
408
|
+
value: getNestedValue(state, key)
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
const [arrayKey, itemId, field] = args;
|
|
412
|
+
const index = getIndex(String(arrayKey), itemId);
|
|
413
|
+
const arr = state[arrayKey];
|
|
414
|
+
const value = index !== void 0 ? getNestedValue(arr[index], field) : void 0;
|
|
415
|
+
const compositeKey = getItemCompositeKey(String(arrayKey), itemId, field);
|
|
416
|
+
return {
|
|
417
|
+
...getItemUXProps(String(arrayKey), itemId, field),
|
|
418
|
+
id: compositeKey,
|
|
419
|
+
onBlur: () => onItemBlur(arrayKey, itemId, field),
|
|
420
|
+
onValueChange: (v) => onItemValueChange(arrayKey, itemId, field, v),
|
|
421
|
+
value
|
|
422
|
+
};
|
|
423
|
+
},
|
|
424
|
+
select: (...args) => {
|
|
425
|
+
if (args.length === 1) {
|
|
426
|
+
const id = args[0];
|
|
427
|
+
const key = String(id);
|
|
428
|
+
const isTopLevel = key in state;
|
|
429
|
+
if (isTopLevel) {
|
|
430
|
+
const isString3 = typeof state[id] === "string" || state[id] === null;
|
|
431
|
+
return {
|
|
432
|
+
...getUXProps(key),
|
|
433
|
+
id: key,
|
|
434
|
+
onBlur: () => onBlur(id),
|
|
435
|
+
onSelectionChange: (v) => onSelectionChange(
|
|
436
|
+
id,
|
|
437
|
+
!isString3 ? v : Array.from(v)[0] || null
|
|
438
|
+
),
|
|
439
|
+
selectedKeys: state[id] === null ? [] : isString3 ? [state[id]] : state[id]
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
const value2 = getNestedValue(state, key);
|
|
443
|
+
const isString2 = typeof value2 === "string" || value2 === null;
|
|
444
|
+
return {
|
|
445
|
+
...getUXProps(key),
|
|
446
|
+
id: key,
|
|
447
|
+
onBlur: () => onNestedBlur(key),
|
|
448
|
+
onSelectionChange: (v) => onNestedSelectionChange(key, v),
|
|
449
|
+
selectedKeys: value2 === null ? [] : isString2 ? [value2] : value2
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
const [arrayKey, itemId, field] = args;
|
|
453
|
+
const index = getIndex(String(arrayKey), itemId);
|
|
454
|
+
const arr = state[arrayKey];
|
|
455
|
+
const value = index !== void 0 ? getNestedValue(arr[index], field) : null;
|
|
456
|
+
const isString = typeof value === "string" || value === null;
|
|
457
|
+
const compositeKey = getItemCompositeKey(String(arrayKey), itemId, field);
|
|
458
|
+
return {
|
|
459
|
+
...getItemUXProps(String(arrayKey), itemId, field),
|
|
460
|
+
id: compositeKey,
|
|
461
|
+
onBlur: () => onItemBlur(arrayKey, itemId, field),
|
|
462
|
+
onSelectionChange: (v) => onItemSelectionChange(arrayKey, itemId, field, v),
|
|
463
|
+
selectedKeys: value === null ? [] : isString ? [value] : value
|
|
464
|
+
};
|
|
465
|
+
},
|
|
466
|
+
autocomplete: (...args) => {
|
|
467
|
+
if (args.length === 1) {
|
|
468
|
+
const id = args[0];
|
|
469
|
+
const key = String(id);
|
|
470
|
+
const isTopLevel = key in state;
|
|
471
|
+
if (isTopLevel) {
|
|
472
|
+
return {
|
|
473
|
+
...getUXProps(key),
|
|
474
|
+
id: key,
|
|
475
|
+
onBlur: () => onBlur(id),
|
|
476
|
+
onSelectionChange: (v) => onSelectionChange(id, v),
|
|
477
|
+
selectedKey: state[id]
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
return {
|
|
481
|
+
...getUXProps(key),
|
|
482
|
+
id: key,
|
|
483
|
+
onBlur: () => onNestedBlur(key),
|
|
484
|
+
onSelectionChange: (v) => onNestedSelectionChange(key, v),
|
|
485
|
+
selectedKey: getNestedValue(state, key)
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
const [arrayKey, itemId, field] = args;
|
|
489
|
+
const index = getIndex(String(arrayKey), itemId);
|
|
490
|
+
const arr = state[arrayKey];
|
|
491
|
+
const value = index !== void 0 ? getNestedValue(arr[index], field) : null;
|
|
492
|
+
const compositeKey = getItemCompositeKey(String(arrayKey), itemId, field);
|
|
493
|
+
return {
|
|
494
|
+
...getItemUXProps(String(arrayKey), itemId, field),
|
|
495
|
+
id: compositeKey,
|
|
496
|
+
onBlur: () => onItemBlur(arrayKey, itemId, field),
|
|
497
|
+
onSelectionChange: (v) => onItemSelectionChange(arrayKey, itemId, field, v),
|
|
498
|
+
selectedKey: value
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
};
|
|
215
502
|
return {
|
|
216
503
|
onBlur,
|
|
217
504
|
onValueChange,
|
|
@@ -220,42 +507,97 @@ function useForm(initialState, { validations, errorMessages } = {}) {
|
|
|
220
507
|
setState,
|
|
221
508
|
touched,
|
|
222
509
|
errors: errors2,
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
id,
|
|
236
|
-
onBlur: () => onBlur(id),
|
|
237
|
-
onSelectionChange: (v) => onSelectionChange(
|
|
238
|
-
id,
|
|
239
|
-
!isString ? v : Array.from(v)[0] || null
|
|
240
|
-
),
|
|
241
|
-
selectedKeys: state[id] === null ? [] : isString ? [state[id]] : state[id]
|
|
242
|
-
};
|
|
510
|
+
on: on2,
|
|
511
|
+
helpers: {
|
|
512
|
+
addItem: (arrayKey, item, index) => {
|
|
513
|
+
setState((prev) => {
|
|
514
|
+
const arr = [...prev[arrayKey]];
|
|
515
|
+
if (index === void 0) {
|
|
516
|
+
arr.push(item);
|
|
517
|
+
} else {
|
|
518
|
+
arr.splice(index, 0, item);
|
|
519
|
+
}
|
|
520
|
+
return { ...prev, [arrayKey]: arr };
|
|
521
|
+
});
|
|
243
522
|
},
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
523
|
+
removeItem: (arrayKey, index) => {
|
|
524
|
+
const itemIdKey = arrayIdentifiers?.[arrayKey] || "id";
|
|
525
|
+
const item = state[arrayKey][index];
|
|
526
|
+
const itemId = item?.[itemIdKey];
|
|
527
|
+
setState((prev) => {
|
|
528
|
+
const arr = [...prev[arrayKey]];
|
|
529
|
+
arr.splice(index, 1);
|
|
530
|
+
return { ...prev, [arrayKey]: arr };
|
|
531
|
+
});
|
|
532
|
+
if (itemId !== void 0) {
|
|
533
|
+
const prefix = `${String(arrayKey)}.${itemId}.`;
|
|
534
|
+
setItemTouched((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
535
|
+
setItemErrors((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
536
|
+
}
|
|
537
|
+
},
|
|
538
|
+
removeById: (arrayKey, itemId) => {
|
|
539
|
+
const index = getIndex(String(arrayKey), itemId);
|
|
540
|
+
if (index !== void 0) {
|
|
541
|
+
const arr = [...state[arrayKey]];
|
|
542
|
+
arr.splice(index, 1);
|
|
543
|
+
setState((prev) => ({ ...prev, [arrayKey]: arr }));
|
|
544
|
+
const prefix = `${String(arrayKey)}.${itemId}.`;
|
|
545
|
+
setItemTouched((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
546
|
+
setItemErrors((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
547
|
+
}
|
|
548
|
+
},
|
|
549
|
+
moveItem: (arrayKey, from, to) => {
|
|
550
|
+
setState((prev) => {
|
|
551
|
+
const arr = [...prev[arrayKey]];
|
|
552
|
+
const [item] = arr.splice(from, 1);
|
|
553
|
+
arr.splice(to, 0, item);
|
|
554
|
+
return { ...prev, [arrayKey]: arr };
|
|
555
|
+
});
|
|
556
|
+
},
|
|
557
|
+
moveById: (arrayKey, fromId, toId) => {
|
|
558
|
+
const fromIndex = getIndex(String(arrayKey), fromId);
|
|
559
|
+
const toIndex = getIndex(String(arrayKey), toId);
|
|
560
|
+
if (fromIndex !== void 0 && toIndex !== void 0) {
|
|
561
|
+
setState((prev) => {
|
|
562
|
+
const arr = [...prev[arrayKey]];
|
|
563
|
+
const [item] = arr.splice(fromIndex, 1);
|
|
564
|
+
arr.splice(toIndex, 0, item);
|
|
565
|
+
return { ...prev, [arrayKey]: arr };
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
}
|
|
251
569
|
},
|
|
570
|
+
isDirty: JSON.stringify(state) !== JSON.stringify(initialState),
|
|
252
571
|
hasInvalidValues: () => {
|
|
253
572
|
setTouched((prev) => allToValue(prev, true));
|
|
254
|
-
|
|
573
|
+
setItemTouched(
|
|
574
|
+
(prev) => Object.keys(prev).reduce(
|
|
575
|
+
(acc, key) => ({ ...acc, [key]: true }),
|
|
576
|
+
{}
|
|
577
|
+
)
|
|
578
|
+
);
|
|
579
|
+
setNestedTouched(
|
|
580
|
+
(prev) => Object.keys(prev).reduce(
|
|
581
|
+
(acc, key) => ({ ...acc, [key]: true }),
|
|
582
|
+
{}
|
|
583
|
+
)
|
|
584
|
+
);
|
|
585
|
+
const topLevelInvalid = JSON.stringify(errors2).includes(":true");
|
|
586
|
+
const itemLevelInvalid = Object.values(itemErrors).some(
|
|
587
|
+
(e) => e?.isInvalid
|
|
588
|
+
);
|
|
589
|
+
const nestedLevelInvalid = Object.values(nestedErrors).some(
|
|
590
|
+
(e) => e?.isInvalid
|
|
591
|
+
);
|
|
592
|
+
return topLevelInvalid || itemLevelInvalid || nestedLevelInvalid;
|
|
255
593
|
},
|
|
256
594
|
resetForm: (preservedKeys) => {
|
|
257
595
|
setTouched(initial.touched);
|
|
258
596
|
setErrors(initial.errors);
|
|
597
|
+
setItemTouched({});
|
|
598
|
+
setItemErrors({});
|
|
599
|
+
setNestedTouched({});
|
|
600
|
+
setNestedErrors({});
|
|
259
601
|
setState(
|
|
260
602
|
(prev) => preservedKeys === void 0 ? initialState : preservedKeys.reduce(
|
|
261
603
|
(acc, key) => ({
|
|
@@ -266,17 +608,47 @@ function useForm(initialState, { validations, errorMessages } = {}) {
|
|
|
266
608
|
)
|
|
267
609
|
);
|
|
268
610
|
},
|
|
269
|
-
resetTouched: (preservedKeys) =>
|
|
270
|
-
(
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
611
|
+
resetTouched: (preservedKeys) => {
|
|
612
|
+
setItemTouched({});
|
|
613
|
+
setNestedTouched({});
|
|
614
|
+
setTouched(
|
|
615
|
+
(prev) => preservedKeys === void 0 ? initialState : preservedKeys.reduce(
|
|
616
|
+
(acc, key) => ({
|
|
617
|
+
...acc,
|
|
618
|
+
[key]: prev[key]
|
|
619
|
+
}),
|
|
620
|
+
initial.touched
|
|
621
|
+
)
|
|
622
|
+
);
|
|
623
|
+
}
|
|
278
624
|
};
|
|
279
625
|
}
|
|
626
|
+
var { on } = useForm({
|
|
627
|
+
name: "Juan",
|
|
628
|
+
age: 25,
|
|
629
|
+
address: {
|
|
630
|
+
city: "Bogota",
|
|
631
|
+
country: "Colombia"
|
|
632
|
+
},
|
|
633
|
+
lines: [
|
|
634
|
+
{
|
|
635
|
+
id: 1,
|
|
636
|
+
name: "Line 1",
|
|
637
|
+
location: {
|
|
638
|
+
country: "CO",
|
|
639
|
+
city: "Bogota"
|
|
640
|
+
}
|
|
641
|
+
},
|
|
642
|
+
{
|
|
643
|
+
id: 2,
|
|
644
|
+
name: "Line 2",
|
|
645
|
+
location: {
|
|
646
|
+
country: "VE",
|
|
647
|
+
city: "Caracas"
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
]
|
|
651
|
+
});
|
|
280
652
|
export {
|
|
281
653
|
NextUIError,
|
|
282
654
|
useForm
|
package/package.json
CHANGED
|
@@ -1,36 +1,37 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@juantroconisf/lib",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "A form validation library for HeroUI.",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"module": "dist/index.mjs",
|
|
7
|
-
"types": "dist/index.d.ts",
|
|
8
|
-
"files": [
|
|
9
|
-
"dist",
|
|
10
|
-
"README.md"
|
|
11
|
-
],
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
},
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@juantroconisf/lib",
|
|
3
|
+
"version": "5.0.0",
|
|
4
|
+
"description": "A form validation library for HeroUI.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
14
|
+
"lint": "tsc",
|
|
15
|
+
"prepublishOnly": "pnpm run build"
|
|
16
|
+
},
|
|
17
|
+
"author": "Juan T",
|
|
18
|
+
"license": "ISC",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/juandiegotroconis/lib/issues"
|
|
21
|
+
},
|
|
22
|
+
"typings": "dist/index.d.ts",
|
|
23
|
+
"homepage": "https://github.com/juandiegotroconis/lib#readme",
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@heroui/react": "^2.8.5",
|
|
26
|
+
"@react-types/shared": "^3.32.1",
|
|
27
|
+
"@types/node": "^24.7.1",
|
|
28
|
+
"@types/react": "^19.2.2",
|
|
29
|
+
"react": "^19.2.0",
|
|
30
|
+
"tsup": "^8.5.0",
|
|
31
|
+
"typescript": "^5.9.3"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"@heroui/react": ">=2.0.0",
|
|
35
|
+
"react": ">=18.0.0"
|
|
36
|
+
}
|
|
37
|
+
}
|