@juantroconisf/lib 11.5.0 → 11.7.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 +180 -433
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +151 -152
- package/dist/index.mjs +151 -152
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -44,11 +44,13 @@ function handleNestedChange({
|
|
|
44
44
|
value,
|
|
45
45
|
hasNestedValues = false
|
|
46
46
|
}) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
const isNested = hasNestedValues || String(id).includes(".");
|
|
48
|
+
if (!isNested) return { ...state, [id]: value };
|
|
49
|
+
const keys = String(id).split(".");
|
|
50
|
+
const newState = { ...state };
|
|
51
|
+
let current = newState;
|
|
52
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
53
|
+
const key = keys[i];
|
|
52
54
|
if (Array.isArray(current[key])) {
|
|
53
55
|
current[key] = [...current[key]];
|
|
54
56
|
} else {
|
|
@@ -56,8 +58,8 @@ function handleNestedChange({
|
|
|
56
58
|
}
|
|
57
59
|
current = current[key];
|
|
58
60
|
}
|
|
59
|
-
current[
|
|
60
|
-
return
|
|
61
|
+
current[keys[keys.length - 1]] = value;
|
|
62
|
+
return newState;
|
|
61
63
|
}
|
|
62
64
|
function handleArrayItemChange({
|
|
63
65
|
state,
|
|
@@ -98,21 +100,6 @@ function removeCompositeKeysByPrefix(map, prefix) {
|
|
|
98
100
|
}
|
|
99
101
|
return result;
|
|
100
102
|
}
|
|
101
|
-
function setNestedValue(state, dotPath, value) {
|
|
102
|
-
const keys = dotPath.split(".");
|
|
103
|
-
const copy = { ...state };
|
|
104
|
-
let current = copy;
|
|
105
|
-
for (let i = 0; i < keys.length - 1; i++) {
|
|
106
|
-
if (Array.isArray(current[keys[i]])) {
|
|
107
|
-
current[keys[i]] = [...current[keys[i]]];
|
|
108
|
-
} else {
|
|
109
|
-
current[keys[i]] = { ...current[keys[i]] };
|
|
110
|
-
}
|
|
111
|
-
current = current[keys[i]];
|
|
112
|
-
}
|
|
113
|
-
current[keys[keys.length - 1]] = value;
|
|
114
|
-
return copy;
|
|
115
|
-
}
|
|
116
103
|
|
|
117
104
|
// src/hooks/useForm.tsx
|
|
118
105
|
var import_react3 = require("@heroui/react");
|
|
@@ -407,7 +394,7 @@ function useForm(schema, {
|
|
|
407
394
|
}, [schema]);
|
|
408
395
|
const [state, setState] = (0, import_react2.useState)(initialState), [metadata, setMetadata] = (0, import_react2.useState)(/* @__PURE__ */ new Map());
|
|
409
396
|
useComponentLanguage();
|
|
410
|
-
const stateRef = (0, import_react2.useRef)(state), metadataRef = (0, import_react2.useRef)(metadata);
|
|
397
|
+
const stateRef = (0, import_react2.useRef)(state), metadataRef = (0, import_react2.useRef)(metadata), propsCache = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
|
|
411
398
|
stateRef.current = state;
|
|
412
399
|
metadataRef.current = metadata;
|
|
413
400
|
const indexMap = (0, import_react2.useMemo)(() => {
|
|
@@ -468,14 +455,7 @@ function useForm(schema, {
|
|
|
468
455
|
const runValidation = (0, import_react2.useCallback)(
|
|
469
456
|
(ruleDef, value, compositeKey, realPath, fullState) => {
|
|
470
457
|
if ((0, import_yup2.isSchema)(ruleDef)) {
|
|
471
|
-
|
|
472
|
-
if (validationSchema && realPath && fullState !== void 0) {
|
|
473
|
-
validationSchema.validateSyncAt(realPath, fullState);
|
|
474
|
-
} else {
|
|
475
|
-
ruleDef.validateSync(value);
|
|
476
|
-
}
|
|
477
|
-
return false;
|
|
478
|
-
} catch (err) {
|
|
458
|
+
const updateMetadata = (err) => {
|
|
479
459
|
const error = {
|
|
480
460
|
isInvalid: true,
|
|
481
461
|
errorMessage: err.message || "Invalid"
|
|
@@ -490,7 +470,32 @@ function useForm(schema, {
|
|
|
490
470
|
newMap.set(compositeKey, { ...currentMeta, ...error });
|
|
491
471
|
return newMap;
|
|
492
472
|
});
|
|
493
|
-
|
|
473
|
+
};
|
|
474
|
+
try {
|
|
475
|
+
if (validationSchema && realPath && fullState !== void 0) {
|
|
476
|
+
validationSchema.validateSyncAt(realPath, fullState);
|
|
477
|
+
} else {
|
|
478
|
+
ruleDef.validateSync(value);
|
|
479
|
+
}
|
|
480
|
+
return false;
|
|
481
|
+
} catch (err) {
|
|
482
|
+
if (err.name === "ValidationError") {
|
|
483
|
+
updateMetadata(err);
|
|
484
|
+
return true;
|
|
485
|
+
}
|
|
486
|
+
return (async () => {
|
|
487
|
+
try {
|
|
488
|
+
if (validationSchema && realPath && fullState !== void 0) {
|
|
489
|
+
await validationSchema.validateAt(realPath, fullState);
|
|
490
|
+
} else {
|
|
491
|
+
await ruleDef.validate(value);
|
|
492
|
+
}
|
|
493
|
+
return false;
|
|
494
|
+
} catch (asyncErr) {
|
|
495
|
+
updateMetadata(asyncErr);
|
|
496
|
+
return true;
|
|
497
|
+
}
|
|
498
|
+
})();
|
|
494
499
|
}
|
|
495
500
|
}
|
|
496
501
|
return false;
|
|
@@ -501,35 +506,46 @@ function useForm(schema, {
|
|
|
501
506
|
(compositeKey, fieldPath, realPath, value, fullState) => {
|
|
502
507
|
let schemaRule = getRule(fieldPath, validationSchema);
|
|
503
508
|
if (schemaRule) {
|
|
504
|
-
|
|
505
|
-
|
|
509
|
+
const result = runValidation(
|
|
510
|
+
schemaRule,
|
|
511
|
+
value,
|
|
512
|
+
compositeKey,
|
|
513
|
+
realPath,
|
|
514
|
+
fullState
|
|
515
|
+
);
|
|
516
|
+
if (result === true) return true;
|
|
517
|
+
if (result instanceof Promise) {
|
|
518
|
+
return result.then((res) => {
|
|
519
|
+
if (!res) clearError();
|
|
520
|
+
return res;
|
|
521
|
+
});
|
|
522
|
+
}
|
|
506
523
|
}
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
524
|
+
function clearError() {
|
|
525
|
+
setMetadata((prev) => {
|
|
526
|
+
const newMap = new Map(prev);
|
|
527
|
+
const currentMeta = newMap.get(compositeKey) || {
|
|
528
|
+
isTouched: false,
|
|
529
|
+
isInvalid: false,
|
|
530
|
+
errorMessage: ""
|
|
531
|
+
};
|
|
532
|
+
newMap.set(compositeKey, {
|
|
533
|
+
...currentMeta,
|
|
534
|
+
isInvalid: false,
|
|
535
|
+
errorMessage: ""
|
|
536
|
+
});
|
|
537
|
+
return newMap;
|
|
518
538
|
});
|
|
519
|
-
|
|
520
|
-
|
|
539
|
+
}
|
|
540
|
+
clearError();
|
|
521
541
|
return false;
|
|
522
542
|
},
|
|
523
543
|
[getRule, runValidation, validationSchema]
|
|
524
544
|
);
|
|
525
545
|
const validateAll = (0, import_react2.useCallback)(() => {
|
|
526
546
|
if (!validationSchema) return false;
|
|
527
|
-
let hasError = false;
|
|
528
547
|
const newMetadata = new Map(metadataRef.current);
|
|
529
|
-
|
|
530
|
-
validationSchema.validateSync(state, { abortEarly: false });
|
|
531
|
-
} catch (err) {
|
|
532
|
-
hasError = true;
|
|
548
|
+
const handleErrors = (err) => {
|
|
533
549
|
if (err.inner) {
|
|
534
550
|
err.inner.forEach((validationError) => {
|
|
535
551
|
const yupPath = validationError.path;
|
|
@@ -570,9 +586,26 @@ function useForm(schema, {
|
|
|
570
586
|
});
|
|
571
587
|
});
|
|
572
588
|
}
|
|
589
|
+
setMetadata(newMetadata);
|
|
590
|
+
return true;
|
|
591
|
+
};
|
|
592
|
+
try {
|
|
593
|
+
validationSchema.validateSync(state, { abortEarly: false });
|
|
594
|
+
} catch (err) {
|
|
595
|
+
if (err.name === "ValidationError") {
|
|
596
|
+
return handleErrors(err);
|
|
597
|
+
}
|
|
598
|
+
return (async () => {
|
|
599
|
+
try {
|
|
600
|
+
await validationSchema.validate(state, { abortEarly: false });
|
|
601
|
+
return false;
|
|
602
|
+
} catch (asyncErr) {
|
|
603
|
+
return handleErrors(asyncErr);
|
|
604
|
+
}
|
|
605
|
+
})();
|
|
573
606
|
}
|
|
574
607
|
setMetadata(newMetadata);
|
|
575
|
-
return
|
|
608
|
+
return false;
|
|
576
609
|
}, [validationSchema, state, arrayIdentifiers]);
|
|
577
610
|
const handleFieldChange = (0, import_react2.useCallback)(
|
|
578
611
|
(resolution, newValue) => {
|
|
@@ -657,7 +690,12 @@ function useForm(schema, {
|
|
|
657
690
|
nextState = { ...nextState, [parentKey]: parentArr };
|
|
658
691
|
}
|
|
659
692
|
} else if (type === "deep" /* Deep */) {
|
|
660
|
-
nextState =
|
|
693
|
+
nextState = handleNestedChange({
|
|
694
|
+
state: nextState,
|
|
695
|
+
id: resolution.realPath,
|
|
696
|
+
value: finalValue,
|
|
697
|
+
hasNestedValues: true
|
|
698
|
+
});
|
|
661
699
|
}
|
|
662
700
|
setState(nextState);
|
|
663
701
|
validateField(
|
|
@@ -713,8 +751,8 @@ function useForm(schema, {
|
|
|
713
751
|
[validateField, getRule, validationSchema]
|
|
714
752
|
);
|
|
715
753
|
const on = (0, import_react2.useMemo)(
|
|
716
|
-
() =>
|
|
717
|
-
|
|
754
|
+
() => {
|
|
755
|
+
const getCachedProps = (method, args, factory) => {
|
|
718
756
|
const data = resolveFieldData(
|
|
719
757
|
args,
|
|
720
758
|
stateRef.current,
|
|
@@ -724,117 +762,78 @@ function useForm(schema, {
|
|
|
724
762
|
validationSchema
|
|
725
763
|
);
|
|
726
764
|
if (!data) return {};
|
|
727
|
-
|
|
765
|
+
const meta = metadataRef.current.get(data.compositeKey);
|
|
766
|
+
const deps = JSON.stringify([
|
|
767
|
+
data.value,
|
|
768
|
+
meta?.isInvalid,
|
|
769
|
+
meta?.errorMessage,
|
|
770
|
+
meta?.isTouched
|
|
771
|
+
]);
|
|
772
|
+
const cacheKey = `${method}:${JSON.stringify(args)}`;
|
|
773
|
+
const cached = propsCache.current.get(cacheKey);
|
|
774
|
+
if (cached && cached.deps === deps) {
|
|
775
|
+
return cached.props;
|
|
776
|
+
}
|
|
777
|
+
const props = factory(data);
|
|
778
|
+
propsCache.current.set(cacheKey, { props, deps });
|
|
779
|
+
return props;
|
|
780
|
+
};
|
|
781
|
+
return {
|
|
782
|
+
input: (...args) => getCachedProps("input", args, (data) => ({
|
|
728
783
|
...createHandlers(data),
|
|
729
784
|
value: data.value === null || data.value === void 0 ? "" : typeof data.value === "boolean" ? data.value : String(data.value),
|
|
730
785
|
onValueChange: (v) => handleFieldChange(data, v)
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
return {
|
|
745
|
-
...createHandlers(data),
|
|
746
|
-
selectedKeys: data.value === null || data.value === void 0 ? [] : isArray ? data.value.map(String) : [String(data.value)],
|
|
747
|
-
onSelectionChange: (v) => {
|
|
748
|
-
const fixed = typeof v === "string" || v === null ? v : isArray ? Array.from(v) : Array.from(v)[0] ?? null;
|
|
749
|
-
handleFieldChange(data, fixed);
|
|
750
|
-
}
|
|
751
|
-
};
|
|
752
|
-
},
|
|
753
|
-
autocomplete: (...args) => {
|
|
754
|
-
const data = resolveFieldData(
|
|
755
|
-
args,
|
|
756
|
-
stateRef.current,
|
|
757
|
-
getIndex,
|
|
758
|
-
getNestedValue,
|
|
759
|
-
getRule,
|
|
760
|
-
validationSchema
|
|
761
|
-
);
|
|
762
|
-
if (!data) return {};
|
|
763
|
-
return {
|
|
786
|
+
})),
|
|
787
|
+
select: (...args) => getCachedProps("select", args, (data) => {
|
|
788
|
+
const isArray = Array.isArray(data.value);
|
|
789
|
+
return {
|
|
790
|
+
...createHandlers(data),
|
|
791
|
+
selectedKeys: data.value === null || data.value === void 0 ? [] : isArray ? data.value.map(String) : [String(data.value)],
|
|
792
|
+
onSelectionChange: (v) => {
|
|
793
|
+
const fixed = typeof v === "string" || v === null ? v : isArray ? Array.from(v) : Array.from(v)[0] ?? null;
|
|
794
|
+
handleFieldChange(data, fixed);
|
|
795
|
+
}
|
|
796
|
+
};
|
|
797
|
+
}),
|
|
798
|
+
autocomplete: (...args) => getCachedProps("autocomplete", args, (data) => ({
|
|
764
799
|
...createHandlers(data),
|
|
765
800
|
selectedKey: data.value === null || data.value === void 0 ? null : String(data.value),
|
|
766
801
|
onSelectionChange: (v) => {
|
|
767
802
|
const fixed = typeof v === "string" || v === null || v === void 0 ? v : String(v);
|
|
768
803
|
handleFieldChange(data, fixed);
|
|
769
804
|
}
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
numberInput: (...args) => {
|
|
773
|
-
const data = resolveFieldData(
|
|
774
|
-
args,
|
|
775
|
-
stateRef.current,
|
|
776
|
-
getIndex,
|
|
777
|
-
getNestedValue,
|
|
778
|
-
getRule,
|
|
779
|
-
validationSchema
|
|
780
|
-
);
|
|
781
|
-
if (!data) return {};
|
|
782
|
-
return {
|
|
805
|
+
})),
|
|
806
|
+
numberInput: (...args) => getCachedProps("numberInput", args, (data) => ({
|
|
783
807
|
...createHandlers(data),
|
|
784
808
|
value: data.value === null || data.value === void 0 ? "" : String(data.value),
|
|
785
809
|
onValueChange: (v) => handleFieldChange(data, v)
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
checkbox: (...args) => {
|
|
789
|
-
const data = resolveFieldData(
|
|
790
|
-
args,
|
|
791
|
-
stateRef.current,
|
|
792
|
-
getIndex,
|
|
793
|
-
getNestedValue,
|
|
794
|
-
getRule,
|
|
795
|
-
validationSchema
|
|
796
|
-
);
|
|
797
|
-
if (!data) return {};
|
|
798
|
-
return {
|
|
810
|
+
})),
|
|
811
|
+
checkbox: (...args) => getCachedProps("checkbox", args, (data) => ({
|
|
799
812
|
...createHandlers(data),
|
|
800
813
|
isSelected: Boolean(data.value),
|
|
801
814
|
onValueChange: (v) => handleFieldChange(data, v)
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
switch: (...args) => {
|
|
805
|
-
const data = resolveFieldData(
|
|
806
|
-
args,
|
|
807
|
-
stateRef.current,
|
|
808
|
-
getIndex,
|
|
809
|
-
getNestedValue,
|
|
810
|
-
getRule,
|
|
811
|
-
validationSchema
|
|
812
|
-
);
|
|
813
|
-
if (!data) return {};
|
|
814
|
-
return {
|
|
815
|
+
})),
|
|
816
|
+
switch: (...args) => getCachedProps("switch", args, (data) => ({
|
|
815
817
|
...createHandlers(data),
|
|
816
818
|
isSelected: Boolean(data.value),
|
|
817
819
|
onValueChange: (v) => handleFieldChange(data, v)
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
radio: (...args) => {
|
|
821
|
-
const data = resolveFieldData(
|
|
822
|
-
args,
|
|
823
|
-
stateRef.current,
|
|
824
|
-
getIndex,
|
|
825
|
-
getNestedValue,
|
|
826
|
-
getRule,
|
|
827
|
-
validationSchema
|
|
828
|
-
);
|
|
829
|
-
if (!data) return {};
|
|
830
|
-
return {
|
|
820
|
+
})),
|
|
821
|
+
radio: (...args) => getCachedProps("radio", args, (data) => ({
|
|
831
822
|
...createHandlers(data),
|
|
832
823
|
value: data.value === null || data.value === void 0 ? "" : String(data.value),
|
|
833
824
|
onValueChange: (v) => handleFieldChange(data, v)
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
[
|
|
825
|
+
}))
|
|
826
|
+
};
|
|
827
|
+
},
|
|
828
|
+
[
|
|
829
|
+
createHandlers,
|
|
830
|
+
getIndex,
|
|
831
|
+
handleFieldChange,
|
|
832
|
+
getRule,
|
|
833
|
+
validationSchema,
|
|
834
|
+
state,
|
|
835
|
+
metadata
|
|
836
|
+
]
|
|
838
837
|
);
|
|
839
838
|
const helpers = (0, import_react2.useMemo)(
|
|
840
839
|
() => ({
|
|
@@ -851,7 +850,7 @@ function useForm(schema, {
|
|
|
851
850
|
});
|
|
852
851
|
});
|
|
853
852
|
},
|
|
854
|
-
|
|
853
|
+
removeItemByIndex: (arrayKey, index) => {
|
|
855
854
|
const currentArr = getNestedValue(stateRef.current, arrayKey) || [];
|
|
856
855
|
const item = currentArr[index];
|
|
857
856
|
const idKey = arrayIdentifiers?.[arrayKey] || "id";
|
|
@@ -951,7 +950,7 @@ function useForm(schema, {
|
|
|
951
950
|
return getNestedValue(stateRef.current, arrayKey)[index];
|
|
952
951
|
}
|
|
953
952
|
}),
|
|
954
|
-
[getIndex, arrayIdentifiers]
|
|
953
|
+
[getIndex, arrayIdentifiers, state, metadata]
|
|
955
954
|
);
|
|
956
955
|
const onBlur = (0, import_react2.useCallback)(
|
|
957
956
|
(id) => {
|
|
@@ -1035,9 +1034,9 @@ function useForm(schema, {
|
|
|
1035
1034
|
[getIndex, handleFieldChange, getRule, validationSchema]
|
|
1036
1035
|
);
|
|
1037
1036
|
const onFormSubmit = (0, import_react2.useCallback)(
|
|
1038
|
-
(fn) => (e) => {
|
|
1037
|
+
(fn) => async (e) => {
|
|
1039
1038
|
e.preventDefault();
|
|
1040
|
-
if (validateAll()) return;
|
|
1039
|
+
if (await validateAll()) return;
|
|
1041
1040
|
fn(stateRef.current, e);
|
|
1042
1041
|
},
|
|
1043
1042
|
[validateAll]
|
|
@@ -1070,9 +1069,9 @@ function useForm(schema, {
|
|
|
1070
1069
|
const ControlledForm = (0, import_react2.useMemo)(() => {
|
|
1071
1070
|
return (props) => {
|
|
1072
1071
|
const { onSubmit, ...rest } = props;
|
|
1073
|
-
const handleSubmit = (e) => {
|
|
1072
|
+
const handleSubmit = async (e) => {
|
|
1074
1073
|
e.preventDefault();
|
|
1075
|
-
if (validateAllRef.current()) {
|
|
1074
|
+
if (await validateAllRef.current()) {
|
|
1076
1075
|
return;
|
|
1077
1076
|
}
|
|
1078
1077
|
onFormSubmitPropRef.current?.(stateRef.current, e);
|