@paragrav/rhf-utils 0.0.102 → 0.0.104

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
@@ -10,11 +10,19 @@ yarn add @paragrav/rhf-utils # yarn
10
10
 
11
11
  ## Config
12
12
 
13
- To configure, create a file like `src/integrations/paragrav-rhf-utils/config.tsx` with desired config:
13
+ To configure, create a file like `src/integrations/paragrav-rhf-utils/config.tsx` with desired config. This is global configuration across all forms.
14
+
15
+ ```tsx
16
+ export const config: RhfUtilsClientConfig = {
17
+ isDevelopment: import.meta.env.DEV,
14
18
 
15
- ```ts
16
- const config: ClientConfig = {
17
19
  defaultOptions: {
20
+ // UseFormProps
21
+ rhf: {
22
+ mode: 'onBlur',
23
+ },
24
+
25
+ // UseFormOptions
18
26
  form: {
19
27
  devTool: {
20
28
  placement: 'top-right',
@@ -24,25 +32,33 @@ const config: ClientConfig = {
24
32
 
25
33
  FormComponent: Form.Root,
26
34
 
27
- onSubmitError: (error) => {
35
+ // transform backend error
36
+ onSubmitError: (
37
+ error, // unknown
38
+ ) => {
39
+ // if other error, re-throw to handle
28
40
  if (!(error instanceof TRPCClientError)) throw error;
29
41
 
42
+ // transform
43
+ const errors = transformToFormSubmitError(error);
30
44
 
31
- const errors = trcpClientErrorToRhfErrorTransformer.parse(error);
32
-
45
+ // return to be merged in RHF context errors
33
46
  return new FormSubmitError(errors);
34
47
  },
35
48
 
36
49
  Children: {
37
- top: function Top({ options }) {
38
- // navigation blocker
50
+ top: (
51
+ { options }, // UseFormFieldsProps
52
+ ) => {
53
+ // navigation blocker (using custom option)
39
54
  useFormRouterBlocker(!!options?.prompter);
40
55
 
41
56
  return null;
42
57
  },
58
+
43
59
  bottom: () => (
44
60
  <>
45
- // global error list
61
+ {/* global error list */}
46
62
  <RootErrorsListFromFlatFieldErrorsContext />
47
63
  </>
48
64
  ),
@@ -52,7 +68,7 @@ const config: ClientConfig = {
52
68
 
53
69
  ## Provider
54
70
 
55
- And add our context provider to your stack:
71
+ And add the context provider to your stack:
56
72
 
57
73
  ```tsx
58
74
  <RhfUtilsClientForZodContextProvider config={config}>
@@ -62,4 +78,68 @@ And add our context provider to your stack:
62
78
 
63
79
  ## Usage
64
80
 
65
- Coming soon.
81
+ ```tsx
82
+ <RhfUtilsZodForm
83
+ schema={authLoginFormSchema}
84
+ defaultValues={{
85
+ email: '',
86
+ }}
87
+ // submit handler
88
+ onSubmit={async (data) => {
89
+ await authLoginService(data);
90
+ onSuccess();
91
+ }}
92
+ // handle error declaratively (i.e., no throw/catch)
93
+ onSubmitError={({
94
+ error, // unknown
95
+ context, // rhf UseFormReturn
96
+ event, // SubmitEvent
97
+ }) => {
98
+ onError(error);
99
+ }}
100
+ // fields
101
+ Fields={({
102
+ formId, // unique id string
103
+ formRef, // ref
104
+ context, // rhf UseFormReturn
105
+ options, // UseFormOptions
106
+ Controller, // strongly-typed controlled
107
+ }) => (
108
+ <>
109
+ <Controller
110
+ name="email" // strongly-typed field name
111
+ render={({ field, formState: { isSubmitting } }) => (
112
+ <input
113
+ autoFocus
114
+ label="Email"
115
+ autoComplete="email"
116
+ disabled={isSubmitting}
117
+ {...field}
118
+ />
119
+ )}
120
+ />
121
+
122
+ <button type="submit">Login</button>
123
+ </>
124
+ )}
125
+ />
126
+ ```
127
+
128
+ `Fields` is a component which is rendered as a child of the form. It receives `UseFormFieldsProps` as props, including type-safe `Controller`.
129
+
130
+ ## Extend Options
131
+
132
+ Extend `UseFormOptions` with custom options, which get passed to `Fields` component in `options` prop.
133
+
134
+ ```tsx
135
+ import '@paragrav/rhf-utils';
136
+
137
+ declare module '@paragrav/rhf-utils' {
138
+ export interface Register {
139
+ UseFormOptions: {
140
+ /** Enable user prompt to confirm navigating away from dirty form. */
141
+ prompter?: boolean;
142
+ };
143
+ }
144
+ }
145
+ ```
@@ -0,0 +1,12 @@
1
+ import { jsx as e } from "react/jsx-runtime";
2
+ import i from "./context/useRhfUtilsClientForZodContext.mjs";
3
+ function f({
4
+ schema: o,
5
+ ...t
6
+ }) {
7
+ const r = i();
8
+ return /* @__PURE__ */ e(r.FormWithProviders, { schema: o, ...t });
9
+ }
10
+ export {
11
+ f as default
12
+ };
@@ -1,24 +1,24 @@
1
1
  import { default as e } from "./client/zod/context/RhfUtilsClientForZodContextProvider.mjs";
2
- import { default as s } from "./client/zod/context/RhfUtilsZodFormWithProviders.mjs";
3
- import { default as f } from "./client/zod/context/useRhfUtilsClientForZodContext.mjs";
4
- import { default as m } from "./client/zod/context/useRhfUtilsZodForm.mjs";
2
+ import { default as s } from "./client/zod/context/useRhfUtilsClientForZodContext.mjs";
3
+ import { default as f } from "./client/zod/context/useRhfUtilsZodForm.mjs";
4
+ import { default as m } from "./client/zod/RhfUtilsZodForm.mjs";
5
5
  import { default as d } from "./devtool/LazyDevTool.mjs";
6
6
  import { default as x } from "./errors/flat/context/useFlatFieldErrorsContext.mjs";
7
7
  import { default as i } from "./errors/flat/FlatFieldErrorsList.mjs";
8
8
  import { default as E } from "./errors/message/FormErrorMessage.mjs";
9
9
  import { default as C } from "./errors/message/FormErrorMessageByPath.mjs";
10
10
  import { default as G } from "./errors/nonfield/FormNonFieldErrorMarker.mjs";
11
- import { default as P } from "./errors/nonfield/FormNonFieldErrorMarkerHtmlAttribute.mjs";
12
- import { default as I } from "./errors/orphan/useFormHasOnlyOrphanFieldErrorsMemo.mjs";
11
+ import { default as c } from "./errors/nonfield/FormNonFieldErrorMarkerHtmlAttribute.mjs";
12
+ import { default as P } from "./errors/orphan/useFormHasOnlyOrphanFieldErrorsMemo.mjs";
13
13
  import { default as B } from "./errors/orphan/useOrphanFormErrorsMemo.mjs";
14
14
  import { default as b } from "./errors/root/RootErrorsListFromFlatFieldErrorsContext.mjs";
15
- import { default as O } from "./errors/root/useRootFormFieldErrorsMemo.mjs";
16
- import { default as T } from "./errors/useFormErrorsEffect.mjs";
17
- import { default as g } from "./errors/useFormErrorsIfAny.mjs";
15
+ import { default as S } from "./errors/root/useRootFormFieldErrorsMemo.mjs";
16
+ import { default as U } from "./errors/useFormErrorsEffect.mjs";
17
+ import { default as v } from "./errors/useFormErrorsIfAny.mjs";
18
18
  import { default as A } from "./form/FormWithProviders.mjs";
19
19
  import { default as D } from "./form/useForm.mjs";
20
20
  import { default as N } from "./form/context/utils/useFormUtilsContext.mjs";
21
- import { default as z } from "./form/context/group/FormGroupContextProvider.mjs";
21
+ import { default as W } from "./form/context/group/FormGroupContextProvider.mjs";
22
22
  import { default as q } from "./form/context/group/useFormGroupChildIsMountedTracker.mjs";
23
23
  import { default as J } from "./form/context/group/useFormGroupChildIsSubmittingTracker.mjs";
24
24
  import { default as Q } from "./form/context/group/useFormGroupChildTracker.mjs";
@@ -34,20 +34,20 @@ export {
34
34
  i as FlatFieldErrorsList,
35
35
  E as FormErrorMessage,
36
36
  C as FormErrorMessageByPath,
37
- z as FormGroupContextProvider,
37
+ W as FormGroupContextProvider,
38
38
  G as FormNonFieldErrorMarker,
39
- P as FormNonFieldErrorMarkerHtmlAttribute,
39
+ c as FormNonFieldErrorMarkerHtmlAttribute,
40
40
  mr as FormSubmitError,
41
41
  A as FormWithProviders,
42
42
  d as LazyDevTool,
43
43
  e as RhfUtilsClientForZodContextProvider,
44
- s as RhfUtilsZodFormWithProviders,
44
+ m as RhfUtilsZodForm,
45
45
  b as RootErrorsListFromFlatFieldErrorsContext,
46
46
  fr as getSubmitterButtonData,
47
47
  x as useFlatFieldErrorsContext,
48
48
  D as useForm,
49
- T as useFormErrorsEffect,
50
- g as useFormErrorsIfAny,
49
+ U as useFormErrorsEffect,
50
+ v as useFormErrorsIfAny,
51
51
  q as useFormGroupChildIsMountedTracker,
52
52
  J as useFormGroupChildIsSubmittingTracker,
53
53
  Q as useFormGroupChildTracker,
@@ -55,12 +55,12 @@ export {
55
55
  _ as useFormGroupIsChildBusy,
56
56
  rr as useFormGroupIsParentBusy,
57
57
  er as useFormGroupParentTracker,
58
- I as useFormHasOnlyOrphanFieldErrorsMemo,
58
+ P as useFormHasOnlyOrphanFieldErrorsMemo,
59
59
  dr as useFormOnSubmitSuccessful,
60
60
  sr as useFormOrParentIsBusy,
61
61
  N as useFormUtilsContext,
62
62
  B as useOrphanFormErrorsMemo,
63
- f as useRhfUtilsClientForZodContext,
64
- m as useRhfUtilsZodForm,
65
- O as useRootFormFieldErrorsMemo
63
+ s as useRhfUtilsClientForZodContext,
64
+ f as useRhfUtilsZodForm,
65
+ S as useRootFormFieldErrorsMemo
66
66
  };
@@ -1,4 +1,4 @@
1
- import { jsxs as F, jsx as o } from "react/jsx-runtime";
1
+ import { jsxs as F, jsx as c } from "react/jsx-runtime";
2
2
  import "react";
3
3
  import { useFormContext as _ } from "react-hook-form";
4
4
  import j from "../client/config/useRhfUtilsClientConfigContext.mjs";
@@ -12,7 +12,7 @@ function q({
12
12
  formRef: C,
13
13
  //
14
14
  onSubmit: d,
15
- onSubmitError: c,
15
+ onSubmitError: o,
16
16
  onSubmitInvalid: y,
17
17
  Fields: h,
18
18
  //
@@ -41,7 +41,7 @@ function q({
41
41
  // if error is not FormSubmitError, consumer can provide global handler
42
42
  (n = e == null ? void 0 : e.onSubmitError) == null ? void 0 : n.call(e, r)
43
43
  );
44
- m && P(l, m), c == null || c(
44
+ m && P(l, m), o == null || o(
45
45
  r,
46
46
  l,
47
47
  a
@@ -49,13 +49,13 @@ function q({
49
49
  }, u = {
50
50
  formId: x,
51
51
  formRef: C,
52
- ctx: l,
52
+ context: l,
53
53
  options: t,
54
54
  Controller: S
55
55
  }, i = (r) => {
56
56
  var m;
57
57
  const a = (m = e == null ? void 0 : e.Children) == null ? void 0 : m[r];
58
- return a && /* @__PURE__ */ o(a, { ...u });
58
+ return a && /* @__PURE__ */ c(a, { ...u });
59
59
  };
60
60
  return /* @__PURE__ */ F(
61
61
  T,
@@ -71,7 +71,7 @@ function q({
71
71
  onSubmit: b,
72
72
  children: [
73
73
  i("top"),
74
- (t == null ? void 0 : t.devTool) !== "disabled" && /* @__PURE__ */ o(
74
+ (t == null ? void 0 : t.devTool) !== "disabled" && /* @__PURE__ */ c(
75
75
  D,
76
76
  {
77
77
  placement: "top-right",
@@ -79,7 +79,7 @@ function q({
79
79
  ...t == null ? void 0 : t.devTool
80
80
  }
81
81
  ),
82
- h && /* @__PURE__ */ o(h, { ...u }),
82
+ h && /* @__PURE__ */ c(h, { ...u }),
83
83
  f,
84
84
  i("bottom")
85
85
  ]
@@ -28,23 +28,47 @@ export type RhfUtilsClientConfig = {
28
28
  form?: UseFormOptions;
29
29
  };
30
30
  /**
31
- * Components injected by slot across all forms.
32
- * (Per-form injection can be done via Fields prop.)
31
+ * Supply your own `<form>` component.
33
32
  *
34
- * top: e.g., block navigation on dirty form.
35
- * bottom: e.g., root errors list.
33
+ * By default, a primitive `<form>` element is used.
36
34
  */
37
- Children?: Partial<Record<FormChildrenSlots, React.FC<UseFormFieldsProps>>>;
35
+ FormComponent?: React.FC<React.PropsWithChildren<React.HTMLAttributes<HTMLFormElement>>>;
38
36
  /**
39
37
  * Handle non-{@link FormSubmitError} errors. Optionally, return {@link FormSubmitError} to merge into context errors.
38
+ *
39
+ * Example use case:
40
+ * - transform API errors to {@link FormSubmitError}.
40
41
  */
41
42
  onSubmitError?: (error: unknown) => FormSubmitError | undefined;
42
- FormComponent?: React.FC<React.PropsWithChildren<React.HTMLAttributes<HTMLFormElement>>>;
43
+ /**
44
+ * Components injected by slot across all forms.
45
+ * (Per-form injection can be done via Fields prop.)
46
+ *
47
+ * - `top`: e.g., block navigation on dirty form.
48
+ * - `bottom`: e.g., root errors list.
49
+ */
50
+ Children?: Partial<Record<FormChildrenSlots, React.FC<UseFormFieldsProps>>>;
43
51
  errors?: {
52
+ /**
53
+ * Configure how/if errors should be outputted.
54
+ */
44
55
  output?: {
56
+ /**
57
+ * Configure how/if errors should be outputted to console.
58
+ *
59
+ * Example use cases:
60
+ * - console.debug errors in development environment.
61
+ * - console.error certain errors in production environment.
62
+ */
45
63
  console?: {
46
64
  getConfig?: (context: RhfUtilsErrorsOutputConfigContext) => RhfUtilsErrorsOutputConsoleConfig | null;
47
65
  };
66
+ /**
67
+ * Configure how/if errors should be thrown.
68
+ *
69
+ * Example use case:
70
+ * - bring attention to certain errors in development environment.
71
+ */
48
72
  throw?: {
49
73
  getConfig?: (context: RhfUtilsErrorsOutputConfigContext) => true | string | false;
50
74
  };
@@ -0,0 +1,8 @@
1
+ import { UseFormProps } from '../../form/useForm';
2
+ import { ZodTypeFieldValues } from './createRhfUtilsClientForZod';
3
+
4
+ type Props<TSchema extends ZodTypeFieldValues> = {
5
+ schema: TSchema;
6
+ } & Omit<UseFormProps<TSchema['_input'], TSchema['_output']>, 'config'>;
7
+ declare function RhfUtilsZodForm<TSchema extends ZodTypeFieldValues>({ schema, ...props }: Props<TSchema>): import("react/jsx-runtime").JSX.Element;
8
+ export default RhfUtilsZodForm;
@@ -0,0 +1,4 @@
1
+ import { UseFormFieldsProps } from '../../form/useForm';
2
+ import { ZodTypeFieldValues } from './createRhfUtilsClientForZod';
3
+
4
+ export type UseFormFieldsZodProps<TSchema extends ZodTypeFieldValues> = UseFormFieldsProps<TSchema['_input'], TSchema['_output']>;
@@ -3,7 +3,6 @@ import { ZodTypeFieldValues } from '../createRhfUtilsClientForZod';
3
3
 
4
4
  type Props<TSchema extends ZodTypeFieldValues> = {
5
5
  schema: TSchema;
6
- form: Omit<UseFormProps<TSchema['_input'], TSchema['_output']>, 'config'>;
7
- };
8
- declare function RhfUtilsZodFormWithProviders<TSchema extends ZodTypeFieldValues>({ schema, form, }: Props<TSchema>): import("react/jsx-runtime").JSX.Element;
6
+ } & Omit<UseFormProps<TSchema['_input'], TSchema['_output']>, 'config'>;
7
+ declare function RhfUtilsZodFormWithProviders<TSchema extends ZodTypeFieldValues>({ schema, ...props }: Props<TSchema>): import("react/jsx-runtime").JSX.Element;
9
8
  export default RhfUtilsZodFormWithProviders;
@@ -0,0 +1,14 @@
1
+ import { FieldErrors } from 'react-hook-form';
2
+ import { SafeFieldValues } from '../form/SafeFieldValues';
3
+
4
+ /**
5
+ * Output form values and errors to console.
6
+ */
7
+ declare const consoleErrors: (message: string, form: {
8
+ values: SafeFieldValues;
9
+ errors: FieldErrors;
10
+ }, options?: {
11
+ other?: Record<string, unknown>;
12
+ isError?: boolean;
13
+ }) => void;
14
+ export default consoleErrors;
@@ -0,0 +1,9 @@
1
+ import { default as React } from 'react';
2
+
3
+ /**
4
+ * Logs out orphan errors to console.error.
5
+ *
6
+ * In development, it will also throw an error to bring attention to dev.
7
+ */
8
+ declare const useOrphanFormErrorsToConsole: (formRef: React.RefObject<HTMLFormElement>, enabled?: boolean) => void;
9
+ export default useOrphanFormErrorsToConsole;
@@ -0,0 +1,14 @@
1
+ import { FieldErrors } from 'react-hook-form';
2
+ import { SafeFieldValues } from '../form/SafeFieldValues';
3
+
4
+ /**
5
+ * Output form values and errors to console and throw in dev.
6
+ */
7
+ declare const outputErrors: (message: string, form: {
8
+ values: SafeFieldValues;
9
+ errors: FieldErrors;
10
+ }, options?: {
11
+ other?: Record<string, unknown>;
12
+ isError?: boolean;
13
+ }) => void;
14
+ export default outputErrors;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Output form errors to console.debug() for easier debugging for certain condition.
3
+ * (e.g., in dev/staging environments or certain users)
4
+ *
5
+ * `console.debug()` is unlikely to trigger any automated console capture reporting.
6
+ */
7
+ declare const useFormErrorConsoleDebug: (enabled?: boolean) => void;
8
+ export default useFormErrorConsoleDebug;
@@ -0,0 +1,13 @@
1
+ import { FlatFieldErrors } from './flat/types';
2
+
3
+ /**
4
+ * Logs out orphan errors to console.error.
5
+ *
6
+ * In development, it will also throw an error to bring attention to dev.
7
+ */
8
+ declare const useFormErrorsToConsole: (message: string, flatErrors: FlatFieldErrors, options?: {
9
+ disabled?: boolean;
10
+ isError?: boolean;
11
+ data?: Record<string, unknown>;
12
+ }) => void;
13
+ export default useFormErrorsToConsole;
@@ -1,9 +1,10 @@
1
1
  export type { Register } from './register';
2
2
  export type { RhfUtilsClientConfig } from './client/config/RhfUtilsClientConfig';
3
3
  export { default as RhfUtilsClientForZodContextProvider } from './client/zod/context/RhfUtilsClientForZodContextProvider';
4
- export { default as RhfUtilsZodFormWithProviders } from './client/zod/context/RhfUtilsZodFormWithProviders';
5
4
  export { default as useRhfUtilsClientForZodContext } from './client/zod/context/useRhfUtilsClientForZodContext';
6
5
  export { default as useRhfUtilsZodForm } from './client/zod/context/useRhfUtilsZodForm';
6
+ export { default as RhfUtilsZodForm } from './client/zod/RhfUtilsZodForm';
7
+ export type { UseFormFieldsZodProps } from './client/zod/UseFormFieldsZodProps';
7
8
  export { default as LazyDevTool } from './devtool/LazyDevTool';
8
9
  export { default as useFlatFieldErrorsContext } from './errors/flat/context/useFlatFieldErrorsContext';
9
10
  export { default as FlatFieldErrorsList } from './errors/flat/FlatFieldErrorsList';
@@ -10,7 +10,7 @@ import { UseFormOptions } from './useFormOptions';
10
10
  export type UseFormFieldsProps<TFieldValues extends SafeFieldValues = SafeFieldValues, TTransformedValues extends SafeFieldValues = SafeFieldValues> = {
11
11
  formId: string;
12
12
  formRef: React.RefObject<HTMLFormElement>;
13
- ctx: RhfUseFormReturn<TFieldValues, unknown, TTransformedValues>;
13
+ context: RhfUseFormReturn<TFieldValues, unknown, TTransformedValues>;
14
14
  options?: UseFormOptions;
15
15
  Controller: typeof _Controller<TFieldValues>;
16
16
  };
@@ -1,5 +1,6 @@
1
1
  /**
2
2
  * Use this to extend internal types.
3
+ *
3
4
  * For example, `UseFormOptions`.
4
5
  */
5
6
  export interface Register {
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.102",
5
+ "version": "0.0.104",
6
6
  "description": "Integration utilities for react-hook-form.",
7
7
  "type": "module",
8
8
  "sideEffects": false,
@@ -1,12 +0,0 @@
1
- import { jsx as i } from "react/jsx-runtime";
2
- import e from "./useRhfUtilsClientForZodContext.mjs";
3
- function f({
4
- schema: o,
5
- form: t
6
- }) {
7
- const r = e();
8
- return /* @__PURE__ */ i(r.FormWithProviders, { schema: o, ...t });
9
- }
10
- export {
11
- f as default
12
- };