remix-hook-form
Advanced tools
Comparing version 2.0.3 to 3.0.0
import * as react_hook_form from 'react-hook-form'; | ||
import { FieldValues, Resolver, FieldErrors, UseFormProps, SubmitHandler, SubmitErrorHandler, Path, RegisterOptions, UseFormReturn } from 'react-hook-form'; | ||
import { FieldValues, Resolver, FieldErrors, UseFormProps, SubmitHandler, SubmitErrorHandler, DeepPartial, Path, RegisterOptions, UseFormReturn } from 'react-hook-form'; | ||
import React from 'react'; | ||
import { SubmitFunction, FetcherWithComponents } from '@remix-run/react'; | ||
declare const getFormDataFromSearchParams: (request: Pick<Request, "url">) => Record<any, any>; | ||
declare const getFormDataFromSearchParams: (request: Pick<Request, "url">, preserveStringified?: boolean) => Record<any, any>; | ||
/** | ||
@@ -45,3 +45,3 @@ * Parses the data from an HTTP request and validates it against a schema. Works in both loaders and actions, in loaders it extracts the data from the search params. | ||
*/ | ||
declare const createFormData: <T extends FieldValues>(data: T, key?: string) => FormData; | ||
declare const createFormData: <T extends FieldValues>(data: T) => FormData; | ||
/** | ||
@@ -51,7 +51,7 @@ Parses the specified Request object's FormData to retrieve the data associated with the specified key. | ||
@param {Request} request - The Request object whose FormData is to be parsed. | ||
@param {string} [key="formData"] - The key of the data to be retrieved from the FormData. | ||
@param {boolean} [preserveStringified=false] - Whether to preserve stringified values or try to convert them | ||
@returns {Promise<T>} - A promise that resolves to the data of type T. | ||
@throws {Error} - If no data is found for the specified key, or if the retrieved data is not a string. | ||
*/ | ||
declare const parseFormData: <T extends unknown>(request: Request, key?: string) => Promise<T>; | ||
declare const parseFormData: <T extends unknown>(request: Request, preserveStringified?: boolean) => Promise<T>; | ||
@@ -70,2 +70,3 @@ type SubmitFunctionOptions = Parameters<SubmitFunction>[1]; | ||
handleSubmit: (e?: React.BaseSyntheticEvent<object, any, any> | undefined) => Promise<void>; | ||
reset: (values?: T | DeepPartial<T> | undefined) => void; | ||
register: (name: Path<T>, options?: (RegisterOptions<T> & { | ||
@@ -88,3 +89,3 @@ disableProgressiveEnhancement?: boolean | undefined; | ||
formState: { | ||
dirtyFields: Partial<Readonly<react_hook_form.DeepMap<react_hook_form.DeepPartial<T>, boolean>>>; | ||
dirtyFields: Partial<Readonly<react_hook_form.DeepMap<DeepPartial<T>, boolean>>>; | ||
isDirty: boolean; | ||
@@ -96,3 +97,3 @@ isSubmitSuccessful: boolean; | ||
isValidating: boolean; | ||
touchedFields: Partial<Readonly<react_hook_form.DeepMap<react_hook_form.DeepPartial<T>, boolean>>>; | ||
touchedFields: Partial<Readonly<react_hook_form.DeepMap<DeepPartial<T>, boolean>>>; | ||
submitCount: number; | ||
@@ -110,3 +111,2 @@ isLoading: boolean; | ||
resetField: react_hook_form.UseFormResetField<T>; | ||
reset: react_hook_form.UseFormReset<T>; | ||
unregister: react_hook_form.UseFormUnregister<T>; | ||
@@ -113,0 +113,0 @@ control: react_hook_form.Control<T, any>; |
// src/utilities/index.ts | ||
var generateFormData = (formData) => { | ||
var tryParseJSON = (jsonString) => { | ||
try { | ||
const json = JSON.parse(jsonString); | ||
return json; | ||
} catch (e) { | ||
return jsonString; | ||
} | ||
}; | ||
var generateFormData = (formData, preserveStringified = false) => { | ||
const outputObject = {}; | ||
for (const [key, value] of formData.entries()) { | ||
const data = preserveStringified ? value : tryParseJSON(value.toString()); | ||
const keyParts = key.split("."); | ||
@@ -21,9 +30,9 @@ let currentObject = outputObject; | ||
} | ||
currentObject[key2].push(value); | ||
currentObject[key2].push(data); | ||
} | ||
if (!lastKeyPartIsArray) { | ||
if (/^\d+$/.test(lastKeyPart)) { | ||
currentObject.push(value); | ||
currentObject.push(data); | ||
} else { | ||
currentObject[lastKeyPart] = value; | ||
currentObject[lastKeyPart] = data; | ||
} | ||
@@ -34,5 +43,5 @@ } | ||
}; | ||
var getFormDataFromSearchParams = (request) => { | ||
var getFormDataFromSearchParams = (request, preserveStringified = false) => { | ||
const searchParams = new URL(request.url).searchParams; | ||
return generateFormData(searchParams); | ||
return generateFormData(searchParams, preserveStringified); | ||
}; | ||
@@ -56,18 +65,27 @@ var isGet = (request) => request.method === "GET" || request.method === "get"; | ||
}; | ||
var createFormData = (data, key = "formData") => { | ||
var createFormData = (data) => { | ||
const formData = new FormData(); | ||
const finalData = JSON.stringify(data); | ||
formData.append(key, finalData); | ||
if (!data) { | ||
return formData; | ||
} | ||
Object.entries(data).map(([key, value]) => { | ||
if (Array.isArray(value)) { | ||
formData.append(key, JSON.stringify(value)); | ||
} else if (value instanceof File) { | ||
formData.append(key, value); | ||
} else if (typeof value === "object" && value !== null) { | ||
formData.append(key, JSON.stringify(value)); | ||
} else if (typeof value === "boolean") { | ||
formData.append(key, value.toString()); | ||
} else if (typeof value === "number") { | ||
formData.append(key, value.toString()); | ||
} else { | ||
formData.append(key, value); | ||
} | ||
}); | ||
return formData; | ||
}; | ||
var parseFormData = async (request, key = "formData") => { | ||
var parseFormData = async (request, preserveStringified = false) => { | ||
const formData = await request.formData(); | ||
const data = formData.get(key); | ||
if (!data) { | ||
return generateFormData(formData); | ||
} | ||
if (!(typeof data === "string")) { | ||
throw new Error("Data is not a string"); | ||
} | ||
return JSON.parse(data); | ||
return generateFormData(formData, preserveStringified); | ||
}; | ||
@@ -113,2 +131,3 @@ var mergeErrors = (frontendErrors, backendErrors, validKeys = [], depth = 0) => { | ||
var _a, _b, _c, _d; | ||
const [isSubmittedSuccessfully, setIsSubmittedSuccessfully] = React.useState(false); | ||
const actionSubmit = useSubmit(); | ||
@@ -122,3 +141,5 @@ const actionData = useActionData(); | ||
const onSubmit = (data2) => { | ||
submit(createFormData({ ...data2, ...submitData }), { | ||
setIsSubmittedSuccessfully(true); | ||
const formData = createFormData({ ...data2, ...submitData }); | ||
submit(formData, { | ||
method: "post", | ||
@@ -157,2 +178,6 @@ ...submitConfig | ||
), | ||
reset: (values2) => { | ||
setIsSubmittedSuccessfully(false); | ||
methods.reset(values2); | ||
}, | ||
register: (name, options) => { | ||
@@ -170,3 +195,3 @@ var _a2, _b2; | ||
isDirty, | ||
isSubmitSuccessful, | ||
isSubmitSuccessful: isSubmittedSuccessfully || isSubmitSuccessful, | ||
isSubmitted, | ||
@@ -173,0 +198,0 @@ isSubmitting: isSubmittingForm || isSubmitting, |
{ | ||
"name": "remix-hook-form", | ||
"version": "2.0.3", | ||
"version": "3.0.0", | ||
"description": "Utility wrapper around react-hook-form for use with Remix.run", | ||
@@ -35,3 +35,3 @@ "type": "module", | ||
"remix-dev": "npm run dev -w src/testing-app", | ||
"build:dev": "npm run build", | ||
"build:dev": "tsup src/index.ts --format cjs,esm --dts", | ||
"build:dev:watch": "npm run build -- --watch", | ||
@@ -77,2 +77,3 @@ "dev": "npm-run-all -s build:dev -p remix-dev build:dev:watch", | ||
"@hookform/resolvers": "^3.1.0", | ||
"@remix-run/node": "^2.0.0", | ||
"@remix-run/react": "^2.0.0", | ||
@@ -92,2 +93,3 @@ "@testing-library/react": "^14.0.0", | ||
"react-hook-form": "^7.43.9", | ||
"remix-development-tools": "^3.1.1", | ||
"rollup": "^3.20.2", | ||
@@ -94,0 +96,0 @@ "rollup-plugin-typescript2": "^0.34.1", |
@@ -161,3 +161,3 @@ # remix-hook-form | ||
createFormData is a utility function that can be used to create a FormData object from the data returned by the handleSubmit function from `react-hook-form`. It takes two arguments, first one is the `data` from the `handleSubmit` function and the second one is the key that the data will be stored in the FormData object. (default is `formData`). It returns a FormData object. | ||
createFormData is a utility function that can be used to create a FormData object from the data returned by the handleSubmit function from `react-hook-form`. It takes one argument, the `data` from the `handleSubmit` function and it converts everything it can to strings and appends files as well. It returns a FormData object. | ||
@@ -172,6 +172,4 @@ ```jsx | ||
onValid: data => { | ||
// This will create a FormData instance ready to be sent to the server, by default all your data is stored inside a key called `formData` but this behavior can be changed by passing a second argument to the function | ||
const formData = createFormData(data); | ||
// Example with a custom key | ||
const formDataCustom = createFormData(data, "yourkeyhere"); | ||
// This will create a FormData instance ready to be sent to the server, by default all your data is converted to a string before sent | ||
const formData = createFormData(data); | ||
// Do something with the formData | ||
@@ -191,3 +189,3 @@ } | ||
parseFormData is a utility function that can be used to parse the data submitted to the action by the handleSubmit function from `react-hook-form`. It takes two arguments, first one is the `request` submitted from the frontend and the second one is the key that the data will be stored in the FormData object. (default is `formData`). It returns an object that contains unvalidated `data` submitted from the frontend. | ||
parseFormData is a utility function that can be used to parse the data submitted to the action by the handleSubmit function from `react-hook-form`. It takes two arguments, first one is the `request` submitted from the frontend and the second one is `preserveStringified`, the form data you submit will be cast to strings because that is how form data works, when retrieving it you can either keep everything as strings or let the helper try to parse it back to original types (eg number to string), default is `false`. It returns an object that contains unvalidated `data` submitted from the frontend. | ||
@@ -201,4 +199,5 @@ | ||
const formData = await parseFormData(request); | ||
// If you used a custom key (eg. `yourkeyhere` from above you can extract like this) | ||
const formDataCustom = await parseFormData(request, "yourkeyhere"); | ||
// formData.age will be a number | ||
const formDataStringified = await parseFormData(request, true); | ||
// formDataStringified.age will be a string | ||
// Do something with the data | ||
@@ -205,0 +204,0 @@ }; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
47980
611
24
348