@paragrav/rhf-utils 0.0.119 → 0.0.121

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 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
- // defaults -- overridable per form instance
21
+ // overridable at individual form level
18
22
  defaults: {
19
23
  // globally-relevant subset of RHF's `UseFormProps` options
20
24
  rhf: {
21
- mode: 'onBlur',
25
+ mode: 'onSubmit',
22
26
  },
23
27
 
24
28
  // RhfUtilsFormOptions (see further below)
25
29
  utils: {
26
- // enable dev tool on dev env
30
+ stopSubmitPropagation: true,
27
31
  devTool: import.meta.env.DEV,
28
32
  },
29
33
 
@@ -38,7 +42,7 @@ export const rhfUtilsClientConfig: RhfUtilsClientConfig = {
38
42
  FormComponent: Form.Root,
39
43
 
40
44
  // optional wrapper to inject your own hooks and components
41
- // `children` prop is provided by RhfUtilsZodForm's Children prop
45
+ // around all RhfUtilsZodForm instances
42
46
  FormChildren: (
43
47
  // UseRhfUtilsFormChildrenProps
44
48
  {
@@ -48,44 +52,52 @@ export const rhfUtilsClientConfig: RhfUtilsClientConfig = {
48
52
  options, // RhfUtilsFormOptions
49
53
  Controller, // strictly-typed controller
50
54
  FormSubmitError, // strictly-typed error class
51
- children, // RhfUtilsZodForm.Children
55
+ children, // RhfUtilsZodForm's Children instance
52
56
  },
53
57
  ) => {
54
- // navigation blocker (using custom option)
55
- useFormRouterBlocker(!!options?.prompter);
58
+ // your own hooks/behaviors
59
+ // (using custom option prop -- see "Extend RhfUtilsFormOptions" section)
60
+ useMyFormNavigationPrompt(!!options?.enableMyFormNavigationPrompt);
56
61
 
57
62
  return (
58
63
  <>
59
- {/* specific form children -- e.g., fields, etc. */}
64
+ {/* RhfUtilsZodForm Children outlet */}
60
65
  {children}
61
66
 
62
- {/* global error list */}
63
- <RootErrorsListFromFlatFieldErrorsContext />
67
+ {/* root errors list */}
68
+ <RootErrorsList />
64
69
  </>
65
70
  );
66
71
  },
67
72
 
68
- // non-FormSubmitError throw in onSubmit
69
- // example use case: transform backend error
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 into RHF context errors
81
+ // return FormSubmitErrors object to be merged to RHF context errors
77
82
  return transformServerErrorToFormSubmitErrors(error);
78
83
  },
79
84
 
80
- errors: {
85
+ // form state field errors
86
+ fieldErrors: {
87
+ // callbacks to determine when to output information about field errors
88
+ // provided `FlatFieldErrorsContext` (all, fields, roots, orphans, hasOrphans)
81
89
  output: {
82
- // callback to determine when to output form context errors to console ("debug" or "error")
90
+ // determine when to console ("debug" or "error")
83
91
  console: ({ hasOrphans }) =>
84
- (hasOrphans && { type: 'error' }) || // console error for reporting on prod
85
- (import.meta.env.DEV && { type: 'debug' }), // facilitate debugging on dev
86
-
87
- // callback to determine when to throw an error based on context
88
- throw: ({ hasOrphans }) => import.meta.env.DEV && hasOrphans,
92
+ // console error for reporting on prod
93
+ (hasOrphans && { type: 'error' }) ||
94
+ // facilitate local debugging of form validation
95
+ (import.meta.env.DEV && { type: 'debug' }),
96
+
97
+ // callback to determine when to throw an error based on field errors
98
+ throw: ({ hasOrphans }) =>
99
+ // bring attention to orphans locally
100
+ import.meta.env.DEV && hasOrphans,
89
101
  },
90
102
  },
91
103
  };
@@ -107,26 +119,26 @@ Currently, only `zod` is supported.
107
119
 
108
120
  ```tsx
109
121
  <RhfUtilsZodForm
110
- schema={authLoginFormSchema}
122
+ schema={loginFormSchema}
111
123
  defaultValues={{
112
124
  email: '',
113
125
  }}
114
126
  // submit handler
115
127
  onSubmit={async (
116
128
  data, // schema output
117
- context, // UseRhfUtilsFormOnSubmitContext (form id, form ref, context (rhf), utils options, strictly-typed FormSubmitError class)
129
+ context, // UseRhfUtilsFormOnSubmitContext (id, ref, rhf context, utils options, strictly-typed FormSubmitError class)
118
130
  event, // SubmitEvent
119
131
  ) => {
120
- await authLoginService(data);
121
- onSuccess();
132
+ await loginService(data);
133
+ props.onSuccess();
122
134
  }}
123
135
  // handle error declaratively (i.e., no throw/catch)
124
136
  onSubmitError={({
125
137
  error, // unknown
126
- context, // UseRhfUtilsFormOnSubmitErrorContext (form id, form ref, context (rhf), utils options)
138
+ context, // UseRhfUtilsFormOnSubmitErrorContext (id, ref, rhf context, utils options)
127
139
  event, // SubmitEvent
128
140
  }) => {
129
- onError(error);
141
+ props.onError(error);
130
142
  }}
131
143
  // fields
132
144
  Children={({
@@ -145,6 +157,7 @@ Currently, only `zod` is supported.
145
157
  <label>
146
158
  Email
147
159
  <input {...field} disabled={isSubmitting} />
160
+ <FormErrorMessageByPath path={field.name} />
148
161
  </label>
149
162
  )}
150
163
  />
@@ -152,10 +165,35 @@ Currently, only `zod` is supported.
152
165
  <button type="submit">Login</button>
153
166
  </>
154
167
  )}
168
+ // form-specific options/overrides
169
+ rhf={{
170
+ mode: 'onBlur',
171
+ }}
172
+ utils={{
173
+ submitOnChange: true,
174
+ resetValuesOnSubmitError: true,
175
+ // custom option props
176
+ // (see "Extend RhfUtilsFormOptions" section)
177
+ enableMyFormNavigationPrompt: true,
178
+ }}
179
+ form={{
180
+ // class names are merged together with global defaults
181
+ className: 'my-special-form-class',
182
+ }}
155
183
  />
156
184
  ```
157
185
 
158
- `Children` is a component which is rendered as a child of the form. It receives `UseRhfUtilsFormChildrenProps` as props, including type-safe `Controller`.
186
+ `Children` prop takes a component which is rendered as a child of the form (and, if supplied, of `RhfUtilsClientConfig.FormChildren`). It receives `UseRhfUtilsFormChildrenProps` as props, including a type-safe `Controller` component.
187
+
188
+ The component hierarchy is:
189
+
190
+ ```tsx
191
+ <RhfUtilsClientConfig.FormComponent>
192
+ <RhfUtilsClientConfig.FormChildren>
193
+ <RhfUtilsZodForm.Children />
194
+ </RhfUtilsClientConfig.FormChildren>
195
+ </RhfUtilsClientConfig.FormComponent>
196
+ ```
159
197
 
160
198
  If you prefer to define your `Children` component as standalone:
161
199
 
@@ -175,7 +213,7 @@ Example:
175
213
 
176
214
  ```tsx
177
215
  <RhfUtilsZodForm
178
- onSubmit={({ FormSubmitError }) => {
216
+ onSubmit={async ({ FormSubmitError }) => {
179
217
  if (isProblem())
180
218
  throw new FormSubmitError({
181
219
  root: { message: 'There was a problem with the form.' },
@@ -189,7 +227,7 @@ Example:
189
227
 
190
228
  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
229
 
192
- Most common use case will be transforming backend errors to frontend shape. (You can use `getOnSubmitTrpcClientErrorHandler` HOF for TRPC backends.)
230
+ 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
231
 
194
232
  ## `RhfUtilsFormOptions`
195
233
 
@@ -209,21 +247,18 @@ type RhfUtilsFormOptions = {
209
247
  /** Reset form after successful submit. */
210
248
  resetFormAfterSubmitSuccessful?: UseResetFormAfterSubmitSuccessfulOptions;
211
249
 
212
- /**
213
- * Control dev tool options.
214
- * (Lazy-loaded when truthy value supplied.)
215
- */
250
+ /** Control dev tool options. (Lazy-loaded when truthy value supplied.) */
216
251
  devTool?: true | Pick<DevtoolUIProps, 'placement' | 'styles'>;
217
252
  };
218
253
  ```
219
254
 
220
255
  If you need access to options deeper in component structure, use `useRhfUtilsContext` to receive `RhfUtilsContext` object, which includes `formId`, `formRef`, and `options` settings.
221
256
 
222
- Use `useRhfUtilsContextRequestSubmit` to get `requestSubmit` fn for current form ref in context. This is useful when you need to trigger form submission programatically.
257
+ Use `useRhfUtilsContextRequestSubmit` hook to get `requestSubmit` function for current form ref in context. This is useful when you need to trigger form submission programatically.
223
258
 
224
259
  ## Extend `RhfUtilsFormOptions`
225
260
 
226
- Extend `RhfUtilsFormOptions` with custom options, which get passed to `Children` component in `options` prop.
261
+ Extend `RhfUtilsFormOptions` with custom options, which get passed to `Children` component in `options` prop. These can take any shape, and allow you to override your own functionality at form-level.
227
262
 
228
263
  ```tsx
229
264
  import '@paragrav/rhf-utils';
@@ -232,7 +267,7 @@ declare module '@paragrav/rhf-utils' {
232
267
  export interface Register {
233
268
  RhfUtilsFormOptions: {
234
269
  /** Enable user prompt to confirm navigating away from dirty form. */
235
- prompter?: boolean;
270
+ enableMyFormNavigationPrompt?: boolean;
236
271
  };
237
272
  }
238
273
  }
@@ -242,6 +277,8 @@ declare module '@paragrav/rhf-utils' {
242
277
 
243
278
  You can configure via `RhfUtilsClientConfig` (example at the top) when form context errors are outputted -- i.e., via console and/or thrown error.
244
279
 
280
+ Use `useFlatFieldErrorsContext()` hook, which returns an object with errors grouped by `all`, `fields`, `roots`, `orphans` records, and `hasErrors` and `hasErrors` and `hasOrphans` booleans.
281
+
245
282
  ### Orphans
246
283
 
247
284
  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.
@@ -252,7 +289,7 @@ The criteria for an orphan is any form context error that meets all of the follo
252
289
  - has no `ref` -- RHF includes `ref` to the associated input on each error object (when applicable)
253
290
  - has no marker in DOM (e.g., `FormNonFieldErrorMarker`)
254
291
 
255
- To get accurate orphan analysis, you must either use `FormNonFieldErrorMarker` in any error you are displaying to user which is not "root" and doesn't have a `ref`. (There is no harm in using this consistently across all errors, even those expected to have a ref.)
292
+ To get accurate orphan analysis, you must either use `FormNonFieldErrorMarker` in any error you are displaying to user that is not "root" and doesn't have a `ref`. (There is no harm in using this consistently across all errors, even those expected to have a ref.)
256
293
 
257
294
  Alternatively, you can use `FormErrorMessageByPath` to display error message to user:
258
295
 
@@ -260,12 +297,12 @@ Alternatively, you can use `FormErrorMessageByPath` to display error message to
260
297
  <FormErrorMessageByPath path="street.address" />
261
298
  ```
262
299
 
263
- Example use case: Field array with minimum items. (When there are no items, the error is not associated with a field and is displayed separately.)
300
+ Example use case: Field array with minimum items. When there are no items, the error is not associated with a field and is displayed separately.
264
301
 
265
302
  Orphans are exposed in a few places.
266
303
 
267
304
  - In errors outputted via console. (Configurable via `RhfUtilsClientConfig['errors']['output']`.)
268
- - And `useFlatFieldErrorsContext()` hook, which returns an object with errors grouped by `all`, `fields`, `root`, and `orphans`.
305
+ - And `useFlatFieldErrorsContext()` hook, which returns an object with errors grouped by `all`, `fields`, `roots`, `orphans` records, and `hasErrors` and `hasOrphans` boolean.
269
306
  - Boolean value from `useFlatFieldErrorsContextHasOnlyOrphans`.
270
307
 
271
308
  `FlatFieldErrors` is a flattened, simplified version of RHF's `FieldErrors`. Keys represent field paths flattened to dot notation.
@@ -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,
@@ -1,23 +1,27 @@
1
- import { jsx as s } from "react/jsx-runtime";
1
+ import { jsx as a } from "react/jsx-runtime";
2
2
  import "react";
3
- import { useFormState as i } from "react-hook-form";
4
- import l from "../../getRefdFromFlatFieldErrors.mjs";
5
- import F from "../../orphan/getOrphansFromFlatFieldErrors.mjs";
6
- import a from "../../root/getRootsFromFlatFieldErrors.mjs";
7
- import n from "../getFlatFieldErrors.mjs";
8
- import { _FormErrorsFlatContextProvider as p } from "./useFlatFieldErrorsContext.mjs";
9
- const h = ({
3
+ import { useFormState as l } from "react-hook-form";
4
+ import F from "../../getRefdFromFlatFieldErrors.mjs";
5
+ import e from "../../../utils/isEmptyObject.mjs";
6
+ import p from "../../orphan/getOrphansFromFlatFieldErrors.mjs";
7
+ import n from "../../root/getRootsFromFlatFieldErrors.mjs";
8
+ import d from "../getFlatFieldErrors.mjs";
9
+ import { _FormErrorsFlatContextProvider as f } from "./useFlatFieldErrorsContext.mjs";
10
+ const C = ({
10
11
  formRef: o,
11
- children: t
12
+ children: m
12
13
  }) => {
13
- const { errors: e } = i(), r = n(e), m = {
14
+ const { errors: t } = l(), r = d(t), s = o.current ? p(r, o.current) : {}, i = {
14
15
  all: r,
15
- fields: l(r),
16
- roots: a(r),
17
- orphans: o.current ? F(r, o.current) : {}
16
+ fields: F(r),
17
+ roots: n(r),
18
+ orphans: s,
19
+ // computed
20
+ hasErrors: !e(t),
21
+ hasOrphans: e(s)
18
22
  };
19
- return /* @__PURE__ */ s(p, { value: m, children: t });
23
+ return /* @__PURE__ */ a(f, { value: i, children: m });
20
24
  };
21
25
  export {
22
- h as default
26
+ C as default
23
27
  };
@@ -1,10 +1,9 @@
1
- import t from "react";
2
- import s from "../../../utils/isEmptyObject.mjs";
1
+ import s from "react";
3
2
  import e from "./useFlatFieldErrorsContext.mjs";
4
- const n = () => {
3
+ const t = () => {
5
4
  const r = e();
6
- return t.useMemo(() => s(r.orphans) ? !1 : Object.keys(r.orphans).length === Object.keys(r.all).length, [r]);
7
- }, O = n;
5
+ return s.useMemo(() => !r.hasErrors || !r.hasOrphans ? !1 : Object.keys(r.orphans).length === Object.keys(r.all).length, [r]);
6
+ }, l = t;
8
7
  export {
9
- O as default
8
+ l as default
10
9
  };
@@ -1,28 +1,25 @@
1
- import h from "react";
2
- import { useFormContext as E } from "react-hook-form";
3
- import l from "../../../utils/isEmptyObject.mjs";
4
- import F from "../../output/consoleErrors.mjs";
5
- import x from "./useFlatFieldErrorsContext.mjs";
6
- const n = (r) => {
7
- const u = E(), t = x();
8
- h.useEffect(() => {
9
- var m, a;
10
- if (l(t.all))
1
+ import u from "react";
2
+ import { useFormContext as p } from "react-hook-form";
3
+ import E from "../../output/consoleErrors.mjs";
4
+ import F from "./useFlatFieldErrorsContext.mjs";
5
+ const C = (r) => {
6
+ const l = p(), t = F();
7
+ u.useEffect(() => {
8
+ var o, m;
9
+ if (!t.hasErrors)
11
10
  return;
12
- const o = {
13
- hasOrphans: !l(t.orphans)
14
- }, e = (m = r == null ? void 0 : r.console) == null ? void 0 : m.call(r, o);
15
- e && F(
16
- e.message ?? p,
17
- u.getValues(),
11
+ const e = (o = r == null ? void 0 : r.console) == null ? void 0 : o.call(r, t);
12
+ e && E(
13
+ e.message ?? a,
14
+ l.getValues(),
18
15
  t,
19
16
  e.type
20
17
  );
21
- const s = (a = r == null ? void 0 : r.throw) == null ? void 0 : a.call(r, o);
18
+ const s = (m = r == null ? void 0 : r.throw) == null ? void 0 : m.call(r, t);
22
19
  if (s)
23
- throw new Error(typeof s == "string" ? s : p);
20
+ throw new Error(typeof s == "string" ? s : a);
24
21
  }, [t]);
25
- }, p = "Form errors";
22
+ }, a = "Form errors";
26
23
  export {
27
- n as default
24
+ C as default
28
25
  };
@@ -1,82 +1,78 @@
1
- import { jsx as a, jsxs as v, Fragment as E } from "react/jsx-runtime";
1
+ import { jsx as s, jsxs as j } from "react/jsx-runtime";
2
2
  import "react";
3
- import { useFormContext as P } from "react-hook-form";
3
+ import { useFormContext as v } from "react-hook-form";
4
4
  import w from "../client/config/useRhfUtilsClientConfigContext.mjs";
5
- import S from "../devtool/LazyDevTool.mjs";
6
- import { FormSubmitError as h } from "../submit/error/FormSubmitError.mjs";
7
- import U from "../submit/error/setCtxErrorsByFormSubmitErrors.mjs";
5
+ import E from "../devtool/LazyDevTool.mjs";
6
+ import { FormSubmitError as c } from "../submit/error/FormSubmitError.mjs";
7
+ import S from "../submit/error/setCtxErrorsByFormSubmitErrors.mjs";
8
+ import U from "../utils/PassthroughChildren.mjs";
8
9
  import _ from "./_Controller.mjs";
9
10
  function G({
10
- formId: n,
11
- formRef: p,
11
+ formId: p,
12
+ formRef: m,
12
13
  //
13
- onSubmit: c,
14
- onSubmitError: d,
15
- onSubmitInvalid: F,
16
- Children: i,
14
+ onSubmit: a,
15
+ onSubmitError: h,
16
+ onSubmitInvalid: i,
17
+ Children: l,
17
18
  //
18
- form: l,
19
+ form: F,
19
20
  utils: o
20
21
  }) {
21
- const e = P(), r = w(), y = async (t) => {
22
+ const n = v(), r = w(), y = async (t) => {
22
23
  o != null && o.stopSubmitPropagation && t.stopPropagation();
23
24
  try {
24
- await e.handleSubmit(f, F)(t);
25
- } catch (m) {
26
- b(m, t);
25
+ await n.handleSubmit(f, i)(t);
26
+ } catch (e) {
27
+ b(e, t);
27
28
  }
28
- }, f = (t, m) => c == null ? void 0 : c(
29
+ }, f = (t, e) => a == null ? void 0 : a(
29
30
  t,
30
31
  {
31
- formId: n,
32
- formRef: p,
33
- context: e,
32
+ formId: p,
33
+ formRef: m,
34
+ context: n,
34
35
  utils: o,
35
- FormSubmitError: h
36
+ FormSubmitError: c
36
37
  },
37
- m
38
- ), b = (t, m) => {
38
+ e
39
+ ), b = (t, e) => {
39
40
  var x;
40
- const C = t instanceof h ? (
41
+ const C = t instanceof c ? (
41
42
  // consumer can manually throw FormSubmitError (e.g., manual validation)
42
43
  t.errors
43
44
  ) : (
44
45
  // if error is not FormSubmitError, consumer can provide global handler
45
46
  (x = r == null ? void 0 : r.onSubmitUnknownError) == null ? void 0 : x.call(r, t)
46
47
  );
47
- C && U(e, C), d == null || d(
48
+ C && S(n, C), h == null || h(
48
49
  t,
49
50
  {
50
- formId: n,
51
- formRef: p,
52
- context: e,
51
+ formId: p,
52
+ formRef: m,
53
+ context: n,
53
54
  utils: o
54
55
  },
55
- m
56
+ e
56
57
  );
57
- }, s = {
58
- formId: n,
59
- formRef: p,
60
- context: e,
58
+ }, d = {
59
+ formId: p,
60
+ formRef: m,
61
+ context: n,
61
62
  utils: o,
62
63
  Controller: _,
63
- FormSubmitError: h
64
- }, T = (r == null ? void 0 : r.FormComponent) ?? "form", j = (r == null ? void 0 : r.FormChildren) ?? k;
65
- return /* @__PURE__ */ a(T, { ...l, ref: p, onSubmit: y, children: /* @__PURE__ */ v(j, { ...s, children: [
66
- (o == null ? void 0 : o.devTool) && /* @__PURE__ */ a(
67
- S,
64
+ FormSubmitError: c
65
+ }, P = (r == null ? void 0 : r.FormComponent) ?? "form", T = (r == null ? void 0 : r.FormChildren) ?? U;
66
+ return /* @__PURE__ */ s(P, { ...F, ref: m, onSubmit: y, children: /* @__PURE__ */ j(T, { ...d, children: [
67
+ (o == null ? void 0 : o.devTool) && /* @__PURE__ */ s(
68
+ E,
68
69
  {
69
70
  props: typeof o.devTool == "object" ? o.devTool : void 0
70
71
  }
71
72
  ),
72
- /* @__PURE__ */ a(i, { ...s })
73
+ /* @__PURE__ */ s(l, { ...d })
73
74
  ] }) });
74
75
  }
75
- function k({
76
- children: n
77
- }) {
78
- return /* @__PURE__ */ a(E, { children: n });
79
- }
80
76
  export {
81
77
  G as default
82
78
  };
@@ -4,18 +4,18 @@ import F from "../../../errors/flat/context/useFlatFieldErrorsContextOutput.mjs"
4
4
  import x from "../../../submit/useFormOnSubmitSuccessfulAndReset.mjs";
5
5
  import O from "../../../submit/useResetFormOnSubmitError.mjs";
6
6
  import b from "../../../submit/useResetFormOnSubmitSuccessful.mjs";
7
- import h from "../../../submit/useSubmitFormOnChange.mjs";
8
- import { _RhfUtilsContextProvider as d } from "./useRhfUtilsContext.mjs";
7
+ import d from "../../../submit/useSubmitFormOnChange.mjs";
8
+ import { _RhfUtilsContextProvider as h } from "./useRhfUtilsContext.mjs";
9
9
  const M = ({
10
- formId: a,
10
+ formId: f,
11
11
  formRef: t,
12
12
  onSubmitSuccessfulAndReset: e,
13
13
  options: r,
14
- children: f
14
+ children: a
15
15
  }) => {
16
16
  var u;
17
17
  const m = C();
18
- return F((u = m == null ? void 0 : m.errors) == null ? void 0 : u.output), h(t, {
18
+ return F((u = m == null ? void 0 : m.fieldErrors) == null ? void 0 : u.output), d(t, {
19
19
  disabled: !(r != null && r.submitOnChange)
20
20
  }), O({
21
21
  disabled: !(r != null && r.resetValuesOnSubmitError)
@@ -23,7 +23,7 @@ const M = ({
23
23
  (r == null ? void 0 : r.resetFormAfterSubmitSuccessful) || !!e
24
24
  ), x(() => {
25
25
  e == null || e();
26
- }), /* @__PURE__ */ l(d, { value: { formId: a, formRef: t, options: r }, children: f });
26
+ }), /* @__PURE__ */ l(h, { value: { formId: f, formRef: t, options: r }, children: a });
27
27
  };
28
28
  export {
29
29
  M as default
@@ -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
- onSubmit: e,
6
- onSubmitError: f,
7
- onSubmitInvalid: p,
8
- defaultValues: n,
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: n
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: e,
31
- onSubmitError: f,
32
- onSubmitInvalid: p,
30
+ onSubmit: f,
31
+ onSubmitError: p,
32
+ onSubmitInvalid: n,
33
33
  formId: r,
34
34
  formRef: o,
35
35
  form: u,
@@ -0,0 +1,7 @@
1
+ import { jsx as t, Fragment as o } from "react/jsx-runtime";
2
+ const a = ({
3
+ children: r
4
+ }) => /* @__PURE__ */ t(o, { children: r });
5
+ export {
6
+ a as default
7
+ };
@@ -57,7 +57,7 @@ export type RhfUtilsClientConfig = {
57
57
  * - if `undefined`: do nothing.
58
58
  */
59
59
  onSubmitUnknownError?: (error: unknown) => FormSubmitErrors | undefined;
60
- errors?: {
60
+ fieldErrors?: {
61
61
  /**
62
62
  * Configure how/if errors should be outputted.
63
63
  */
@@ -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: Omit<UseRhfUtilsFormPropsForm, 'config'>) => UseRhfUtilsFormReturn<TSchemaInput, TSchemaOutput> & {
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
- } & Omit<UseRhfUtilsFormProps<TSchema[typeof zodTypeInput], TSchema[typeof zodTypeOutput]>, 'config'>;
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: Omit<UseRhfUtilsFormProps<TSchema[typeof zodTypeInput], TSchema[typeof zodTypeOutput]>, 'config'>) => import('../../../form/UseRhfUtilsFormReturn').UseRhfUtilsFormReturn<TSchema["_input"], TSchema["_output"]> & {
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
  }>;
@@ -1,4 +1,5 @@
1
- import { RhfUtilsErrorsOutputConfigContext, RhfUtilsErrorsOutputConsoleConfig } from '../../output/types';
1
+ import { RhfUtilsErrorsOutputConsoleConfig } from '../../output/types';
2
+ import { FlatFieldErrorsContext } from './useFlatFieldErrorsContext';
2
3
 
3
4
  export type FlatFieldErrorsOutputConfig = {
4
5
  /**
@@ -8,12 +9,12 @@ export type FlatFieldErrorsOutputConfig = {
8
9
  * - console.debug errors in development environment.
9
10
  * - console.error certain errors in production environment.
10
11
  */
11
- console?: (context: RhfUtilsErrorsOutputConfigContext) => RhfUtilsErrorsOutputConsoleConfig | null | false | undefined;
12
+ console?: (context: FlatFieldErrorsContext) => RhfUtilsErrorsOutputConsoleConfig | null | false | undefined;
12
13
  /**
13
14
  * Configure how/if errors should be thrown.
14
15
  *
15
16
  * Example use case:
16
17
  * - bring attention to certain errors in development environment.
17
18
  */
18
- throw?: (context: RhfUtilsErrorsOutputConfigContext) => true | string | false | undefined;
19
+ throw?: (context: FlatFieldErrorsContext) => true | string | false | undefined;
19
20
  };
@@ -5,6 +5,8 @@ export type FlatFieldErrorsContext = {
5
5
  fields: FlatFieldErrors;
6
6
  roots: FlatFieldErrors;
7
7
  orphans: FlatFieldErrors;
8
+ hasErrors: boolean;
9
+ hasOrphans: boolean;
8
10
  };
9
11
  declare const _FormErrorsFlatContextProvider: import('react').Provider<FlatFieldErrorsContext | undefined>, useFlatFieldErrorsContext: () => FlatFieldErrorsContext;
10
12
  export default useFlatFieldErrorsContext;
@@ -1,8 +1,7 @@
1
- import { FieldErrors } from 'react-hook-form';
2
1
  import { SafeFieldValues } from '../../form/SafeFieldValues';
3
2
 
4
3
  /**
5
4
  * Output form values and errors to console.
6
5
  */
7
- declare const consoleErrors: (message: string, values: SafeFieldValues, errors: FieldErrors, type?: 'debug' | 'error') => void;
6
+ declare const consoleErrors: (message: string, values: SafeFieldValues, errors: Record<string, unknown>, type?: 'debug' | 'error') => void;
8
7
  export default consoleErrors;
@@ -5,10 +5,3 @@ export type RhfUtilsErrorsOutputConsoleConfig = {
5
5
  type?: 'debug' | 'error';
6
6
  message?: string;
7
7
  };
8
- /**
9
- * Contextual data to determine whether to output error.
10
- */
11
- export type RhfUtilsErrorsOutputConfigContext = {
12
- isDevelopment?: boolean;
13
- hasOrphans?: boolean;
14
- };
@@ -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, defaultValues, Children, rhf, form, utils, }: UseRhfUtilsFormProps<TFieldValues, TTransformedValues>) => UseRhfUtilsFormReturn<TFieldValues, TTransformedValues>;
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>;
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+ /**
3
+ * Component for simply passing through children.
4
+ *
5
+ * (Useful for conditional wrapping of children.)
6
+ */
7
+ declare const PassthroughChildren: React.FC<React.PropsWithChildren>;
8
+ export default PassthroughChildren;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@paragrav/rhf-utils",
3
3
  "author": "paragrav.dev",
4
4
  "license": "MIT",
5
- "version": "0.0.119",
5
+ "version": "0.0.121",
6
6
  "description": "Integration utilities for react-hook-form.",
7
7
  "type": "module",
8
8
  "sideEffects": false,