Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

remix-hook-form

Package Overview
Dependencies
Maintainers
1
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

remix-hook-form - npm Package Compare versions

Comparing version 1.0.8 to 1.1.0

17

dist/hook/index.d.ts
import React from "react";
import { SubmitFunction } from "@remix-run/react";
import { SubmitErrorHandler, SubmitHandler } from "react-hook-form";
import type { FieldValues, UseFormProps, UseFormReturn } from "react-hook-form/dist/types";
import type { FieldValues, Path, RegisterOptions, UseFormProps, UseFormReturn } from "react-hook-form/dist/types";
export type SubmitFunctionOptions = Parameters<SubmitFunction>[1];

@@ -16,2 +16,16 @@ interface UseRemixFormOptions<T extends FieldValues> extends UseFormProps<T> {

handleSubmit: (e?: React.BaseSyntheticEvent<object, any, any> | undefined) => Promise<void>;
register: (name: Path<T>, options: RegisterOptions<T>) => {
defaultValue: any;
onChange: import("react-hook-form").ChangeHandler;
onBlur: import("react-hook-form").ChangeHandler;
ref: import("react-hook-form").RefCallBack;
name: Path<T>;
min?: string | number | undefined;
max?: string | number | undefined;
maxLength?: number | undefined;
minLength?: number | undefined;
pattern?: string | undefined;
required?: boolean | undefined;
disabled?: boolean | undefined;
};
formState: {

@@ -41,3 +55,2 @@ dirtyFields: Partial<Readonly<import("react-hook-form").DeepMap<import("react-hook-form").DeepPartial<T>, boolean>>>;

control: import("react-hook-form").Control<T, any>;
register: import("react-hook-form").UseFormRegister<T>;
setFocus: import("react-hook-form").UseFormSetFocus<T>;

@@ -44,0 +57,0 @@ };

139

dist/index.js

@@ -1,74 +0,81 @@

import V from "react";
import { useSubmit as $, useActionData as j } from "@remix-run/react";
import { useForm as k, FormProvider as R, useFormContext as A } from "react-hook-form";
const u = (t) => {
const e = {};
for (const [o, a] of t.entries()) {
const i = o.split(".");
let r = e;
for (let s = 0; s < i.length - 1; s++) {
const c = i[s];
r[c] || (r[c] = /^\d+$/.test(i[s + 1]) ? [] : {}), r = r[c];
import k from "react";
import { useSubmit as R, useActionData as A } from "@remix-run/react";
import { useForm as _, FormProvider as C, useFormContext as I } from "react-hook-form";
const f = (t) => {
const o = {};
for (const [e, a] of t.entries()) {
const n = e.split(".");
let r = o;
for (let i = 0; i < n.length - 1; i++) {
const u = n[i];
r[u] || (r[u] = /^\d+$/.test(n[i + 1]) ? [] : {}), r = r[u];
}
const n = i[i.length - 1], m = /\[\d*\]$|\[\]$/.test(n);
if (m) {
const s = n.replace(/\[\d*\]$|\[\]$/, "");
r[s] || (r[s] = []), r[s].push(a);
const c = n[n.length - 1], s = /\[\d*\]$|\[\]$/.test(c);
if (s) {
const i = c.replace(/\[\d*\]$|\[\]$/, "");
r[i] || (r[i] = []), r[i].push(a);
}
m || (/^\d+$/.test(n) ? r.push(a) : r[n] = a);
s || (/^\d+$/.test(c) ? r.push(a) : r[c] = a);
}
return e;
}, C = (t) => {
const e = new URL(t.url).searchParams;
return u(e);
}, I = (t) => t.method === "GET" || t.method === "get", _ = async (t, e) => {
const o = I(t) ? C(t) : await J(t);
return await N(o, e);
}, N = async (t, e) => {
const { errors: o, values: a } = await e(t, {}, { shouldUseNativeValidation: !1, fields: {} });
return Object.keys(o).length > 0 ? { errors: o, data: void 0 } : { errors: void 0, data: a };
}, G = (t, e = "formData") => {
const o = new FormData(), a = JSON.stringify(t);
return o.append(e, a), o;
}, J = async (t, e = "formData") => {
const o = await t.formData(), a = o.get(e);
return o;
}, N = (t) => {
const o = new URL(t.url).searchParams;
return f(o);
}, G = (t) => t.method === "GET" || t.method === "get", B = async (t, o) => {
const e = G(t) ? N(t) : await L(t);
return { ...await J(e, o), receivedValues: e };
}, J = async (t, o) => {
const { errors: e, values: a } = await o(t, {}, { shouldUseNativeValidation: !1, fields: {} });
return Object.keys(e).length > 0 ? { errors: e, data: void 0 } : { errors: void 0, data: a };
}, K = (t, o = "formData") => {
const e = new FormData(), a = JSON.stringify(t);
return e.append(o, a), e;
}, L = async (t, o = "formData") => {
const e = await t.formData(), a = e.get(o);
if (!a)
return u(o);
return f(e);
if (typeof a != "string")
throw new Error("Data is not a string");
return JSON.parse(a);
}, l = (t, e) => {
if (!e)
}, v = (t, o) => {
if (!o)
return t;
for (const [o, a] of Object.entries(e))
typeof a == "object" && !Array.isArray(a) ? (t[o] || (t[o] = {}), l(t[o], a)) : a && (t[o] = a);
for (const [e, a] of Object.entries(o))
typeof a == "object" && !Array.isArray(a) ? (t[e] || (t[e] = {}), v(t[e], a)) : a && (t[e] = a);
return t;
}, T = ({ submitHandlers: t, submitConfig: e, submitData: o, ...a }) => {
var i, r;
const n = $(), m = j(), s = k(a), c = (x) => {
n(G({ ...x, ...o }), {
}, M = ({ submitHandlers: t, submitConfig: o, submitData: e, ...a }) => {
var n, r;
const c = R(), s = A(), i = _(a), u = (l) => {
c(K({ ...l, ...e }), {
method: "post",
...e
...o
});
}, d = () => {
}, f = s.formState, { dirtyFields: h, isDirty: v, isSubmitSuccessful: y, isSubmitted: p, isSubmitting: g, isValid: D, isValidating: F, touchedFields: S, submitCount: b, errors: P, isLoading: w } = f, O = l(P, m);
}, h = () => {
}, y = i.formState, { dirtyFields: g, isDirty: p, isSubmitSuccessful: D, isSubmitted: F, isSubmitting: S, isValid: b, isValidating: P, touchedFields: V, submitCount: w, errors: O, isLoading: x } = y, $ = v(O, s != null && s.errors ? s.errors : s);
return {
...s,
handleSubmit: s.handleSubmit((i = t == null ? void 0 : t.onValid) !== null && i !== void 0 ? i : c, (r = t == null ? void 0 : t.onInvalid) !== null && r !== void 0 ? r : d),
...i,
handleSubmit: i.handleSubmit((n = t == null ? void 0 : t.onValid) !== null && n !== void 0 ? n : u, (r = t == null ? void 0 : t.onInvalid) !== null && r !== void 0 ? r : h),
register: (l, j) => {
var d, m;
return {
...i.register(l, j),
defaultValue: (m = (d = s == null ? void 0 : s.defaultValues) === null || d === void 0 ? void 0 : d[l]) !== null && m !== void 0 ? m : ""
};
},
formState: {
dirtyFields: h,
isDirty: v,
isSubmitSuccessful: y,
isSubmitted: p,
isSubmitting: g,
isValid: D,
isValidating: F,
touchedFields: S,
submitCount: b,
isLoading: w,
errors: O
dirtyFields: g,
isDirty: p,
isSubmitSuccessful: D,
isSubmitted: F,
isSubmitting: S,
isValid: b,
isValidating: P,
touchedFields: V,
submitCount: w,
isLoading: x,
errors: $
}
};
}, z = ({ children: t, ...e }) => V.createElement(R, { ...e }, t), B = () => {
const t = A();
}, Q = ({ children: t, ...o }) => k.createElement(C, { ...o }, t), W = () => {
const t = I();
return {

@@ -80,10 +87,10 @@ ...t,

export {
z as RemixFormProvider,
G as createFormData,
C as getFormDataFromSearchParams,
_ as getValidatedFormData,
J as parseFormData,
T as useRemixForm,
B as useRemixFormContext,
N as validateFormData
Q as RemixFormProvider,
K as createFormData,
N as getFormDataFromSearchParams,
B as getValidatedFormData,
L as parseFormData,
M as useRemixForm,
W as useRemixFormContext,
J as validateFormData
};

@@ -22,5 +22,7 @@ import { FieldValues, Resolver, FieldErrors, FieldErrorsImpl, DeepRequired } from "react-hook-form";

export declare const getValidatedFormData: <T extends FieldValues>(request: Request, resolver: Resolver) => Promise<{
receivedValues: Record<any, any>;
errors: FieldErrors<T>;
data: undefined;
} | {
receivedValues: Record<any, any>;
errors: undefined;

@@ -27,0 +29,0 @@ data: T;

{
"name": "remix-hook-form",
"version": "1.0.8",
"version": "1.1.0",
"description": "Utility wrapper around react-hook-form for use with Remix.run",

@@ -5,0 +5,0 @@ "type": "module",

@@ -16,2 +16,3 @@ # remix-hook-form

Oh, and did we mention that this is fully Progressively enhanced? That's right, you can use this with or without javascript!

@@ -28,3 +29,3 @@ ## Installation

## Usage
## Basic usage

@@ -91,2 +92,64 @@ Here is an example usage of remix-hook-form:

## Usage with NO js
Here is an example usage of remix-hook-form:
```jsx
import { useRemixForm, getValidatedFormData } from "remix-hook-form";
import { Form } from "@remix-run/react";
import { zodResolver } from "@hookform/resolvers/zod";
import * as zod from "zod";
import { ActionArgs, json } from "@remix-run/server-runtime";
const schema = zod.object({
name: zod.string().nonempty(),
email: zod.string().email().nonempty(),
});
type FormData = zod.infer<typeof schema>;
const resolver = zodResolver(schema);
export const action = async ({ request }: ActionArgs) => {
const { errors, data, receivedValues: defaultValues } =
await getValidatedFormData<FormData>(request, resolver);
if (errors) {
return json({ errors, defaultValues });
}
// Do something with the data
return json(data);
};
export default function MyForm() {
const {
handleSubmit,
formState: { errors },
register,
} = useRemixForm({
mode: "onSubmit",
defaultValues: {
name: "",
email: "",
},
resolver,
});
return (
<Form onSubmit={handleSubmit}>
<label>
Name:
<input type="text" {...register("name")} />
{errors.name && <p>{errors.name.message}</p>}
</label>
<label>
Email:
<input type="email" {...register("email")} />
{errors.email && <p>{errors.email.message}</p>}
</label>
<button type="submit">Submit</button>
</Form>
);
}
```
## Utilities

@@ -102,4 +165,7 @@

getValidatedFormData is a utility function that can be used to validate form data in your action. It takes two arguments: the request object and the resolver function. It returns an object with two properties: `errors` and `data`. If there are no errors, `errors` will be `undefined`. If there are errors, `errors` will be an object with the same shape as the `errors` object returned by `useRemixForm`. If there are no errors, `data` will be an object with the same shape as the `data` object returned by `useRemixForm`.
getValidatedFormData is a utility function that can be used to validate form data in your action. It takes two arguments: the request object and the resolver function. It returns an object with three properties: `errors`, `receivedValues` and `data`. If there are no errors, `errors` will be `undefined`. If there are errors, `errors` will be an object with the same shape as the `errors` object returned by `useRemixForm`. If there are no errors, `data` will be an object with the same shape as the `data` object returned by `useRemixForm`.
The `receivedValues` property allows you to set the default values of your form to the values that were received from the request object. This is useful if you want to display the form again with the values that were submitted by the user when there is no JS present
### Example with errors only
```jsx

@@ -117,3 +183,18 @@ /** all the same code from above */

};
```
### Example with errors and receivedValues
```jsx
/** all the same code from above */
export const action = async ({ request }: ActionArgs) => {
// Takes the request from the frontend, parses and validates it and returns the data
const { errors, data, receivedValues } =
await getValidatedFormData<FormData>(request, resolver);
if (errors) {
return json({ errors, receivedValues });
}
// Do something with the data
};
```

@@ -213,3 +294,2 @@

- The success case is provided by default where when the form is validated by the provided resolver, and it has no errors, it will automatically submit the form to the current route using a POST request. The data will be sent as `formData` to the action function.

@@ -221,2 +301,3 @@ - The data that is sent is automatically wrapped into a formData object and passed to the server ready to be used. Easiest way to consume it is by using the `parseFormData` or `getValidatedFormData` function from the `remix-hook-form` package.

The `register` function returned also has super powers that allows it to set the default value of the input returned from the server.

@@ -223,0 +304,0 @@ This is achieved by using `useActionData` from `@remix-run/react` to get the data returned by the action function. If the data returned by the action function is an object with the same shape as the `errors` object returned by `useRemixForm`, it will automatically populate the `formState.errors` object with the errors returned by the server. To ensure this is done properly, it is recommended that you use `getValidatedFormData` and then return the errors object from the action function as `json(errors)`.

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc