remix-validated-form 4.5.0-beta.0 → 4.5.1
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/.turbo/turbo-build.log +7 -7
- package/browser/ValidatedForm.js +10 -32
- package/browser/internal/hooks.d.ts +3 -1
- package/browser/internal/hooks.js +2 -0
- package/browser/internal/logic/nestedObjectToPathObject.d.ts +1 -0
- package/browser/internal/logic/nestedObjectToPathObject.js +47 -0
- package/browser/internal/state/arrayUtil.d.ts +12 -0
- package/browser/internal/state/arrayUtil.js +337 -0
- package/browser/internal/state/createFormStore.d.ts +4 -2
- package/browser/internal/state/createFormStore.js +21 -4
- package/browser/internal/state/fieldArray.d.ts +28 -0
- package/browser/internal/state/fieldArray.js +73 -0
- package/browser/internal/state/types.d.ts +0 -0
- package/browser/internal/state/types.js +0 -0
- package/browser/unreleased/formStateHooks.d.ts +12 -2
- package/browser/unreleased/formStateHooks.js +15 -2
- package/browser/userFacingFormContext.d.ts +12 -2
- package/browser/userFacingFormContext.js +5 -1
- package/dist/remix-validated-form.cjs.js +3 -3
- package/dist/remix-validated-form.cjs.js.map +1 -1
- package/dist/remix-validated-form.es.js +55 -37
- package/dist/remix-validated-form.es.js.map +1 -1
- package/dist/remix-validated-form.umd.js +3 -3
- package/dist/remix-validated-form.umd.js.map +1 -1
- package/dist/types/internal/hooks.d.ts +3 -1
- package/dist/types/internal/state/createFormStore.d.ts +4 -2
- package/dist/types/unreleased/formStateHooks.d.ts +12 -2
- package/dist/types/userFacingFormContext.d.ts +12 -2
- package/package.json +1 -1
- package/src/ValidatedForm.tsx +24 -42
- package/src/internal/hooks.ts +6 -0
- package/src/internal/state/createFormStore.ts +40 -6
- package/src/unreleased/formStateHooks.ts +32 -3
- package/src/userFacingFormContext.ts +22 -2
- package/src/validation/validation.test.ts +7 -7
|
@@ -1996,8 +1996,13 @@ const defaultFormState = {
|
|
|
1996
1996
|
setFormElement: noOp,
|
|
1997
1997
|
validateField: async () => null,
|
|
1998
1998
|
validate: async () => {
|
|
1999
|
+
throw new Error("Validate called before form was initialized.");
|
|
1999
2000
|
},
|
|
2000
|
-
|
|
2001
|
+
submit: async () => {
|
|
2002
|
+
throw new Error("Submit called before form was initialized.");
|
|
2003
|
+
},
|
|
2004
|
+
resetFormElement: noOp,
|
|
2005
|
+
getValues: () => new FormData()
|
|
2001
2006
|
};
|
|
2002
2007
|
const createFormState = (formId, set2, get2) => ({
|
|
2003
2008
|
isHydrated: false,
|
|
@@ -2067,9 +2072,20 @@ const createFormState = (formId, set2, get2) => ({
|
|
|
2067
2072
|
invariant(formElement, "Cannot find reference to form. This is probably a bug in remix-validated-form.");
|
|
2068
2073
|
const validator = (_a = get2().formProps) == null ? void 0 : _a.validator;
|
|
2069
2074
|
invariant(validator, "Cannot validator. This is probably a bug in remix-validated-form.");
|
|
2070
|
-
const
|
|
2071
|
-
if (error)
|
|
2072
|
-
get2().setFieldErrors(error.fieldErrors);
|
|
2075
|
+
const result = await validator.validate(new FormData(formElement));
|
|
2076
|
+
if (result.error)
|
|
2077
|
+
get2().setFieldErrors(result.error.fieldErrors);
|
|
2078
|
+
return result;
|
|
2079
|
+
},
|
|
2080
|
+
submit: () => {
|
|
2081
|
+
const formElement = get2().formElement;
|
|
2082
|
+
invariant(formElement, "Cannot find reference to form. This is probably a bug in remix-validated-form.");
|
|
2083
|
+
formElement.submit();
|
|
2084
|
+
},
|
|
2085
|
+
getValues: () => {
|
|
2086
|
+
const formElement = get2().formElement;
|
|
2087
|
+
invariant(formElement, "Cannot find reference to form. This is probably a bug in remix-validated-form.");
|
|
2088
|
+
return new FormData(formElement);
|
|
2073
2089
|
},
|
|
2074
2090
|
resetFormElement: () => {
|
|
2075
2091
|
var _a;
|
|
@@ -2205,6 +2221,7 @@ const useTouchedFields = (formId) => useFormStore(formId, (state) => state.touch
|
|
|
2205
2221
|
const useFieldErrors = (formId) => useFormStore(formId, (state) => state.fieldErrors);
|
|
2206
2222
|
const useSetFieldErrors = (formId) => useFormStore(formId, (state) => state.setFieldErrors);
|
|
2207
2223
|
const useResetFormElement = (formId) => useFormStore(formId, (state) => state.resetFormElement);
|
|
2224
|
+
const useSubmitForm = (formId) => useFormStore(formId, (state) => state.submit);
|
|
2208
2225
|
const useFormActionProp = (formId) => useFormStore(formId, (state) => {
|
|
2209
2226
|
var _a;
|
|
2210
2227
|
return (_a = state.formProps) == null ? void 0 : _a.action;
|
|
@@ -2213,6 +2230,7 @@ const useFormSubactionProp = (formId) => useFormStore(formId, (state) => {
|
|
|
2213
2230
|
var _a;
|
|
2214
2231
|
return (_a = state.formProps) == null ? void 0 : _a.subaction;
|
|
2215
2232
|
});
|
|
2233
|
+
const useFormValues = (formId) => useFormStore(formId, (state) => state.getValues);
|
|
2216
2234
|
const useControlledFieldValue = (context, field) => {
|
|
2217
2235
|
const value = useControlledFieldStore((state) => {
|
|
2218
2236
|
var _a;
|
|
@@ -2526,7 +2544,7 @@ const focusFirstInvalidInput = (fieldErrors, customFocusHandlers, formElement) =
|
|
|
2526
2544
|
var _a;
|
|
2527
2545
|
const namesInOrder = [...formElement.elements].map((el) => {
|
|
2528
2546
|
const input = el instanceof RadioNodeList ? el[0] : el;
|
|
2529
|
-
if (input instanceof
|
|
2547
|
+
if (input instanceof HTMLElement && "name" in input)
|
|
2530
2548
|
return input.name;
|
|
2531
2549
|
return null;
|
|
2532
2550
|
}).filter(nonNull).filter((name) => name in fieldErrors);
|
|
@@ -2548,8 +2566,8 @@ const focusFirstInvalidInput = (fieldErrors, customFocusHandlers, formElement) =
|
|
|
2548
2566
|
break;
|
|
2549
2567
|
}
|
|
2550
2568
|
}
|
|
2551
|
-
if (elem instanceof
|
|
2552
|
-
if (elem.type === "hidden") {
|
|
2569
|
+
if (elem instanceof HTMLElement) {
|
|
2570
|
+
if (elem instanceof HTMLInputElement && elem.type === "hidden") {
|
|
2553
2571
|
continue;
|
|
2554
2572
|
}
|
|
2555
2573
|
elem.focus();
|
|
@@ -2688,25 +2706,7 @@ function ValidatedForm(_a) {
|
|
|
2688
2706
|
useSubmitComplete(hasActiveSubmission, () => {
|
|
2689
2707
|
endSubmit();
|
|
2690
2708
|
});
|
|
2691
|
-
|
|
2692
|
-
useEffect(() => {
|
|
2693
|
-
let form = formRef.current;
|
|
2694
|
-
if (!form)
|
|
2695
|
-
return;
|
|
2696
|
-
function handleClick(event) {
|
|
2697
|
-
if (!(event.target instanceof HTMLElement))
|
|
2698
|
-
return;
|
|
2699
|
-
let submitButton = event.target.closest("button,input[type=submit]");
|
|
2700
|
-
if (submitButton && submitButton.form === form && submitButton.type === "submit") {
|
|
2701
|
-
clickedButtonRef.current = submitButton;
|
|
2702
|
-
}
|
|
2703
|
-
}
|
|
2704
|
-
window.addEventListener("click", handleClick, { capture: true });
|
|
2705
|
-
return () => {
|
|
2706
|
-
window.removeEventListener("click", handleClick, { capture: true });
|
|
2707
|
-
};
|
|
2708
|
-
}, []);
|
|
2709
|
-
const handleSubmit = async (e2) => {
|
|
2709
|
+
const handleSubmit = async (e2, target, nativeEvent) => {
|
|
2710
2710
|
startSubmit();
|
|
2711
2711
|
const result = await validator.validate(getDataFromForm(e2.currentTarget));
|
|
2712
2712
|
if (result.error) {
|
|
@@ -2722,12 +2722,11 @@ function ValidatedForm(_a) {
|
|
|
2722
2722
|
endSubmit();
|
|
2723
2723
|
return;
|
|
2724
2724
|
}
|
|
2725
|
-
const submitter =
|
|
2725
|
+
const submitter = nativeEvent.submitter;
|
|
2726
2726
|
if (fetcher)
|
|
2727
2727
|
fetcher.submit(submitter || e2.currentTarget);
|
|
2728
2728
|
else
|
|
2729
|
-
submit(submitter ||
|
|
2730
|
-
clickedButtonRef.current = null;
|
|
2729
|
+
submit(submitter || target, { replace });
|
|
2731
2730
|
}
|
|
2732
2731
|
};
|
|
2733
2732
|
return /* @__PURE__ */ React.createElement(Form$1, __spreadProps(__spreadValues({
|
|
@@ -2739,7 +2738,7 @@ function ValidatedForm(_a) {
|
|
|
2739
2738
|
replace,
|
|
2740
2739
|
onSubmit: (e2) => {
|
|
2741
2740
|
e2.preventDefault();
|
|
2742
|
-
handleSubmit(e2);
|
|
2741
|
+
handleSubmit(e2, e2.currentTarget, e2.nativeEvent);
|
|
2743
2742
|
},
|
|
2744
2743
|
onReset: (event) => {
|
|
2745
2744
|
onReset == null ? void 0 : onReset(event);
|
|
@@ -2750,7 +2749,7 @@ function ValidatedForm(_a) {
|
|
|
2750
2749
|
}
|
|
2751
2750
|
}), /* @__PURE__ */ React.createElement(InternalFormContext.Provider, {
|
|
2752
2751
|
value: contextValue
|
|
2753
|
-
}, /* @__PURE__ */ React.createElement(FormResetter, {
|
|
2752
|
+
}, /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(FormResetter, {
|
|
2754
2753
|
formRef,
|
|
2755
2754
|
resetAfterSubmit
|
|
2756
2755
|
}), subaction && /* @__PURE__ */ React.createElement("input", {
|
|
@@ -2761,7 +2760,7 @@ function ValidatedForm(_a) {
|
|
|
2761
2760
|
type: "hidden",
|
|
2762
2761
|
value: id,
|
|
2763
2762
|
name: FORM_ID_FIELD
|
|
2764
|
-
}), children));
|
|
2763
|
+
}), children)));
|
|
2765
2764
|
}
|
|
2766
2765
|
var baseSet = _baseSet;
|
|
2767
2766
|
function set(object, path, value) {
|
|
@@ -2847,14 +2846,27 @@ const useFormHelpers = (formId) => {
|
|
|
2847
2846
|
const clearError = useClearError(formContext);
|
|
2848
2847
|
const setFieldErrors = useSetFieldErrors(formContext.formId);
|
|
2849
2848
|
const reset = useResetFormElement(formContext.formId);
|
|
2849
|
+
const submit = useSubmitForm(formContext.formId);
|
|
2850
|
+
const getValues = useFormValues(formContext.formId);
|
|
2850
2851
|
return useMemo(() => ({
|
|
2851
2852
|
setTouched,
|
|
2852
2853
|
validateField,
|
|
2853
2854
|
clearError,
|
|
2854
2855
|
validate,
|
|
2855
2856
|
clearAllErrors: () => setFieldErrors({}),
|
|
2856
|
-
reset
|
|
2857
|
-
|
|
2857
|
+
reset,
|
|
2858
|
+
submit,
|
|
2859
|
+
getValues
|
|
2860
|
+
}), [
|
|
2861
|
+
clearError,
|
|
2862
|
+
reset,
|
|
2863
|
+
setFieldErrors,
|
|
2864
|
+
setTouched,
|
|
2865
|
+
submit,
|
|
2866
|
+
validate,
|
|
2867
|
+
validateField,
|
|
2868
|
+
getValues
|
|
2869
|
+
]);
|
|
2858
2870
|
};
|
|
2859
2871
|
const useFormContext = (formId) => {
|
|
2860
2872
|
const context = useInternalFormContext(formId, "useFormContext");
|
|
@@ -2865,7 +2877,9 @@ const useFormContext = (formId) => {
|
|
|
2865
2877
|
validateField,
|
|
2866
2878
|
clearAllErrors,
|
|
2867
2879
|
validate,
|
|
2868
|
-
reset
|
|
2880
|
+
reset,
|
|
2881
|
+
submit,
|
|
2882
|
+
getValues
|
|
2869
2883
|
} = useFormHelpers(formId);
|
|
2870
2884
|
const registerReceiveFocus = useRegisterReceiveFocus(context.formId);
|
|
2871
2885
|
const clearError = useCallback((...names) => {
|
|
@@ -2880,7 +2894,9 @@ const useFormContext = (formId) => {
|
|
|
2880
2894
|
registerReceiveFocus,
|
|
2881
2895
|
clearAllErrors,
|
|
2882
2896
|
validate,
|
|
2883
|
-
reset
|
|
2897
|
+
reset,
|
|
2898
|
+
submit,
|
|
2899
|
+
getValues
|
|
2884
2900
|
}), [
|
|
2885
2901
|
clearAllErrors,
|
|
2886
2902
|
clearError,
|
|
@@ -2888,8 +2904,10 @@ const useFormContext = (formId) => {
|
|
|
2888
2904
|
reset,
|
|
2889
2905
|
setTouched,
|
|
2890
2906
|
state,
|
|
2907
|
+
submit,
|
|
2891
2908
|
validate,
|
|
2892
|
-
validateField
|
|
2909
|
+
validateField,
|
|
2910
|
+
getValues
|
|
2893
2911
|
]);
|
|
2894
2912
|
};
|
|
2895
2913
|
export { ValidatedForm, createValidator, setFormDefaults, useControlField, useField, useFormContext, useIsSubmitting, useIsValid, useUpdateControlledField, validationError };
|