@paragrav/rhf-utils 0.0.117 → 0.0.118

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
@@ -31,49 +31,51 @@ export const rhfUtilsClientConfig: RhfUtilsClientConfig = {
31
31
  // optional (defaults to primitive HTML form)
32
32
  FormComponent: Form.Root,
33
33
 
34
+ // optional wrapper to inject your own hooks and components
35
+ // `children` prop is provided by RhfUtilsZodForm's Children prop
36
+ FormChildren: (
37
+ // UseRhfUtilsFormChildrenProps
38
+ {
39
+ formId, // unique id string
40
+ formRef, // ref
41
+ context, // rhf UseFormReturn
42
+ options, // RhfUtilsFormOptions
43
+ Controller, // strictly-typed controller
44
+ FormSubmitError, // strictly-typed error class
45
+ children, // RhfUtilsZodForm.Children
46
+ },
47
+ ) => {
48
+ // navigation blocker (using custom option)
49
+ useFormRouterBlocker(!!options?.prompter);
50
+
51
+ return (
52
+ <>
53
+ {/* specific form children -- e.g., fields, etc. */}
54
+ {children}
55
+
56
+ {/* global error list */}
57
+ <RootErrorsListFromFlatFieldErrorsContext />
58
+ </>
59
+ );
60
+ },
61
+
34
62
  // non-FormSubmitError throw in onSubmit
35
- // use case: transform backend error
63
+ // example use case: transform backend error
36
64
  onSubmitUnknownError: (
37
65
  error, // unknown
38
66
  ) => {
39
67
  // if other error, re-throw to handle in ErrorBoundary
40
68
  if (!(error instanceof MyServerError)) throw error;
41
69
 
42
- // return to be merged into RHF context errors
70
+ // return FormSubmitErrors object to be merged into RHF context errors
43
71
  return transformServerErrorToFormSubmitErrors(error);
44
72
  },
45
73
 
46
- Children: {
47
- top: (
48
- // UseRhfUtilsFormChildrenProps
49
- {
50
- formId, // unique id string
51
- formRef, // ref
52
- context, // rhf UseFormReturn
53
- options, // RhfUtilsFormOptions
54
- Controller, // strictly-typed controller
55
- FormSubmitError, // strictly-typed error class
56
- },
57
- ) => {
58
- // navigation blocker (using custom option)
59
- useFormRouterBlocker(!!options?.prompter);
60
-
61
- return null;
62
- },
63
-
64
- bottom: () => (
65
- <>
66
- {/* global error list */}
67
- <RootErrorsListFromFlatFieldErrorsContext />
68
- </>
69
- ),
70
- },
71
-
72
74
  errors: {
73
75
  output: {
74
76
  // callback to determine when to output form context errors to console ("debug" or "error")
75
77
  console: ({ hasOrphans }) =>
76
- (hasOrphans && { type: 'error' }) || // report all orphan errors
78
+ (hasOrphans && { type: 'error' }) || // console error for reporting on prod
77
79
  (import.meta.env.DEV && { type: 'debug' }), // facilitate debugging on dev
78
80
 
79
81
  // callback to determine when to throw an error based on context
@@ -159,9 +161,9 @@ function Children({...}: RhfUtilsUseFormChildrenZodProps<typeof schema>) { }
159
161
 
160
162
  ## `FormSubmitError`
161
163
 
162
- This is an `Error`-based class you can use to throw a structured error in your submit handler. It is strictly-typed, so it only allows field names in schema and `root`/`root.{string}` keys.
164
+ This is an `Error`-based class you can use to throw a structured error in your submit handler. It is strictly-typed, so it only allows field names from your schema and `root`/`root.{string}` keys.
163
165
 
164
- It uses `FormSubmitErrors` shape, which is a flat (dot notation) equivalent of RHF's `FieldErrors`.
166
+ It uses `FormSubmitErrors` type's structure, which is a flat, simplified version of RHF's `FieldErrors`.
165
167
 
166
168
  Example:
167
169
 
@@ -4,28 +4,26 @@ import d from "../form/useRhfUtilsForm.mjs";
4
4
  const R = (e) => (r) => {
5
5
  const m = F(e, r);
6
6
  return {
7
- useForm: (i, s) => {
8
- const t = m(i, s);
7
+ useForm: (o, s) => {
8
+ const t = m(o, s);
9
9
  return {
10
10
  ...d(t),
11
- FormWithProviders: ({
12
- children: o
13
- }) => /* @__PURE__ */ h(f, { ...t, children: o })
11
+ FormWithProviders: () => /* @__PURE__ */ h(f, { ...t })
14
12
  };
15
13
  },
16
14
  FormWithProviders: a(e, r)
17
15
  };
18
- }, F = (e, r) => function(i, s) {
19
- var t, o, l, n, u;
16
+ }, F = (e, r) => function(o, s) {
17
+ var t, i, l, n, u;
20
18
  return {
21
19
  ...s,
22
20
  rhf: {
23
21
  ...(t = r.defaults) == null ? void 0 : t.rhf,
24
22
  ...s.rhf,
25
- resolver: e(i)
23
+ resolver: e(o)
26
24
  },
27
25
  utils: {
28
- ...(o = r.defaults) == null ? void 0 : o.utils,
26
+ ...(i = r.defaults) == null ? void 0 : i.utils,
29
27
  ...s.utils,
30
28
  classNames: [
31
29
  ...((n = (l = r.defaults) == null ? void 0 : l.utils) == null ? void 0 : n.classNames) ?? [],
@@ -34,15 +32,15 @@ const R = (e) => (r) => {
34
32
  }
35
33
  };
36
34
  }, a = (e, r) => function({
37
- schema: i,
35
+ schema: o,
38
36
  children: s,
39
37
  ...t
40
38
  }) {
41
- const o = F(e, r);
39
+ const i = F(e, r);
42
40
  return /* @__PURE__ */ h(
43
41
  f,
44
42
  {
45
- ...o(i, t),
43
+ ...i(o, t),
46
44
  children: s
47
45
  }
48
46
  );
@@ -1,98 +1,92 @@
1
- import { jsxs as _, jsx as d } from "react/jsx-runtime";
1
+ import { jsx as c, jsxs as E, Fragment as N } from "react/jsx-runtime";
2
2
  import "react";
3
- import { useFormContext as v } from "react-hook-form";
4
- import N from "../client/config/useRhfUtilsClientConfigContext.mjs";
5
- import P from "../devtool/LazyDevTool.mjs";
6
- import { FormSubmitError as x } from "../submit/error/FormSubmitError.mjs";
7
- import S from "../submit/error/setCtxErrorsByFormSubmitErrors.mjs";
8
- import w from "./_Controller.mjs";
9
- import E from "./_FormBase.mjs";
3
+ import { useFormContext as P } from "react-hook-form";
4
+ import f from "../client/config/useRhfUtilsClientConfigContext.mjs";
5
+ import w from "../devtool/LazyDevTool.mjs";
6
+ import { FormSubmitError as C } from "../submit/error/FormSubmitError.mjs";
7
+ import B from "../submit/error/setCtxErrorsByFormSubmitErrors.mjs";
8
+ import S from "./_Controller.mjs";
10
9
  function A({
11
- formId: s,
10
+ formId: e,
12
11
  formRef: m,
13
12
  //
14
- onSubmit: c,
15
- onSubmitError: C,
16
- onSubmitInvalid: b,
13
+ onSubmit: s,
14
+ onSubmitError: d,
15
+ onSubmitInvalid: y,
17
16
  Children: h,
18
17
  //
19
18
  form: p,
20
- utils: o,
21
- //
22
- children: i
19
+ utils: o
23
20
  }) {
24
- const n = v(), r = N(), j = async (t) => {
21
+ const n = P(), r = f(), i = async (t) => {
25
22
  o != null && o.stopSubmitPropagation && t.stopPropagation();
26
23
  try {
27
- await n.handleSubmit(B, b)(t);
28
- } catch (e) {
29
- T(e, t);
24
+ await n.handleSubmit(b, y)(t);
25
+ } catch (a) {
26
+ j(a, t);
30
27
  }
31
- }, B = (t, e) => c == null ? void 0 : c(
28
+ }, b = (t, a) => s == null ? void 0 : s(
32
29
  t,
33
30
  {
34
- formId: s,
31
+ formId: e,
35
32
  formRef: m,
36
33
  context: n,
37
34
  utils: o,
38
- FormSubmitError: x
35
+ FormSubmitError: C
39
36
  },
40
- e
41
- ), T = (t, e) => {
42
- var F;
43
- const a = t instanceof x ? (
37
+ a
38
+ ), j = (t, a) => {
39
+ var l;
40
+ const F = t instanceof C ? (
44
41
  // consumer can manually throw FormSubmitError (e.g., manual validation)
45
42
  t.errors
46
43
  ) : (
47
44
  // if error is not FormSubmitError, consumer can provide global handler
48
- (F = r == null ? void 0 : r.onSubmitUnknownError) == null ? void 0 : F.call(r, t)
45
+ (l = r == null ? void 0 : r.onSubmitUnknownError) == null ? void 0 : l.call(r, t)
49
46
  );
50
- a && S(n, a), C == null || C(
47
+ F && B(n, F), d == null || d(
51
48
  t,
52
49
  {
53
- formId: s,
50
+ formId: e,
54
51
  formRef: m,
55
52
  context: n,
56
53
  utils: o
57
54
  },
58
- e
55
+ a
59
56
  );
60
- }, l = {
61
- formId: s,
57
+ }, x = {
58
+ formId: e,
62
59
  formRef: m,
63
60
  context: n,
64
61
  utils: o,
65
- Controller: w,
66
- FormSubmitError: x
67
- }, y = (t) => {
68
- var a;
69
- const e = (a = r == null ? void 0 : r.Children) == null ? void 0 : a[t];
70
- return e && /* @__PURE__ */ d(e, { ...l });
71
- };
72
- return /* @__PURE__ */ _(
73
- E,
62
+ Controller: S,
63
+ FormSubmitError: C
64
+ }, T = (r == null ? void 0 : r.FormComponent) ?? "form", v = (r == null ? void 0 : r.FormChildren) ?? U;
65
+ return /* @__PURE__ */ c(
66
+ T,
74
67
  {
75
68
  noValidate: !0,
76
- Component: r == null ? void 0 : r.FormComponent,
77
- formRef: m,
69
+ ref: m,
78
70
  ...p,
79
71
  className: [o == null ? void 0 : o.classNames, p == null ? void 0 : p.className].filter(Boolean).join(" "),
80
- onSubmit: j,
81
- children: [
82
- y("top"),
83
- (o == null ? void 0 : o.devTool) && /* @__PURE__ */ d(
84
- P,
72
+ onSubmit: i,
73
+ children: /* @__PURE__ */ E(v, { ...x, children: [
74
+ (o == null ? void 0 : o.devTool) && /* @__PURE__ */ c(
75
+ w,
85
76
  {
86
77
  props: typeof o.devTool == "object" ? o.devTool : void 0
87
78
  }
88
79
  ),
89
- h && /* @__PURE__ */ d(h, { ...l }),
90
- i,
91
- y("bottom")
92
- ]
80
+ h && /* @__PURE__ */ c(h, { ...x })
81
+ ] })
93
82
  }
94
83
  );
95
84
  }
85
+ function U({
86
+ children: e
87
+ }) {
88
+ return /* @__PURE__ */ c(N, { children: e });
89
+ }
96
90
  export {
97
91
  A as default
98
92
  };
@@ -1,14 +1,11 @@
1
1
  import { jsx as o } from "react/jsx-runtime";
2
- import t from "./Form.mjs";
3
- import f from "./RhfUtilsFormProviders.mjs";
4
- import s from "./useRhfUtilsForm.mjs";
5
- function h({
6
- children: m,
7
- ...i
8
- }) {
9
- const r = s(i);
10
- return /* @__PURE__ */ o(f, { ...r.providerProps, children: /* @__PURE__ */ o(t, { ...r.formProps, children: m }) });
2
+ import i from "./Form.mjs";
3
+ import t from "./RhfUtilsFormProviders.mjs";
4
+ import f from "./useRhfUtilsForm.mjs";
5
+ function n(m) {
6
+ const r = f(m);
7
+ return /* @__PURE__ */ o(t, { ...r.providerProps, children: /* @__PURE__ */ o(i, { ...r.formProps }) });
11
8
  }
12
9
  export {
13
- h as default
10
+ n as default
14
11
  };
@@ -1,7 +1,7 @@
1
1
  import { UseFormProps } from 'react-hook-form';
2
2
  import { FlatFieldErrorsOutputConfig } from '../../errors/flat/context/FlatFieldErrorsOutputConfig';
3
- import { FormChildrenSlots } from '../../form/Form';
4
3
  import { RhfUtilsFormOptions } from '../../form/RhfUtilsFormOptions';
4
+ import { SafeFieldValues } from '../../form/SafeFieldValues';
5
5
  import { UseRhfUtilsFormChildrenProps } from '../../form/UseRhfUtilsFormChildrenProps';
6
6
  import { FormSubmitErrors } from '../../submit/error/FormSubmitErrors';
7
7
 
@@ -34,6 +34,14 @@ export type RhfUtilsClientConfig = {
34
34
  * By default, a primitive `<form>` element is used.
35
35
  */
36
36
  FormComponent?: React.FC<React.PropsWithChildren<React.HTMLAttributes<HTMLFormElement>>>;
37
+ /**
38
+ * Wrap all form bodies with your own hooks, components, etc.
39
+ *
40
+ * Use cases:
41
+ * - custom hooks/behaviors based on `options`
42
+ * - shared header, footer
43
+ */
44
+ FormChildren?: <TFieldValues extends SafeFieldValues, TTransformedValues extends SafeFieldValues>(props: React.PropsWithChildren<UseRhfUtilsFormChildrenProps<TFieldValues, TTransformedValues>>) => React.ReactNode;
37
45
  /**
38
46
  * Global submit error handler when/if submit handler throws an error other than {@link FormSubmitError}.
39
47
  *
@@ -45,14 +53,6 @@ export type RhfUtilsClientConfig = {
45
53
  * - if `undefined`: do nothing.
46
54
  */
47
55
  onSubmitUnknownError?: (error: unknown) => FormSubmitErrors | undefined;
48
- /**
49
- * Components injected by slot across all forms.
50
- * (Per-form injection can be done via `Children` prop.)
51
- *
52
- * - `top`: e.g., block navigation on dirty form.
53
- * - `bottom`: e.g., root errors list.
54
- */
55
- Children?: Partial<Record<FormChildrenSlots, React.FC<UseRhfUtilsFormChildrenProps>>>;
56
56
  errors?: {
57
57
  /**
58
58
  * Configure how/if errors should be outputted.
@@ -3,9 +3,9 @@ import { SafeFieldValues } from './SafeFieldValues';
3
3
  import { UseRhfUtilsFormProps } from './UseRhfUtilsFormProps';
4
4
 
5
5
  export type FormChildrenSlots = 'top' | 'bottom';
6
- export type FormProps<TFieldValues extends SafeFieldValues, TTransformedValues extends SafeFieldValues> = React.PropsWithChildren<{
6
+ export type FormProps<TFieldValues extends SafeFieldValues, TTransformedValues extends SafeFieldValues> = {
7
7
  formId: string;
8
8
  formRef: React.RefObject<HTMLFormElement>;
9
- } & Pick<UseRhfUtilsFormProps<TFieldValues, TTransformedValues>, 'onSubmit' | 'onSubmitError' | 'onSubmitInvalid' | 'Children' | 'form' | 'utils'>>;
10
- declare function _Form<TFieldValues extends SafeFieldValues, TTransformedValues extends SafeFieldValues>({ formId, formRef, onSubmit, onSubmitError, onSubmitInvalid, Children, form, utils, children, }: FormProps<TFieldValues, TTransformedValues>): import("react/jsx-runtime").JSX.Element;
9
+ } & Pick<UseRhfUtilsFormProps<TFieldValues, TTransformedValues>, 'onSubmit' | 'onSubmitError' | 'onSubmitInvalid' | 'Children' | 'form' | 'utils'>;
10
+ declare function _Form<TFieldValues extends SafeFieldValues, TTransformedValues extends SafeFieldValues>({ formId, formRef, onSubmit, onSubmitError, onSubmitInvalid, Children, form, utils, }: FormProps<TFieldValues, TTransformedValues>): import("react/jsx-runtime").JSX.Element;
11
11
  export default _Form;
@@ -9,5 +9,5 @@ export type FormWithProvidersProps<TFieldValues extends SafeFieldValues, TTransf
9
9
  * Use {@link useRhfUtilsForm} if you need to specific nesting hierarchy.
10
10
  * (e.g., wrapping `<tr>` with provider and nesting `<form>` within `<td>` to appease HTML rules.)
11
11
  */
12
- declare function FormWithProviders<TFieldValues extends SafeFieldValues, TTransformedValues extends SafeFieldValues>({ children, ...props }: FormWithProvidersProps<TFieldValues, TTransformedValues>): import("react/jsx-runtime").JSX.Element;
12
+ declare function FormWithProviders<TFieldValues extends SafeFieldValues, TTransformedValues extends SafeFieldValues>(props: FormWithProvidersProps<TFieldValues, TTransformedValues>): import("react/jsx-runtime").JSX.Element;
13
13
  export default FormWithProviders;
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.117",
5
+ "version": "0.0.118",
6
6
  "description": "Integration utilities for react-hook-form.",
7
7
  "type": "module",
8
8
  "sideEffects": false,
@@ -1,11 +0,0 @@
1
- import { jsx as m } from "react/jsx-runtime";
2
- import "react";
3
- const s = ({
4
- formRef: o,
5
- Component: r,
6
- children: t,
7
- ...e
8
- }) => /* @__PURE__ */ m(r ?? "form", { role: "form", ...e, ref: o, children: t });
9
- export {
10
- s as default
11
- };