@paragrav/rhf-utils 0.0.119 → 0.0.120
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 +42 -25
- package/dist/esm/client/index.mjs +3 -2
- package/dist/esm/form/useRhfUtilsForm.mjs +8 -8
- package/dist/types/client/index.d.ts +1 -1
- package/dist/types/client/zod/context/RhfUtilsZodForm.d.ts +1 -1
- package/dist/types/client/zod/context/useRhfUtilsZodForm.d.ts +1 -1
- package/dist/types/form/UseRhfUtilsFormProps.d.ts +1 -1
- package/dist/types/form/useRhfUtilsForm.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# README
|
|
2
2
|
|
|
3
|
+
## About
|
|
4
|
+
|
|
5
|
+
Integration and utility library for react-hook-form.
|
|
6
|
+
|
|
3
7
|
## Install
|
|
4
8
|
|
|
5
9
|
```sh
|
|
@@ -14,16 +18,16 @@ To configure, create a file `config.tsx` with desired configuration settings. Th
|
|
|
14
18
|
|
|
15
19
|
```tsx
|
|
16
20
|
export const rhfUtilsClientConfig: RhfUtilsClientConfig = {
|
|
17
|
-
//
|
|
21
|
+
// overridable per form instance
|
|
18
22
|
defaults: {
|
|
19
23
|
// globally-relevant subset of RHF's `UseFormProps` options
|
|
20
24
|
rhf: {
|
|
21
|
-
mode: '
|
|
25
|
+
mode: 'onSubmit',
|
|
22
26
|
},
|
|
23
27
|
|
|
24
28
|
// RhfUtilsFormOptions (see further below)
|
|
25
29
|
utils: {
|
|
26
|
-
|
|
30
|
+
stopSubmitPropagation: true,
|
|
27
31
|
devTool: import.meta.env.DEV,
|
|
28
32
|
},
|
|
29
33
|
|
|
@@ -38,7 +42,8 @@ export const rhfUtilsClientConfig: RhfUtilsClientConfig = {
|
|
|
38
42
|
FormComponent: Form.Root,
|
|
39
43
|
|
|
40
44
|
// optional wrapper to inject your own hooks and components
|
|
41
|
-
//
|
|
45
|
+
// around all RhfUtilsZodForm instances
|
|
46
|
+
// (see further below for more info)
|
|
42
47
|
FormChildren: (
|
|
43
48
|
// UseRhfUtilsFormChildrenProps
|
|
44
49
|
{
|
|
@@ -48,32 +53,32 @@ export const rhfUtilsClientConfig: RhfUtilsClientConfig = {
|
|
|
48
53
|
options, // RhfUtilsFormOptions
|
|
49
54
|
Controller, // strictly-typed controller
|
|
50
55
|
FormSubmitError, // strictly-typed error class
|
|
51
|
-
children, // RhfUtilsZodForm
|
|
56
|
+
children, // RhfUtilsZodForm's Children instance
|
|
52
57
|
},
|
|
53
58
|
) => {
|
|
54
|
-
// navigation blocker (using custom option)
|
|
55
|
-
|
|
59
|
+
// your navigation blocker (using custom option prop -- see "Extend RhfUtilsFormOptions" section)
|
|
60
|
+
useMyFormNavigationPrompt(!!options?.enableMyFormNavigationPrompt);
|
|
56
61
|
|
|
57
62
|
return (
|
|
58
63
|
<>
|
|
59
|
-
{/*
|
|
64
|
+
{/* RhfUtilsZodForm Children outlet */}
|
|
60
65
|
{children}
|
|
61
66
|
|
|
62
|
-
{/*
|
|
63
|
-
<
|
|
67
|
+
{/* root errors list */}
|
|
68
|
+
<RootErrorsList />
|
|
64
69
|
</>
|
|
65
70
|
);
|
|
66
71
|
},
|
|
67
72
|
|
|
68
|
-
// non-FormSubmitError
|
|
69
|
-
//
|
|
73
|
+
// non-FormSubmitError thrown in onSubmit
|
|
74
|
+
// use case: catch backend error and transform data for frontend
|
|
70
75
|
onSubmitUnknownError: (
|
|
71
76
|
error, // unknown
|
|
72
77
|
) => {
|
|
73
78
|
// if other error, re-throw to handle in ErrorBoundary
|
|
74
79
|
if (!(error instanceof MyServerError)) throw error;
|
|
75
80
|
|
|
76
|
-
// return FormSubmitErrors object to be merged
|
|
81
|
+
// return FormSubmitErrors object to be merged to RHF context errors
|
|
77
82
|
return transformServerErrorToFormSubmitErrors(error);
|
|
78
83
|
},
|
|
79
84
|
|
|
@@ -107,26 +112,26 @@ Currently, only `zod` is supported.
|
|
|
107
112
|
|
|
108
113
|
```tsx
|
|
109
114
|
<RhfUtilsZodForm
|
|
110
|
-
schema={
|
|
115
|
+
schema={loginFormSchema}
|
|
111
116
|
defaultValues={{
|
|
112
117
|
email: '',
|
|
113
118
|
}}
|
|
114
119
|
// submit handler
|
|
115
120
|
onSubmit={async (
|
|
116
121
|
data, // schema output
|
|
117
|
-
context, // UseRhfUtilsFormOnSubmitContext (
|
|
122
|
+
context, // UseRhfUtilsFormOnSubmitContext (id, ref, rhf context, utils options, strictly-typed FormSubmitError class)
|
|
118
123
|
event, // SubmitEvent
|
|
119
124
|
) => {
|
|
120
125
|
await authLoginService(data);
|
|
121
|
-
onSuccess();
|
|
126
|
+
props.onSuccess();
|
|
122
127
|
}}
|
|
123
128
|
// handle error declaratively (i.e., no throw/catch)
|
|
124
129
|
onSubmitError={({
|
|
125
130
|
error, // unknown
|
|
126
|
-
context, // UseRhfUtilsFormOnSubmitErrorContext (
|
|
131
|
+
context, // UseRhfUtilsFormOnSubmitErrorContext (id, ref, rhf context, utils options)
|
|
127
132
|
event, // SubmitEvent
|
|
128
133
|
}) => {
|
|
129
|
-
onError(error);
|
|
134
|
+
props.onError(error);
|
|
130
135
|
}}
|
|
131
136
|
// fields
|
|
132
137
|
Children={({
|
|
@@ -152,6 +157,19 @@ Currently, only `zod` is supported.
|
|
|
152
157
|
<button type="submit">Login</button>
|
|
153
158
|
</>
|
|
154
159
|
)}
|
|
160
|
+
// options/overrides
|
|
161
|
+
rhf={{
|
|
162
|
+
mode: 'onBlur',
|
|
163
|
+
}}
|
|
164
|
+
utils={{
|
|
165
|
+
submitOnChange: true,
|
|
166
|
+
resetValuesOnSubmitError: true,
|
|
167
|
+
enableMyFormNavigationPrompt: true, // custom option prop (see "Extend RhfUtilsFormOptions" section)
|
|
168
|
+
}}
|
|
169
|
+
form={{
|
|
170
|
+
// class names are merged together with global defaults
|
|
171
|
+
className: 'my-special-form-class',
|
|
172
|
+
}}
|
|
155
173
|
/>
|
|
156
174
|
```
|
|
157
175
|
|
|
@@ -175,7 +193,7 @@ Example:
|
|
|
175
193
|
|
|
176
194
|
```tsx
|
|
177
195
|
<RhfUtilsZodForm
|
|
178
|
-
onSubmit={({ FormSubmitError }) => {
|
|
196
|
+
onSubmit={async ({ FormSubmitError }) => {
|
|
179
197
|
if (isProblem())
|
|
180
198
|
throw new FormSubmitError({
|
|
181
199
|
root: { message: 'There was a problem with the form.' },
|
|
@@ -189,7 +207,7 @@ Example:
|
|
|
189
207
|
|
|
190
208
|
Any non-`FormSubmitError`s thrown from submit handler (e.g., fetch/axios error) can be transformed by `RhfUtilsClientConfig`'s `onSubmitUnknownError` callback. This takes an `unknown` error and can return a `FormSubmitErrors` object, which is merged in RHF's context errors.
|
|
191
209
|
|
|
192
|
-
Most common use case will be transforming backend errors to frontend shape. (You can use `getOnSubmitTrpcClientErrorHandler` HOF for TRPC backends.)
|
|
210
|
+
Most common use case will be transforming backend errors to frontend shape. (You can use `getOnSubmitTrpcClientErrorHandler` HOF provided by this library for TRPC backends.)
|
|
193
211
|
|
|
194
212
|
## `RhfUtilsFormOptions`
|
|
195
213
|
|
|
@@ -209,10 +227,7 @@ type RhfUtilsFormOptions = {
|
|
|
209
227
|
/** Reset form after successful submit. */
|
|
210
228
|
resetFormAfterSubmitSuccessful?: UseResetFormAfterSubmitSuccessfulOptions;
|
|
211
229
|
|
|
212
|
-
/**
|
|
213
|
-
* Control dev tool options.
|
|
214
|
-
* (Lazy-loaded when truthy value supplied.)
|
|
215
|
-
*/
|
|
230
|
+
/** Control dev tool options. (Lazy-loaded when truthy value supplied.) */
|
|
216
231
|
devTool?: true | Pick<DevtoolUIProps, 'placement' | 'styles'>;
|
|
217
232
|
};
|
|
218
233
|
```
|
|
@@ -232,7 +247,7 @@ declare module '@paragrav/rhf-utils' {
|
|
|
232
247
|
export interface Register {
|
|
233
248
|
RhfUtilsFormOptions: {
|
|
234
249
|
/** Enable user prompt to confirm navigating away from dirty form. */
|
|
235
|
-
|
|
250
|
+
enableMyFormNavigationPrompt?: boolean;
|
|
236
251
|
};
|
|
237
252
|
}
|
|
238
253
|
}
|
|
@@ -242,6 +257,8 @@ declare module '@paragrav/rhf-utils' {
|
|
|
242
257
|
|
|
243
258
|
You can configure via `RhfUtilsClientConfig` (example at the top) when form context errors are outputted -- i.e., via console and/or thrown error.
|
|
244
259
|
|
|
260
|
+
Use `useFlatFieldErrorsContext()` hook, which returns an object with errors grouped by `all`, `fields`, `root`, and `orphans`.
|
|
261
|
+
|
|
245
262
|
### Orphans
|
|
246
263
|
|
|
247
264
|
The concept of orphan errors is any error that is not being shown to user. An example would be a stray field in a schema that is prohibiting users from successfully submitting a form.
|
|
@@ -17,10 +17,11 @@ const v = (e) => (r) => {
|
|
|
17
17
|
var o, i, f, l, n, h;
|
|
18
18
|
return {
|
|
19
19
|
...t,
|
|
20
|
+
// merge global config with instance options...
|
|
20
21
|
rhf: {
|
|
22
|
+
resolver: e(s),
|
|
21
23
|
...(o = r.defaults) == null ? void 0 : o.rhf,
|
|
22
|
-
...t.rhf
|
|
23
|
-
resolver: e(s)
|
|
24
|
+
...t.rhf
|
|
24
25
|
},
|
|
25
26
|
utils: {
|
|
26
27
|
...(i = r.defaults) == null ? void 0 : i.utils,
|
|
@@ -2,10 +2,10 @@ import s from "react";
|
|
|
2
2
|
import { useForm as d } from "react-hook-form";
|
|
3
3
|
import { FormSubmitError as F } from "../submit/error/FormSubmitError.mjs";
|
|
4
4
|
const v = ({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
defaultValues: e,
|
|
6
|
+
onSubmit: f,
|
|
7
|
+
onSubmitError: p,
|
|
8
|
+
onSubmitInvalid: n,
|
|
9
9
|
Children: c,
|
|
10
10
|
rhf: i,
|
|
11
11
|
form: u,
|
|
@@ -13,7 +13,7 @@ const v = ({
|
|
|
13
13
|
}) => {
|
|
14
14
|
const r = s.useId(), m = d({
|
|
15
15
|
...i,
|
|
16
|
-
defaultValues:
|
|
16
|
+
defaultValues: e
|
|
17
17
|
}), o = s.useRef(null);
|
|
18
18
|
return {
|
|
19
19
|
id: r,
|
|
@@ -27,9 +27,9 @@ const v = ({
|
|
|
27
27
|
},
|
|
28
28
|
formProps: {
|
|
29
29
|
Children: c,
|
|
30
|
-
onSubmit:
|
|
31
|
-
onSubmitError:
|
|
32
|
-
onSubmitInvalid:
|
|
30
|
+
onSubmit: f,
|
|
31
|
+
onSubmitError: p,
|
|
32
|
+
onSubmitInvalid: n,
|
|
33
33
|
formId: r,
|
|
34
34
|
formRef: o,
|
|
35
35
|
form: u,
|
|
@@ -14,7 +14,7 @@ export type ObjectSchema<TInputKey extends string, TOutputKey extends string> =
|
|
|
14
14
|
[key in TOutputKey]: SafeFieldValues;
|
|
15
15
|
};
|
|
16
16
|
export type CreateRhfUtilsClient<TObjectSchema extends ObjectSchema<TObjectSchemaInputKey, TObjectSchemaOutputKey>, TObjectSchemaInputKey extends string, TObjectSchemaOutputKey extends string> = {
|
|
17
|
-
useForm: <TSchema extends TObjectSchema, TSchemaInput extends SafeFieldValues = TSchema[TObjectSchemaInputKey], TSchemaOutput extends SafeFieldValues = TSchema[TObjectSchemaOutputKey], UseRhfUtilsFormPropsForm extends UseRhfUtilsFormProps<TSchemaInput, TSchemaOutput> = UseRhfUtilsFormProps<TSchemaInput, TSchemaOutput>>(schema: TSchema, form:
|
|
17
|
+
useForm: <TSchema extends TObjectSchema, TSchemaInput extends SafeFieldValues = TSchema[TObjectSchemaInputKey], TSchemaOutput extends SafeFieldValues = TSchema[TObjectSchemaOutputKey], UseRhfUtilsFormPropsForm extends UseRhfUtilsFormProps<TSchemaInput, TSchemaOutput> = UseRhfUtilsFormProps<TSchemaInput, TSchemaOutput>>(schema: TSchema, form: UseRhfUtilsFormPropsForm) => UseRhfUtilsFormReturn<TSchemaInput, TSchemaOutput> & {
|
|
18
18
|
FormWithProviders: React.FC<React.PropsWithChildren>;
|
|
19
19
|
};
|
|
20
20
|
FormWithProviders: <TSchema extends TObjectSchema, TSchemaInput extends SafeFieldValues = TSchema[TObjectSchemaInputKey], TSchemaOutput extends SafeFieldValues = TSchema[TObjectSchemaOutputKey]>(props: {
|
|
@@ -4,6 +4,6 @@ import { ZodTypeFieldValues } from '../ZodTypeFieldValues';
|
|
|
4
4
|
|
|
5
5
|
type Props<TSchema extends ZodTypeFieldValues> = {
|
|
6
6
|
schema: TSchema;
|
|
7
|
-
} &
|
|
7
|
+
} & UseRhfUtilsFormProps<TSchema[typeof zodTypeInput], TSchema[typeof zodTypeOutput]>;
|
|
8
8
|
declare function RhfUtilsZodForm<TSchema extends ZodTypeFieldValues>({ schema, ...props }: Props<TSchema>): import("react/jsx-runtime").JSX.Element;
|
|
9
9
|
export default RhfUtilsZodForm;
|
|
@@ -2,7 +2,7 @@ import { UseRhfUtilsFormProps } from '../../../form/UseRhfUtilsFormProps';
|
|
|
2
2
|
import { zodTypeInput, zodTypeOutput } from '../consts';
|
|
3
3
|
import { ZodTypeFieldValues } from '../ZodTypeFieldValues';
|
|
4
4
|
|
|
5
|
-
declare const useRhfUtilsZodForm: <TSchema extends ZodTypeFieldValues>(schema: TSchema, form:
|
|
5
|
+
declare const useRhfUtilsZodForm: <TSchema extends ZodTypeFieldValues>(schema: TSchema, form: UseRhfUtilsFormProps<TSchema[typeof zodTypeInput], TSchema[typeof zodTypeOutput]>) => import('../../../form/UseRhfUtilsFormReturn').UseRhfUtilsFormReturn<TSchema["_input"], TSchema["_output"]> & {
|
|
6
6
|
FormWithProviders: import('react').FC<{
|
|
7
7
|
children?: import('react').ReactNode;
|
|
8
8
|
}>;
|
|
@@ -6,12 +6,12 @@ import { UseRhfUtilsFormChildrenProps } from './UseRhfUtilsFormChildrenProps';
|
|
|
6
6
|
import { UseRhfUtilsFormOnSubmitContext, UseRhfUtilsFormOnSubmitErrorContext } from './UseRhfUtilsFormOnSubmitContext';
|
|
7
7
|
|
|
8
8
|
export type UseRhfUtilsFormProps<TFieldValues extends SafeFieldValues, TTransformedValues extends SafeFieldValues> = {
|
|
9
|
+
defaultValues?: UseFormProps<TFieldValues>['defaultValues'];
|
|
9
10
|
onSubmit?: (values: TTransformedValues, context: UseRhfUtilsFormOnSubmitContext<TFieldValues, TTransformedValues>, event: React.BaseSyntheticEvent<SubmitEvent>) => unknown | Promise<unknown>;
|
|
10
11
|
/** Submit error handler. (Only for errors not of instance `FormError`, which are handled internally.) */
|
|
11
12
|
onSubmitError?: (error: unknown, context: UseRhfUtilsFormOnSubmitErrorContext<TFieldValues, TTransformedValues>, event: React.BaseSyntheticEvent<SubmitEvent>) => void;
|
|
12
13
|
/** Submit handler when form is invalid. */
|
|
13
14
|
onSubmitInvalid?: SubmitErrorHandler<TFieldValues>;
|
|
14
|
-
defaultValues?: UseFormProps<TFieldValues>['defaultValues'];
|
|
15
15
|
Children: React.FC<UseRhfUtilsFormChildrenProps<TFieldValues, TTransformedValues>>;
|
|
16
16
|
/** {@link RhfUseFormProps} props for RHF's {@link useForm}. */
|
|
17
17
|
rhf?: Omit<UseFormProps<TFieldValues>, 'defaultValues'>;
|
|
@@ -11,6 +11,6 @@ import { UseRhfUtilsFormReturn } from './UseRhfUtilsFormReturn';
|
|
|
11
11
|
* see https://caniuse.com/?search=form%20attribute
|
|
12
12
|
* @returns Form provider and form.
|
|
13
13
|
*/
|
|
14
|
-
declare const useRhfUtilsForm: <TFieldValues extends SafeFieldValues, TTransformedValues extends SafeFieldValues>({ onSubmit, onSubmitError, onSubmitInvalid,
|
|
14
|
+
declare const useRhfUtilsForm: <TFieldValues extends SafeFieldValues, TTransformedValues extends SafeFieldValues>({ defaultValues, onSubmit, onSubmitError, onSubmitInvalid, Children, rhf, form, utils, }: UseRhfUtilsFormProps<TFieldValues, TTransformedValues>) => UseRhfUtilsFormReturn<TFieldValues, TTransformedValues>;
|
|
15
15
|
export default useRhfUtilsForm;
|
|
16
16
|
export type UseRhfUtilsForm<TFieldValues extends SafeFieldValues, TTransformedValues extends SafeFieldValues> = typeof useRhfUtilsForm<TFieldValues, TTransformedValues>;
|