@juantroconisf/lib 6.0.0 → 6.1.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 +8 -27
- package/dist/index.d.ts +8 -27
- package/dist/index.js +33 -27
- package/dist/index.mjs +33 -27
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -43,38 +43,19 @@ type ValidatorErrorMessage = {
|
|
|
43
43
|
* @template O The state type.
|
|
44
44
|
* @template K The key of the array in the state.
|
|
45
45
|
*/
|
|
46
|
-
type
|
|
47
|
-
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
* Custom error messages for individual fields in an array item.
|
|
51
|
-
* @template O The state type.
|
|
52
|
-
* @template K The key of the array in the state.
|
|
53
|
-
*/
|
|
54
|
-
type ArrayMessages<O extends StateType, K extends keyof O = keyof O> = {
|
|
55
|
-
[F in FieldPaths<ArrayElement<O[K]>>]?: ValidatorErrorMessage;
|
|
56
|
-
};
|
|
46
|
+
type ValidatorRule<item = any> = ValidatorParams | ((item: item, ...args: any[]) => ValidatorParams);
|
|
47
|
+
type RulePath<T> = T extends object ? {
|
|
48
|
+
[K in keyof T & string]: NonNullable<T[K]> extends (infer E)[] ? K | (E extends object ? `${K}.${RulePath<E>}` : never) : NonNullable<T[K]> extends object ? NonNullable<T[K]> extends Date ? K : K | `${K}.${RulePath<NonNullable<T[K]>>}` : K;
|
|
49
|
+
}[keyof T & string] : never;
|
|
57
50
|
/**
|
|
58
51
|
* Options for the useForm hook.
|
|
59
52
|
* @template O The state type.
|
|
60
53
|
*/
|
|
61
54
|
interface FormOptions<O extends StateType> {
|
|
62
55
|
/** Validation rules for top-level fields. */
|
|
63
|
-
rules?:
|
|
64
|
-
[key in keyof O]?: ValidatorParams;
|
|
65
|
-
};
|
|
56
|
+
rules?: Partial<Record<RulePath<O>, ValidatorRule>>;
|
|
66
57
|
/** Custom error messages for top-level fields. */
|
|
67
|
-
messages?:
|
|
68
|
-
[key in keyof O]?: ValidatorErrorMessage;
|
|
69
|
-
};
|
|
70
|
-
/** Validation rules for items within arrays. */
|
|
71
|
-
arrayRules?: {
|
|
72
|
-
[K in ArrayKeys<O>]?: ArrayRules<O, K>;
|
|
73
|
-
};
|
|
74
|
-
/** Custom error messages for items within arrays. */
|
|
75
|
-
arrayMessages?: {
|
|
76
|
-
[K in ArrayKeys<O>]?: ArrayMessages<O, K>;
|
|
77
|
-
};
|
|
58
|
+
messages?: Partial<Record<RulePath<O>, ValidatorErrorMessage>>;
|
|
78
59
|
/**
|
|
79
60
|
* Custom property names used as unique identifiers for items in specific arrays.
|
|
80
61
|
* Default is "id".
|
|
@@ -196,6 +177,6 @@ interface UseFormResponse<O extends StateType> {
|
|
|
196
177
|
resetTouched: (preservedKeys?: (keyof O)[]) => void;
|
|
197
178
|
}
|
|
198
179
|
|
|
199
|
-
declare function useForm<O extends StateType>(initialState: O, { rules, messages,
|
|
180
|
+
declare function useForm<O extends StateType>(initialState: O, { rules, messages, arrayIdentifiers }?: FormOptions<O>): UseFormResponse<O>;
|
|
200
181
|
|
|
201
|
-
export { type
|
|
182
|
+
export { type BlurFunc, type ErrorsType, type FormOptions, type HelpersFunc, type NestedChangeProps, NextUIError, type OnMethods, type StateType, type TouchedType, type UXProps, type UseFormResponse, type Validator, type ValidatorErrorMessage, type ValidatorParams, type ValidatorRule, type ValidatorTypes, type ValueChangeFunc, useForm };
|
package/dist/index.d.ts
CHANGED
|
@@ -43,38 +43,19 @@ type ValidatorErrorMessage = {
|
|
|
43
43
|
* @template O The state type.
|
|
44
44
|
* @template K The key of the array in the state.
|
|
45
45
|
*/
|
|
46
|
-
type
|
|
47
|
-
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
* Custom error messages for individual fields in an array item.
|
|
51
|
-
* @template O The state type.
|
|
52
|
-
* @template K The key of the array in the state.
|
|
53
|
-
*/
|
|
54
|
-
type ArrayMessages<O extends StateType, K extends keyof O = keyof O> = {
|
|
55
|
-
[F in FieldPaths<ArrayElement<O[K]>>]?: ValidatorErrorMessage;
|
|
56
|
-
};
|
|
46
|
+
type ValidatorRule<item = any> = ValidatorParams | ((item: item, ...args: any[]) => ValidatorParams);
|
|
47
|
+
type RulePath<T> = T extends object ? {
|
|
48
|
+
[K in keyof T & string]: NonNullable<T[K]> extends (infer E)[] ? K | (E extends object ? `${K}.${RulePath<E>}` : never) : NonNullable<T[K]> extends object ? NonNullable<T[K]> extends Date ? K : K | `${K}.${RulePath<NonNullable<T[K]>>}` : K;
|
|
49
|
+
}[keyof T & string] : never;
|
|
57
50
|
/**
|
|
58
51
|
* Options for the useForm hook.
|
|
59
52
|
* @template O The state type.
|
|
60
53
|
*/
|
|
61
54
|
interface FormOptions<O extends StateType> {
|
|
62
55
|
/** Validation rules for top-level fields. */
|
|
63
|
-
rules?:
|
|
64
|
-
[key in keyof O]?: ValidatorParams;
|
|
65
|
-
};
|
|
56
|
+
rules?: Partial<Record<RulePath<O>, ValidatorRule>>;
|
|
66
57
|
/** Custom error messages for top-level fields. */
|
|
67
|
-
messages?:
|
|
68
|
-
[key in keyof O]?: ValidatorErrorMessage;
|
|
69
|
-
};
|
|
70
|
-
/** Validation rules for items within arrays. */
|
|
71
|
-
arrayRules?: {
|
|
72
|
-
[K in ArrayKeys<O>]?: ArrayRules<O, K>;
|
|
73
|
-
};
|
|
74
|
-
/** Custom error messages for items within arrays. */
|
|
75
|
-
arrayMessages?: {
|
|
76
|
-
[K in ArrayKeys<O>]?: ArrayMessages<O, K>;
|
|
77
|
-
};
|
|
58
|
+
messages?: Partial<Record<RulePath<O>, ValidatorErrorMessage>>;
|
|
78
59
|
/**
|
|
79
60
|
* Custom property names used as unique identifiers for items in specific arrays.
|
|
80
61
|
* Default is "id".
|
|
@@ -196,6 +177,6 @@ interface UseFormResponse<O extends StateType> {
|
|
|
196
177
|
resetTouched: (preservedKeys?: (keyof O)[]) => void;
|
|
197
178
|
}
|
|
198
179
|
|
|
199
|
-
declare function useForm<O extends StateType>(initialState: O, { rules, messages,
|
|
180
|
+
declare function useForm<O extends StateType>(initialState: O, { rules, messages, arrayIdentifiers }?: FormOptions<O>): UseFormResponse<O>;
|
|
200
181
|
|
|
201
|
-
export { type
|
|
182
|
+
export { type BlurFunc, type ErrorsType, type FormOptions, type HelpersFunc, type NestedChangeProps, NextUIError, type OnMethods, type StateType, type TouchedType, type UXProps, type UseFormResponse, type Validator, type ValidatorErrorMessage, type ValidatorParams, type ValidatorRule, type ValidatorTypes, type ValueChangeFunc, useForm };
|
package/dist/index.js
CHANGED
|
@@ -219,13 +219,7 @@ function useValidate() {
|
|
|
219
219
|
}
|
|
220
220
|
|
|
221
221
|
// src/hooks/useForm.tsx
|
|
222
|
-
function useForm(initialState, {
|
|
223
|
-
rules,
|
|
224
|
-
messages,
|
|
225
|
-
arrayRules,
|
|
226
|
-
arrayMessages,
|
|
227
|
-
arrayIdentifiers
|
|
228
|
-
} = {}) {
|
|
222
|
+
function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
229
223
|
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();
|
|
230
224
|
const indexMap = (0, import_react.useMemo)(() => {
|
|
231
225
|
const map2 = /* @__PURE__ */ new Map();
|
|
@@ -252,12 +246,21 @@ function useForm(initialState, {
|
|
|
252
246
|
},
|
|
253
247
|
[indexMap]
|
|
254
248
|
);
|
|
249
|
+
const getRule = (path) => {
|
|
250
|
+
if (rules?.[path]) return rules[path];
|
|
251
|
+
const genericPath = path.replace(/\.\d+\./g, ".").replace(/\.\d+$/, "");
|
|
252
|
+
return rules?.[genericPath];
|
|
253
|
+
};
|
|
254
|
+
const getMessage = (path) => {
|
|
255
|
+
if (messages?.[path]) return messages[path];
|
|
256
|
+
const genericPath = path.replace(/\.\d+\./g, ".").replace(/\.\d+$/, "");
|
|
257
|
+
return messages?.[genericPath];
|
|
258
|
+
};
|
|
255
259
|
const validateInput = (compositeKey, value, ruleKey) => {
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
);
|
|
260
|
+
const ruleDef = getRule(ruleKey);
|
|
261
|
+
const rule = typeof ruleDef === "function" ? ruleDef(value, state) : ruleDef;
|
|
262
|
+
const message = getMessage(ruleKey);
|
|
263
|
+
const error = performValidations(value, rule, message);
|
|
261
264
|
setErrors((prev) => new Map(prev).set(compositeKey, error));
|
|
262
265
|
};
|
|
263
266
|
const getUXProps = (0, import_react.useCallback)(
|
|
@@ -272,14 +275,14 @@ function useForm(initialState, {
|
|
|
272
275
|
[errors2, touched]
|
|
273
276
|
);
|
|
274
277
|
const onBlur = (id) => {
|
|
275
|
-
validateInput(String(id), state[id], id);
|
|
278
|
+
validateInput(String(id), state[id], String(id));
|
|
276
279
|
if (touched.get(String(id))) return;
|
|
277
280
|
setTouched((prev) => new Map(prev).set(String(id), true));
|
|
278
281
|
}, onValueChange = ((...args) => {
|
|
279
282
|
if (args.length === 2) {
|
|
280
283
|
const [id, value] = args;
|
|
281
284
|
setState((prev) => handleNestedChange({ state: prev, id, value }));
|
|
282
|
-
validateInput(String(id), value, id);
|
|
285
|
+
validateInput(String(id), value, String(id));
|
|
283
286
|
return;
|
|
284
287
|
}
|
|
285
288
|
if (args.length === 3) {
|
|
@@ -325,7 +328,7 @@ function useForm(initialState, {
|
|
|
325
328
|
value: fixedValue
|
|
326
329
|
})
|
|
327
330
|
);
|
|
328
|
-
validateInput(String(id), fixedValue, id);
|
|
331
|
+
validateInput(String(id), fixedValue, String(id));
|
|
329
332
|
};
|
|
330
333
|
const getItemCompositeKey = (arrayKey, itemId, field) => `${arrayKey}.${itemId}.${field}`;
|
|
331
334
|
const getPrimitiveCompositeKey = (arrayKey, index) => `${arrayKey}.@${index}`;
|
|
@@ -333,16 +336,20 @@ function useForm(initialState, {
|
|
|
333
336
|
const validateItemInput = (arrayKey, itemId, field, value) => {
|
|
334
337
|
const index = getIndex(String(arrayKey), itemId);
|
|
335
338
|
if (index === void 0) return;
|
|
336
|
-
const arrayRuleDef = arrayRules?.[arrayKey]?.[field];
|
|
337
339
|
const item = state[arrayKey][index];
|
|
338
|
-
const fieldRules = typeof arrayRuleDef === "function" ? arrayRuleDef(item, index) : arrayRuleDef;
|
|
339
|
-
const fieldMessages = arrayMessages?.[arrayKey]?.[field];
|
|
340
340
|
const compositeKey = getItemCompositeKey(String(arrayKey), itemId, field);
|
|
341
|
+
let genericField = field.replace(/\.@\d+/, "");
|
|
342
|
+
if (genericField === "")
|
|
343
|
+
genericField = String(arrayKey);
|
|
344
|
+
else genericField = `${String(arrayKey)}.${genericField}`;
|
|
345
|
+
let effectivePath = `${String(arrayKey)}.${field}`;
|
|
346
|
+
if (field === "") effectivePath = String(arrayKey);
|
|
347
|
+
effectivePath = effectivePath.replace(/\.@\d+/g, "").replace(/\.@\d+$/, "");
|
|
348
|
+
const ruleDef = getRule(effectivePath);
|
|
349
|
+
const rule = typeof ruleDef === "function" ? ruleDef(value, state, item, index) : ruleDef;
|
|
350
|
+
const message = getMessage(effectivePath);
|
|
341
351
|
setErrors(
|
|
342
|
-
(prev) => new Map(prev).set(
|
|
343
|
-
compositeKey,
|
|
344
|
-
performValidations(value, fieldRules, fieldMessages)
|
|
345
|
-
)
|
|
352
|
+
(prev) => new Map(prev).set(compositeKey, performValidations(value, rule, message))
|
|
346
353
|
);
|
|
347
354
|
};
|
|
348
355
|
const getItemUXProps = (0, import_react.useCallback)(
|
|
@@ -394,12 +401,11 @@ function useForm(initialState, {
|
|
|
394
401
|
validateItemInput(arrayKey, itemId, field, fixedValue);
|
|
395
402
|
};
|
|
396
403
|
const validateNestedInput = (dotPath, value) => {
|
|
397
|
-
const
|
|
404
|
+
const ruleDef = getRule(dotPath);
|
|
405
|
+
const rule = typeof ruleDef === "function" ? ruleDef(value, state) : ruleDef;
|
|
406
|
+
const message = getMessage(dotPath);
|
|
398
407
|
setErrors(
|
|
399
|
-
(prev) => new Map(prev).set(
|
|
400
|
-
dotPath,
|
|
401
|
-
performValidations(value, rules?.[topKey], messages?.[topKey])
|
|
402
|
-
)
|
|
408
|
+
(prev) => new Map(prev).set(dotPath, performValidations(value, rule, message))
|
|
403
409
|
);
|
|
404
410
|
};
|
|
405
411
|
const onNestedBlur = (dotPath) => {
|
package/dist/index.mjs
CHANGED
|
@@ -200,13 +200,7 @@ function useValidate() {
|
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
// src/hooks/useForm.tsx
|
|
203
|
-
function useForm(initialState, {
|
|
204
|
-
rules,
|
|
205
|
-
messages,
|
|
206
|
-
arrayRules,
|
|
207
|
-
arrayMessages,
|
|
208
|
-
arrayIdentifiers
|
|
209
|
-
} = {}) {
|
|
203
|
+
function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
210
204
|
const [state, setState] = useState(initialState), [touched, setTouched] = useState(/* @__PURE__ */ new Map()), [errors2, setErrors] = useState(/* @__PURE__ */ new Map()), { performValidations } = useValidate();
|
|
211
205
|
const indexMap = useMemo(() => {
|
|
212
206
|
const map2 = /* @__PURE__ */ new Map();
|
|
@@ -233,12 +227,21 @@ function useForm(initialState, {
|
|
|
233
227
|
},
|
|
234
228
|
[indexMap]
|
|
235
229
|
);
|
|
230
|
+
const getRule = (path) => {
|
|
231
|
+
if (rules?.[path]) return rules[path];
|
|
232
|
+
const genericPath = path.replace(/\.\d+\./g, ".").replace(/\.\d+$/, "");
|
|
233
|
+
return rules?.[genericPath];
|
|
234
|
+
};
|
|
235
|
+
const getMessage = (path) => {
|
|
236
|
+
if (messages?.[path]) return messages[path];
|
|
237
|
+
const genericPath = path.replace(/\.\d+\./g, ".").replace(/\.\d+$/, "");
|
|
238
|
+
return messages?.[genericPath];
|
|
239
|
+
};
|
|
236
240
|
const validateInput = (compositeKey, value, ruleKey) => {
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
);
|
|
241
|
+
const ruleDef = getRule(ruleKey);
|
|
242
|
+
const rule = typeof ruleDef === "function" ? ruleDef(value, state) : ruleDef;
|
|
243
|
+
const message = getMessage(ruleKey);
|
|
244
|
+
const error = performValidations(value, rule, message);
|
|
242
245
|
setErrors((prev) => new Map(prev).set(compositeKey, error));
|
|
243
246
|
};
|
|
244
247
|
const getUXProps = useCallback(
|
|
@@ -253,14 +256,14 @@ function useForm(initialState, {
|
|
|
253
256
|
[errors2, touched]
|
|
254
257
|
);
|
|
255
258
|
const onBlur = (id) => {
|
|
256
|
-
validateInput(String(id), state[id], id);
|
|
259
|
+
validateInput(String(id), state[id], String(id));
|
|
257
260
|
if (touched.get(String(id))) return;
|
|
258
261
|
setTouched((prev) => new Map(prev).set(String(id), true));
|
|
259
262
|
}, onValueChange = ((...args) => {
|
|
260
263
|
if (args.length === 2) {
|
|
261
264
|
const [id, value] = args;
|
|
262
265
|
setState((prev) => handleNestedChange({ state: prev, id, value }));
|
|
263
|
-
validateInput(String(id), value, id);
|
|
266
|
+
validateInput(String(id), value, String(id));
|
|
264
267
|
return;
|
|
265
268
|
}
|
|
266
269
|
if (args.length === 3) {
|
|
@@ -306,7 +309,7 @@ function useForm(initialState, {
|
|
|
306
309
|
value: fixedValue
|
|
307
310
|
})
|
|
308
311
|
);
|
|
309
|
-
validateInput(String(id), fixedValue, id);
|
|
312
|
+
validateInput(String(id), fixedValue, String(id));
|
|
310
313
|
};
|
|
311
314
|
const getItemCompositeKey = (arrayKey, itemId, field) => `${arrayKey}.${itemId}.${field}`;
|
|
312
315
|
const getPrimitiveCompositeKey = (arrayKey, index) => `${arrayKey}.@${index}`;
|
|
@@ -314,16 +317,20 @@ function useForm(initialState, {
|
|
|
314
317
|
const validateItemInput = (arrayKey, itemId, field, value) => {
|
|
315
318
|
const index = getIndex(String(arrayKey), itemId);
|
|
316
319
|
if (index === void 0) return;
|
|
317
|
-
const arrayRuleDef = arrayRules?.[arrayKey]?.[field];
|
|
318
320
|
const item = state[arrayKey][index];
|
|
319
|
-
const fieldRules = typeof arrayRuleDef === "function" ? arrayRuleDef(item, index) : arrayRuleDef;
|
|
320
|
-
const fieldMessages = arrayMessages?.[arrayKey]?.[field];
|
|
321
321
|
const compositeKey = getItemCompositeKey(String(arrayKey), itemId, field);
|
|
322
|
+
let genericField = field.replace(/\.@\d+/, "");
|
|
323
|
+
if (genericField === "")
|
|
324
|
+
genericField = String(arrayKey);
|
|
325
|
+
else genericField = `${String(arrayKey)}.${genericField}`;
|
|
326
|
+
let effectivePath = `${String(arrayKey)}.${field}`;
|
|
327
|
+
if (field === "") effectivePath = String(arrayKey);
|
|
328
|
+
effectivePath = effectivePath.replace(/\.@\d+/g, "").replace(/\.@\d+$/, "");
|
|
329
|
+
const ruleDef = getRule(effectivePath);
|
|
330
|
+
const rule = typeof ruleDef === "function" ? ruleDef(value, state, item, index) : ruleDef;
|
|
331
|
+
const message = getMessage(effectivePath);
|
|
322
332
|
setErrors(
|
|
323
|
-
(prev) => new Map(prev).set(
|
|
324
|
-
compositeKey,
|
|
325
|
-
performValidations(value, fieldRules, fieldMessages)
|
|
326
|
-
)
|
|
333
|
+
(prev) => new Map(prev).set(compositeKey, performValidations(value, rule, message))
|
|
327
334
|
);
|
|
328
335
|
};
|
|
329
336
|
const getItemUXProps = useCallback(
|
|
@@ -375,12 +382,11 @@ function useForm(initialState, {
|
|
|
375
382
|
validateItemInput(arrayKey, itemId, field, fixedValue);
|
|
376
383
|
};
|
|
377
384
|
const validateNestedInput = (dotPath, value) => {
|
|
378
|
-
const
|
|
385
|
+
const ruleDef = getRule(dotPath);
|
|
386
|
+
const rule = typeof ruleDef === "function" ? ruleDef(value, state) : ruleDef;
|
|
387
|
+
const message = getMessage(dotPath);
|
|
379
388
|
setErrors(
|
|
380
|
-
(prev) => new Map(prev).set(
|
|
381
|
-
dotPath,
|
|
382
|
-
performValidations(value, rules?.[topKey], messages?.[topKey])
|
|
383
|
-
)
|
|
389
|
+
(prev) => new Map(prev).set(dotPath, performValidations(value, rule, message))
|
|
384
390
|
);
|
|
385
391
|
};
|
|
386
392
|
const onNestedBlur = (dotPath) => {
|