@juantroconisf/lib 11.8.0 → 11.9.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 +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +102 -96
- package/dist/index.mjs +102 -96
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -239,7 +239,10 @@ interface HelpersFunc<O extends StateType> {
|
|
|
239
239
|
/** Gets an item from an array by its unique identifier (O(1) via indexMap). */
|
|
240
240
|
getItemById: <K extends ArrayPaths<O>>(arrayKey: K, itemId: string | number) => (NestedFieldValue<O, K> extends (infer E)[] ? E : never) | undefined;
|
|
241
241
|
/** Validates a single item in an array by its unique identifier. */
|
|
242
|
-
validateItem: <K extends ArrayPaths<O>>(arrayKey: K, itemId: string | number) => Promise<
|
|
242
|
+
validateItem: <K extends ArrayPaths<O>>(arrayKey: K, itemId: string | number) => Promise<{
|
|
243
|
+
isValid: boolean;
|
|
244
|
+
errors: string[];
|
|
245
|
+
}>;
|
|
243
246
|
}
|
|
244
247
|
/**
|
|
245
248
|
* The response object from the useForm hook.
|
|
@@ -287,7 +290,7 @@ interface UseFormResponse<O extends StateType> {
|
|
|
287
290
|
* If validation fails, identifying errors and touching fields.
|
|
288
291
|
* If validation succeeds, calls the provided handler with the current state.
|
|
289
292
|
*/
|
|
290
|
-
onFormSubmit: (fn: FormSubmitHandler<O>) => (e: React.FormEvent) => void
|
|
293
|
+
onFormSubmit: (fn: FormSubmitHandler<O>) => (e: React.FormEvent) => Promise<void>;
|
|
291
294
|
/**
|
|
292
295
|
* A controlled form component that handles submission and validation.
|
|
293
296
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -239,7 +239,10 @@ interface HelpersFunc<O extends StateType> {
|
|
|
239
239
|
/** Gets an item from an array by its unique identifier (O(1) via indexMap). */
|
|
240
240
|
getItemById: <K extends ArrayPaths<O>>(arrayKey: K, itemId: string | number) => (NestedFieldValue<O, K> extends (infer E)[] ? E : never) | undefined;
|
|
241
241
|
/** Validates a single item in an array by its unique identifier. */
|
|
242
|
-
validateItem: <K extends ArrayPaths<O>>(arrayKey: K, itemId: string | number) => Promise<
|
|
242
|
+
validateItem: <K extends ArrayPaths<O>>(arrayKey: K, itemId: string | number) => Promise<{
|
|
243
|
+
isValid: boolean;
|
|
244
|
+
errors: string[];
|
|
245
|
+
}>;
|
|
243
246
|
}
|
|
244
247
|
/**
|
|
245
248
|
* The response object from the useForm hook.
|
|
@@ -287,7 +290,7 @@ interface UseFormResponse<O extends StateType> {
|
|
|
287
290
|
* If validation fails, identifying errors and touching fields.
|
|
288
291
|
* If validation succeeds, calls the provided handler with the current state.
|
|
289
292
|
*/
|
|
290
|
-
onFormSubmit: (fn: FormSubmitHandler<O>) => (e: React.FormEvent) => void
|
|
293
|
+
onFormSubmit: (fn: FormSubmitHandler<O>) => (e: React.FormEvent) => Promise<void>;
|
|
291
294
|
/**
|
|
292
295
|
* A controlled form component that handles submission and validation.
|
|
293
296
|
*/
|
package/dist/index.js
CHANGED
|
@@ -553,15 +553,21 @@ function useForm(schema, {
|
|
|
553
553
|
[getRule, runValidation, validationSchema]
|
|
554
554
|
);
|
|
555
555
|
const validateAll = (0, import_react2.useCallback)(() => {
|
|
556
|
-
if (!validationSchema)
|
|
556
|
+
if (!validationSchema)
|
|
557
|
+
return Promise.resolve({ isValid: true, errors: [] });
|
|
557
558
|
const cleanMetadata = new Map(metadataRef.current);
|
|
558
559
|
cleanMetadata.forEach((value, key) => {
|
|
559
560
|
if (value.isInvalid) {
|
|
560
|
-
cleanMetadata.set(key, {
|
|
561
|
+
cleanMetadata.set(key, {
|
|
562
|
+
...value,
|
|
563
|
+
isInvalid: false,
|
|
564
|
+
errorMessage: ""
|
|
565
|
+
});
|
|
561
566
|
}
|
|
562
567
|
});
|
|
563
568
|
const handleErrors = (err) => {
|
|
564
569
|
const newMetadata = new Map(cleanMetadata);
|
|
570
|
+
const errors = [];
|
|
565
571
|
if (err.inner) {
|
|
566
572
|
err.inner.forEach((validationError) => {
|
|
567
573
|
const yupPath = validationError.path;
|
|
@@ -589,6 +595,7 @@ function useForm(schema, {
|
|
|
589
595
|
}
|
|
590
596
|
}
|
|
591
597
|
const compositeKey = compositeParts.join(".");
|
|
598
|
+
errors.push(compositeKey);
|
|
592
599
|
const currentMeta = newMetadata.get(compositeKey) || {
|
|
593
600
|
isTouched: false,
|
|
594
601
|
isInvalid: false,
|
|
@@ -603,26 +610,26 @@ function useForm(schema, {
|
|
|
603
610
|
});
|
|
604
611
|
}
|
|
605
612
|
setMetadata(newMetadata);
|
|
606
|
-
return
|
|
613
|
+
return { isValid: false, errors };
|
|
607
614
|
};
|
|
608
615
|
try {
|
|
609
616
|
validationSchema.validateSync(state, { abortEarly: false });
|
|
610
617
|
} catch (err) {
|
|
611
618
|
if (err.name === "ValidationError") {
|
|
612
|
-
return handleErrors(err);
|
|
619
|
+
return Promise.resolve(handleErrors(err));
|
|
613
620
|
}
|
|
614
621
|
return (async () => {
|
|
615
622
|
try {
|
|
616
623
|
await validationSchema.validate(state, { abortEarly: false });
|
|
617
624
|
setMetadata(cleanMetadata);
|
|
618
|
-
return
|
|
625
|
+
return { isValid: true, errors: [] };
|
|
619
626
|
} catch (asyncErr) {
|
|
620
627
|
return handleErrors(asyncErr);
|
|
621
628
|
}
|
|
622
629
|
})();
|
|
623
630
|
}
|
|
624
631
|
setMetadata(cleanMetadata);
|
|
625
|
-
return
|
|
632
|
+
return Promise.resolve({ isValid: true, errors: [] });
|
|
626
633
|
}, [validationSchema, state, arrayIdentifiers]);
|
|
627
634
|
const handleFieldChange = (0, import_react2.useCallback)(
|
|
628
635
|
(resolution, newValue) => {
|
|
@@ -767,91 +774,88 @@ function useForm(schema, {
|
|
|
767
774
|
},
|
|
768
775
|
[validateField, getRule, validationSchema]
|
|
769
776
|
);
|
|
770
|
-
const on = (0, import_react2.useMemo)(
|
|
771
|
-
() => {
|
|
772
|
-
const
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
return {
|
|
807
|
-
...createHandlers(data),
|
|
808
|
-
selectedKeys: data.value === null || data.value === void 0 ? [] : isArray ? data.value.map(String) : [String(data.value)],
|
|
809
|
-
onSelectionChange: (v) => {
|
|
810
|
-
const fixed = typeof v === "string" || v === null ? v : isArray ? Array.from(v) : Array.from(v)[0] ?? null;
|
|
811
|
-
handleFieldChange(data, fixed);
|
|
812
|
-
}
|
|
813
|
-
};
|
|
814
|
-
}),
|
|
815
|
-
autocomplete: (...args) => getCachedProps("autocomplete", args, (data) => ({
|
|
777
|
+
const on = (0, import_react2.useMemo)(() => {
|
|
778
|
+
const getCachedProps = (method, args, factory) => {
|
|
779
|
+
const data = resolveFieldData(
|
|
780
|
+
args,
|
|
781
|
+
stateRef.current,
|
|
782
|
+
getIndex,
|
|
783
|
+
getNestedValue,
|
|
784
|
+
getRule,
|
|
785
|
+
validationSchema
|
|
786
|
+
);
|
|
787
|
+
if (!data) return {};
|
|
788
|
+
const meta = metadataRef.current.get(data.compositeKey);
|
|
789
|
+
const deps = JSON.stringify([
|
|
790
|
+
data.value,
|
|
791
|
+
meta?.isInvalid,
|
|
792
|
+
meta?.errorMessage,
|
|
793
|
+
meta?.isTouched
|
|
794
|
+
]);
|
|
795
|
+
const cacheKey = `${method}:${JSON.stringify(args)}`;
|
|
796
|
+
const cached = propsCache.current.get(cacheKey);
|
|
797
|
+
if (cached && cached.deps === deps) {
|
|
798
|
+
return cached.props;
|
|
799
|
+
}
|
|
800
|
+
const props = factory(data);
|
|
801
|
+
propsCache.current.set(cacheKey, { props, deps });
|
|
802
|
+
return props;
|
|
803
|
+
};
|
|
804
|
+
return {
|
|
805
|
+
input: (...args) => getCachedProps("input", args, (data) => ({
|
|
806
|
+
...createHandlers(data),
|
|
807
|
+
value: data.value === null || data.value === void 0 ? "" : typeof data.value === "boolean" ? data.value : String(data.value),
|
|
808
|
+
onValueChange: (v) => handleFieldChange(data, v)
|
|
809
|
+
})),
|
|
810
|
+
select: (...args) => getCachedProps("select", args, (data) => {
|
|
811
|
+
const isArray = Array.isArray(data.value);
|
|
812
|
+
return {
|
|
816
813
|
...createHandlers(data),
|
|
817
|
-
|
|
814
|
+
selectedKeys: data.value === null || data.value === void 0 ? [] : isArray ? data.value.map(String) : [String(data.value)],
|
|
818
815
|
onSelectionChange: (v) => {
|
|
819
|
-
const fixed = typeof v === "string" || v === null
|
|
816
|
+
const fixed = typeof v === "string" || v === null ? v : isArray ? Array.from(v) : Array.from(v)[0] ?? null;
|
|
820
817
|
handleFieldChange(data, fixed);
|
|
821
818
|
}
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
819
|
+
};
|
|
820
|
+
}),
|
|
821
|
+
autocomplete: (...args) => getCachedProps("autocomplete", args, (data) => ({
|
|
822
|
+
...createHandlers(data),
|
|
823
|
+
selectedKey: data.value === null || data.value === void 0 ? null : String(data.value),
|
|
824
|
+
onSelectionChange: (v) => {
|
|
825
|
+
const fixed = typeof v === "string" || v === null || v === void 0 ? v : String(v);
|
|
826
|
+
handleFieldChange(data, fixed);
|
|
827
|
+
}
|
|
828
|
+
})),
|
|
829
|
+
numberInput: (...args) => getCachedProps("numberInput", args, (data) => ({
|
|
830
|
+
...createHandlers(data),
|
|
831
|
+
value: data.value === null || data.value === void 0 ? "" : String(data.value),
|
|
832
|
+
onValueChange: (v) => handleFieldChange(data, v)
|
|
833
|
+
})),
|
|
834
|
+
checkbox: (...args) => getCachedProps("checkbox", args, (data) => ({
|
|
835
|
+
...createHandlers(data),
|
|
836
|
+
isSelected: Boolean(data.value),
|
|
837
|
+
onValueChange: (v) => handleFieldChange(data, v)
|
|
838
|
+
})),
|
|
839
|
+
switch: (...args) => getCachedProps("switch", args, (data) => ({
|
|
840
|
+
...createHandlers(data),
|
|
841
|
+
isSelected: Boolean(data.value),
|
|
842
|
+
onValueChange: (v) => handleFieldChange(data, v)
|
|
843
|
+
})),
|
|
844
|
+
radio: (...args) => getCachedProps("radio", args, (data) => ({
|
|
845
|
+
...createHandlers(data),
|
|
846
|
+
value: data.value === null || data.value === void 0 ? "" : String(data.value),
|
|
847
|
+
onValueChange: (v) => handleFieldChange(data, v)
|
|
848
|
+
}))
|
|
849
|
+
};
|
|
850
|
+
}, [
|
|
851
|
+
createHandlers,
|
|
852
|
+
getIndex,
|
|
853
|
+
handleFieldChange,
|
|
854
|
+
getRule,
|
|
855
|
+
validationSchema,
|
|
856
|
+
state,
|
|
857
|
+
metadata
|
|
858
|
+
]);
|
|
855
859
|
const helpers = (0, import_react2.useMemo)(
|
|
856
860
|
() => ({
|
|
857
861
|
addItem: (arrayKey, item, index) => {
|
|
@@ -967,9 +971,9 @@ function useForm(schema, {
|
|
|
967
971
|
return getNestedValue(stateRef.current, arrayKey)[index];
|
|
968
972
|
},
|
|
969
973
|
validateItem: async (arrayKey, itemId) => {
|
|
970
|
-
if (!validationSchema) return
|
|
974
|
+
if (!validationSchema) return { isValid: true, errors: [] };
|
|
971
975
|
const index = getIndex(arrayKey, itemId);
|
|
972
|
-
if (index === void 0) return
|
|
976
|
+
if (index === void 0) return { isValid: true, errors: [] };
|
|
973
977
|
const yupPath = `${String(arrayKey)}[${index}]`;
|
|
974
978
|
const prefix = `${String(arrayKey)}.${itemId}.`;
|
|
975
979
|
const cleanMetadata = new Map(metadataRef.current);
|
|
@@ -985,6 +989,7 @@ function useForm(schema, {
|
|
|
985
989
|
}
|
|
986
990
|
const handleErrors = (err) => {
|
|
987
991
|
const newMetadata = new Map(cleanMetadata);
|
|
992
|
+
const errors = [];
|
|
988
993
|
if (err.inner) {
|
|
989
994
|
err.inner.forEach((validationError) => {
|
|
990
995
|
const localDotPath = validationError.path.replace(
|
|
@@ -1014,6 +1019,7 @@ function useForm(schema, {
|
|
|
1014
1019
|
}
|
|
1015
1020
|
}
|
|
1016
1021
|
const compositeKey = compositeParts.join(".");
|
|
1022
|
+
errors.push(compositeKey);
|
|
1017
1023
|
const currentMeta = newMetadata.get(compositeKey) || {
|
|
1018
1024
|
isTouched: false,
|
|
1019
1025
|
isInvalid: false,
|
|
@@ -1028,19 +1034,19 @@ function useForm(schema, {
|
|
|
1028
1034
|
});
|
|
1029
1035
|
}
|
|
1030
1036
|
setMetadata(newMetadata);
|
|
1031
|
-
return
|
|
1037
|
+
return { isValid: false, errors };
|
|
1032
1038
|
};
|
|
1033
1039
|
try {
|
|
1034
1040
|
await validationSchema.validateAt(yupPath, stateRef.current, {
|
|
1035
1041
|
abortEarly: false
|
|
1036
1042
|
});
|
|
1037
1043
|
setMetadata(cleanMetadata);
|
|
1038
|
-
return
|
|
1044
|
+
return { isValid: true, errors: [] };
|
|
1039
1045
|
} catch (err) {
|
|
1040
1046
|
if (err.name === "ValidationError") {
|
|
1041
1047
|
return handleErrors(err);
|
|
1042
1048
|
}
|
|
1043
|
-
return
|
|
1049
|
+
return { isValid: true, errors: [] };
|
|
1044
1050
|
}
|
|
1045
1051
|
}
|
|
1046
1052
|
}),
|
|
@@ -1130,7 +1136,8 @@ function useForm(schema, {
|
|
|
1130
1136
|
const onFormSubmit = (0, import_react2.useCallback)(
|
|
1131
1137
|
(fn) => async (e) => {
|
|
1132
1138
|
e.preventDefault();
|
|
1133
|
-
|
|
1139
|
+
const { isValid } = await validateAll();
|
|
1140
|
+
if (!isValid) return;
|
|
1134
1141
|
fn(stateRef.current, e);
|
|
1135
1142
|
},
|
|
1136
1143
|
[validateAll]
|
|
@@ -1165,9 +1172,8 @@ function useForm(schema, {
|
|
|
1165
1172
|
const { onSubmit, ...rest } = props;
|
|
1166
1173
|
const handleSubmit = async (e) => {
|
|
1167
1174
|
e.preventDefault();
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
}
|
|
1175
|
+
const { isValid } = await validateAllRef.current();
|
|
1176
|
+
if (!isValid) return;
|
|
1171
1177
|
onFormSubmitPropRef.current?.(stateRef.current, e);
|
|
1172
1178
|
if (resetOnSubmitRef.current) {
|
|
1173
1179
|
handleReset({ keepValues: keepValuesPropRef.current });
|
package/dist/index.mjs
CHANGED
|
@@ -527,15 +527,21 @@ function useForm(schema, {
|
|
|
527
527
|
[getRule, runValidation, validationSchema]
|
|
528
528
|
);
|
|
529
529
|
const validateAll = useCallback(() => {
|
|
530
|
-
if (!validationSchema)
|
|
530
|
+
if (!validationSchema)
|
|
531
|
+
return Promise.resolve({ isValid: true, errors: [] });
|
|
531
532
|
const cleanMetadata = new Map(metadataRef.current);
|
|
532
533
|
cleanMetadata.forEach((value, key) => {
|
|
533
534
|
if (value.isInvalid) {
|
|
534
|
-
cleanMetadata.set(key, {
|
|
535
|
+
cleanMetadata.set(key, {
|
|
536
|
+
...value,
|
|
537
|
+
isInvalid: false,
|
|
538
|
+
errorMessage: ""
|
|
539
|
+
});
|
|
535
540
|
}
|
|
536
541
|
});
|
|
537
542
|
const handleErrors = (err) => {
|
|
538
543
|
const newMetadata = new Map(cleanMetadata);
|
|
544
|
+
const errors = [];
|
|
539
545
|
if (err.inner) {
|
|
540
546
|
err.inner.forEach((validationError) => {
|
|
541
547
|
const yupPath = validationError.path;
|
|
@@ -563,6 +569,7 @@ function useForm(schema, {
|
|
|
563
569
|
}
|
|
564
570
|
}
|
|
565
571
|
const compositeKey = compositeParts.join(".");
|
|
572
|
+
errors.push(compositeKey);
|
|
566
573
|
const currentMeta = newMetadata.get(compositeKey) || {
|
|
567
574
|
isTouched: false,
|
|
568
575
|
isInvalid: false,
|
|
@@ -577,26 +584,26 @@ function useForm(schema, {
|
|
|
577
584
|
});
|
|
578
585
|
}
|
|
579
586
|
setMetadata(newMetadata);
|
|
580
|
-
return
|
|
587
|
+
return { isValid: false, errors };
|
|
581
588
|
};
|
|
582
589
|
try {
|
|
583
590
|
validationSchema.validateSync(state, { abortEarly: false });
|
|
584
591
|
} catch (err) {
|
|
585
592
|
if (err.name === "ValidationError") {
|
|
586
|
-
return handleErrors(err);
|
|
593
|
+
return Promise.resolve(handleErrors(err));
|
|
587
594
|
}
|
|
588
595
|
return (async () => {
|
|
589
596
|
try {
|
|
590
597
|
await validationSchema.validate(state, { abortEarly: false });
|
|
591
598
|
setMetadata(cleanMetadata);
|
|
592
|
-
return
|
|
599
|
+
return { isValid: true, errors: [] };
|
|
593
600
|
} catch (asyncErr) {
|
|
594
601
|
return handleErrors(asyncErr);
|
|
595
602
|
}
|
|
596
603
|
})();
|
|
597
604
|
}
|
|
598
605
|
setMetadata(cleanMetadata);
|
|
599
|
-
return
|
|
606
|
+
return Promise.resolve({ isValid: true, errors: [] });
|
|
600
607
|
}, [validationSchema, state, arrayIdentifiers]);
|
|
601
608
|
const handleFieldChange = useCallback(
|
|
602
609
|
(resolution, newValue) => {
|
|
@@ -741,91 +748,88 @@ function useForm(schema, {
|
|
|
741
748
|
},
|
|
742
749
|
[validateField, getRule, validationSchema]
|
|
743
750
|
);
|
|
744
|
-
const on = useMemo(
|
|
745
|
-
() => {
|
|
746
|
-
const
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
return {
|
|
781
|
-
...createHandlers(data),
|
|
782
|
-
selectedKeys: data.value === null || data.value === void 0 ? [] : isArray ? data.value.map(String) : [String(data.value)],
|
|
783
|
-
onSelectionChange: (v) => {
|
|
784
|
-
const fixed = typeof v === "string" || v === null ? v : isArray ? Array.from(v) : Array.from(v)[0] ?? null;
|
|
785
|
-
handleFieldChange(data, fixed);
|
|
786
|
-
}
|
|
787
|
-
};
|
|
788
|
-
}),
|
|
789
|
-
autocomplete: (...args) => getCachedProps("autocomplete", args, (data) => ({
|
|
751
|
+
const on = useMemo(() => {
|
|
752
|
+
const getCachedProps = (method, args, factory) => {
|
|
753
|
+
const data = resolveFieldData(
|
|
754
|
+
args,
|
|
755
|
+
stateRef.current,
|
|
756
|
+
getIndex,
|
|
757
|
+
getNestedValue,
|
|
758
|
+
getRule,
|
|
759
|
+
validationSchema
|
|
760
|
+
);
|
|
761
|
+
if (!data) return {};
|
|
762
|
+
const meta = metadataRef.current.get(data.compositeKey);
|
|
763
|
+
const deps = JSON.stringify([
|
|
764
|
+
data.value,
|
|
765
|
+
meta?.isInvalid,
|
|
766
|
+
meta?.errorMessage,
|
|
767
|
+
meta?.isTouched
|
|
768
|
+
]);
|
|
769
|
+
const cacheKey = `${method}:${JSON.stringify(args)}`;
|
|
770
|
+
const cached = propsCache.current.get(cacheKey);
|
|
771
|
+
if (cached && cached.deps === deps) {
|
|
772
|
+
return cached.props;
|
|
773
|
+
}
|
|
774
|
+
const props = factory(data);
|
|
775
|
+
propsCache.current.set(cacheKey, { props, deps });
|
|
776
|
+
return props;
|
|
777
|
+
};
|
|
778
|
+
return {
|
|
779
|
+
input: (...args) => getCachedProps("input", args, (data) => ({
|
|
780
|
+
...createHandlers(data),
|
|
781
|
+
value: data.value === null || data.value === void 0 ? "" : typeof data.value === "boolean" ? data.value : String(data.value),
|
|
782
|
+
onValueChange: (v) => handleFieldChange(data, v)
|
|
783
|
+
})),
|
|
784
|
+
select: (...args) => getCachedProps("select", args, (data) => {
|
|
785
|
+
const isArray = Array.isArray(data.value);
|
|
786
|
+
return {
|
|
790
787
|
...createHandlers(data),
|
|
791
|
-
|
|
788
|
+
selectedKeys: data.value === null || data.value === void 0 ? [] : isArray ? data.value.map(String) : [String(data.value)],
|
|
792
789
|
onSelectionChange: (v) => {
|
|
793
|
-
const fixed = typeof v === "string" || v === null
|
|
790
|
+
const fixed = typeof v === "string" || v === null ? v : isArray ? Array.from(v) : Array.from(v)[0] ?? null;
|
|
794
791
|
handleFieldChange(data, fixed);
|
|
795
792
|
}
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
793
|
+
};
|
|
794
|
+
}),
|
|
795
|
+
autocomplete: (...args) => getCachedProps("autocomplete", args, (data) => ({
|
|
796
|
+
...createHandlers(data),
|
|
797
|
+
selectedKey: data.value === null || data.value === void 0 ? null : String(data.value),
|
|
798
|
+
onSelectionChange: (v) => {
|
|
799
|
+
const fixed = typeof v === "string" || v === null || v === void 0 ? v : String(v);
|
|
800
|
+
handleFieldChange(data, fixed);
|
|
801
|
+
}
|
|
802
|
+
})),
|
|
803
|
+
numberInput: (...args) => getCachedProps("numberInput", args, (data) => ({
|
|
804
|
+
...createHandlers(data),
|
|
805
|
+
value: data.value === null || data.value === void 0 ? "" : String(data.value),
|
|
806
|
+
onValueChange: (v) => handleFieldChange(data, v)
|
|
807
|
+
})),
|
|
808
|
+
checkbox: (...args) => getCachedProps("checkbox", args, (data) => ({
|
|
809
|
+
...createHandlers(data),
|
|
810
|
+
isSelected: Boolean(data.value),
|
|
811
|
+
onValueChange: (v) => handleFieldChange(data, v)
|
|
812
|
+
})),
|
|
813
|
+
switch: (...args) => getCachedProps("switch", args, (data) => ({
|
|
814
|
+
...createHandlers(data),
|
|
815
|
+
isSelected: Boolean(data.value),
|
|
816
|
+
onValueChange: (v) => handleFieldChange(data, v)
|
|
817
|
+
})),
|
|
818
|
+
radio: (...args) => getCachedProps("radio", args, (data) => ({
|
|
819
|
+
...createHandlers(data),
|
|
820
|
+
value: data.value === null || data.value === void 0 ? "" : String(data.value),
|
|
821
|
+
onValueChange: (v) => handleFieldChange(data, v)
|
|
822
|
+
}))
|
|
823
|
+
};
|
|
824
|
+
}, [
|
|
825
|
+
createHandlers,
|
|
826
|
+
getIndex,
|
|
827
|
+
handleFieldChange,
|
|
828
|
+
getRule,
|
|
829
|
+
validationSchema,
|
|
830
|
+
state,
|
|
831
|
+
metadata
|
|
832
|
+
]);
|
|
829
833
|
const helpers = useMemo(
|
|
830
834
|
() => ({
|
|
831
835
|
addItem: (arrayKey, item, index) => {
|
|
@@ -941,9 +945,9 @@ function useForm(schema, {
|
|
|
941
945
|
return getNestedValue(stateRef.current, arrayKey)[index];
|
|
942
946
|
},
|
|
943
947
|
validateItem: async (arrayKey, itemId) => {
|
|
944
|
-
if (!validationSchema) return
|
|
948
|
+
if (!validationSchema) return { isValid: true, errors: [] };
|
|
945
949
|
const index = getIndex(arrayKey, itemId);
|
|
946
|
-
if (index === void 0) return
|
|
950
|
+
if (index === void 0) return { isValid: true, errors: [] };
|
|
947
951
|
const yupPath = `${String(arrayKey)}[${index}]`;
|
|
948
952
|
const prefix = `${String(arrayKey)}.${itemId}.`;
|
|
949
953
|
const cleanMetadata = new Map(metadataRef.current);
|
|
@@ -959,6 +963,7 @@ function useForm(schema, {
|
|
|
959
963
|
}
|
|
960
964
|
const handleErrors = (err) => {
|
|
961
965
|
const newMetadata = new Map(cleanMetadata);
|
|
966
|
+
const errors = [];
|
|
962
967
|
if (err.inner) {
|
|
963
968
|
err.inner.forEach((validationError) => {
|
|
964
969
|
const localDotPath = validationError.path.replace(
|
|
@@ -988,6 +993,7 @@ function useForm(schema, {
|
|
|
988
993
|
}
|
|
989
994
|
}
|
|
990
995
|
const compositeKey = compositeParts.join(".");
|
|
996
|
+
errors.push(compositeKey);
|
|
991
997
|
const currentMeta = newMetadata.get(compositeKey) || {
|
|
992
998
|
isTouched: false,
|
|
993
999
|
isInvalid: false,
|
|
@@ -1002,19 +1008,19 @@ function useForm(schema, {
|
|
|
1002
1008
|
});
|
|
1003
1009
|
}
|
|
1004
1010
|
setMetadata(newMetadata);
|
|
1005
|
-
return
|
|
1011
|
+
return { isValid: false, errors };
|
|
1006
1012
|
};
|
|
1007
1013
|
try {
|
|
1008
1014
|
await validationSchema.validateAt(yupPath, stateRef.current, {
|
|
1009
1015
|
abortEarly: false
|
|
1010
1016
|
});
|
|
1011
1017
|
setMetadata(cleanMetadata);
|
|
1012
|
-
return
|
|
1018
|
+
return { isValid: true, errors: [] };
|
|
1013
1019
|
} catch (err) {
|
|
1014
1020
|
if (err.name === "ValidationError") {
|
|
1015
1021
|
return handleErrors(err);
|
|
1016
1022
|
}
|
|
1017
|
-
return
|
|
1023
|
+
return { isValid: true, errors: [] };
|
|
1018
1024
|
}
|
|
1019
1025
|
}
|
|
1020
1026
|
}),
|
|
@@ -1104,7 +1110,8 @@ function useForm(schema, {
|
|
|
1104
1110
|
const onFormSubmit = useCallback(
|
|
1105
1111
|
(fn) => async (e) => {
|
|
1106
1112
|
e.preventDefault();
|
|
1107
|
-
|
|
1113
|
+
const { isValid } = await validateAll();
|
|
1114
|
+
if (!isValid) return;
|
|
1108
1115
|
fn(stateRef.current, e);
|
|
1109
1116
|
},
|
|
1110
1117
|
[validateAll]
|
|
@@ -1139,9 +1146,8 @@ function useForm(schema, {
|
|
|
1139
1146
|
const { onSubmit, ...rest } = props;
|
|
1140
1147
|
const handleSubmit = async (e) => {
|
|
1141
1148
|
e.preventDefault();
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
}
|
|
1149
|
+
const { isValid } = await validateAllRef.current();
|
|
1150
|
+
if (!isValid) return;
|
|
1145
1151
|
onFormSubmitPropRef.current?.(stateRef.current, e);
|
|
1146
1152
|
if (resetOnSubmitRef.current) {
|
|
1147
1153
|
handleReset({ keepValues: keepValuesPropRef.current });
|