@juantroconisf/lib 4.1.3 → 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 +422 -49
- package/dist/index.mjs +423 -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}$/
|
|
@@ -142,6 +191,7 @@ function useValidate() {
|
|
|
142
191
|
if (value === "" && !isRequired) return validProps;
|
|
143
192
|
let errorFound = validProps;
|
|
144
193
|
for (const [key, opts] of items) {
|
|
194
|
+
if (opts === null) continue;
|
|
145
195
|
const { validate, msg } = errors[key], isInvalid = !validate(value, opts);
|
|
146
196
|
if (isInvalid) {
|
|
147
197
|
errorFound = {
|
|
@@ -157,7 +207,14 @@ function useValidate() {
|
|
|
157
207
|
}
|
|
158
208
|
|
|
159
209
|
// src/hooks/useForm.tsx
|
|
160
|
-
function useForm(initialState, {
|
|
210
|
+
function useForm(initialState, {
|
|
211
|
+
rules,
|
|
212
|
+
messages,
|
|
213
|
+
arrayRules,
|
|
214
|
+
arrayMessages,
|
|
215
|
+
arrayIdentifiers,
|
|
216
|
+
config
|
|
217
|
+
} = {}) {
|
|
161
218
|
const initial = {
|
|
162
219
|
touched: allToValue(initialState, false),
|
|
163
220
|
errors: allToValue(initialState, {
|
|
@@ -165,27 +222,50 @@ function useForm(initialState, { validations, errorMessages } = {}) {
|
|
|
165
222
|
errorMessage: ""
|
|
166
223
|
})
|
|
167
224
|
};
|
|
168
|
-
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]);
|
|
169
248
|
const validateInput = (id, value) => setErrors(
|
|
170
249
|
(prev) => handleNestedChange({
|
|
171
250
|
state: prev,
|
|
172
251
|
id,
|
|
173
252
|
value: performValidations(
|
|
174
253
|
value,
|
|
175
|
-
|
|
176
|
-
|
|
254
|
+
rules?.[id],
|
|
255
|
+
messages?.[id]
|
|
177
256
|
)
|
|
178
257
|
})
|
|
179
258
|
);
|
|
180
259
|
const getUXProps = useCallback(
|
|
181
260
|
(id) => {
|
|
182
|
-
const inputError = errors2[id]
|
|
261
|
+
const inputError = errors2[id] || nestedErrors[id];
|
|
262
|
+
const isTouched = touched[id] || nestedTouched[id];
|
|
183
263
|
return {
|
|
184
|
-
isInvalid: isTouched && inputError
|
|
185
|
-
errorMessage: isTouched ? inputError
|
|
264
|
+
isInvalid: Boolean(isTouched && inputError?.isInvalid),
|
|
265
|
+
errorMessage: isTouched ? inputError?.errorMessage || "" : ""
|
|
186
266
|
};
|
|
187
267
|
},
|
|
188
|
-
[errors2, touched]
|
|
268
|
+
[errors2, touched, nestedErrors, nestedTouched]
|
|
189
269
|
);
|
|
190
270
|
const onBlur = (id) => {
|
|
191
271
|
validateInput(id, state[id]);
|
|
@@ -211,6 +291,214 @@ function useForm(initialState, { validations, errorMessages } = {}) {
|
|
|
211
291
|
);
|
|
212
292
|
validateInput(id, fixedValue);
|
|
213
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
|
+
};
|
|
214
502
|
return {
|
|
215
503
|
onBlur,
|
|
216
504
|
onValueChange,
|
|
@@ -219,42 +507,97 @@ function useForm(initialState, { validations, errorMessages } = {}) {
|
|
|
219
507
|
setState,
|
|
220
508
|
touched,
|
|
221
509
|
errors: errors2,
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
id,
|
|
235
|
-
onBlur: () => onBlur(id),
|
|
236
|
-
onSelectionChange: (v) => onSelectionChange(
|
|
237
|
-
id,
|
|
238
|
-
!isString ? v : Array.from(v)[0] || null
|
|
239
|
-
),
|
|
240
|
-
selectedKeys: state[id] === null ? [] : isString ? [state[id]] : state[id]
|
|
241
|
-
};
|
|
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
|
+
});
|
|
242
522
|
},
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
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
|
+
}
|
|
250
569
|
},
|
|
570
|
+
isDirty: JSON.stringify(state) !== JSON.stringify(initialState),
|
|
251
571
|
hasInvalidValues: () => {
|
|
252
572
|
setTouched((prev) => allToValue(prev, true));
|
|
253
|
-
|
|
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;
|
|
254
593
|
},
|
|
255
594
|
resetForm: (preservedKeys) => {
|
|
256
595
|
setTouched(initial.touched);
|
|
257
596
|
setErrors(initial.errors);
|
|
597
|
+
setItemTouched({});
|
|
598
|
+
setItemErrors({});
|
|
599
|
+
setNestedTouched({});
|
|
600
|
+
setNestedErrors({});
|
|
258
601
|
setState(
|
|
259
602
|
(prev) => preservedKeys === void 0 ? initialState : preservedKeys.reduce(
|
|
260
603
|
(acc, key) => ({
|
|
@@ -265,17 +608,47 @@ function useForm(initialState, { validations, errorMessages } = {}) {
|
|
|
265
608
|
)
|
|
266
609
|
);
|
|
267
610
|
},
|
|
268
|
-
resetTouched: (preservedKeys) =>
|
|
269
|
-
(
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
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
|
+
}
|
|
277
624
|
};
|
|
278
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
|
+
});
|
|
279
652
|
export {
|
|
280
653
|
NextUIError,
|
|
281
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
|
+
}
|