@paragrav/rhf-utils 0.0.121 → 0.0.125

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.
Files changed (30) hide show
  1. package/README.md +12 -9
  2. package/dist/esm/devtool/LazyDevTool.mjs +1 -2
  3. package/dist/esm/errors/flat/context/FlatFieldErrorsContextProvider.mjs +1 -1
  4. package/dist/esm/errors/flat/context/useFlatFieldErrorsContextOutput.mjs +1 -2
  5. package/dist/esm/errors/flat/getFlatFieldErrors.mjs +1 -2
  6. package/dist/esm/exports.mjs +25 -23
  7. package/dist/esm/form/Form.mjs +41 -33
  8. package/dist/esm/form/context/utils/RhfUtilsContextProvider.mjs +22 -23
  9. package/dist/esm/form/utils/useFormRequestSubmit.mjs +1 -2
  10. package/dist/esm/form/utils/useShouldFormBlockNavigation.mjs +9 -0
  11. package/dist/esm/submit/useFormOnSubmitSuccessfulAndReset.mjs +7 -9
  12. package/dist/esm/submit/useFormOnSubmitted.mjs +12 -0
  13. package/dist/esm/submit/useResetFormOnSubmitted.mjs +21 -0
  14. package/dist/esm/submit/useSubmitFormOnChange.mjs +9 -11
  15. package/dist/esm/utils/createContext.mjs +1 -2
  16. package/dist/esm/utils/useRefIfValueWasTrue.mjs +14 -0
  17. package/dist/types/exports.d.ts +1 -0
  18. package/dist/types/form/RhfUtilsFormOptions.d.ts +5 -7
  19. package/dist/types/form/UseRhfUtilsFormProps.d.ts +2 -1
  20. package/dist/types/form/utils/useShouldFormBlockNavigation.d.ts +13 -0
  21. package/dist/types/submit/useFormOnSubmitSuccessfulAndReset.d.ts +4 -2
  22. package/dist/types/submit/useFormOnSubmitted.d.ts +6 -0
  23. package/dist/types/submit/useResetFormOnSubmitted.d.ts +23 -0
  24. package/dist/types/submit/useSubmitFormOnChange.d.ts +1 -0
  25. package/dist/types/utils/types.d.ts +1 -0
  26. package/dist/types/utils/useRefIfValueWasTrue.d.ts +1 -0
  27. package/package.json +1 -1
  28. package/dist/esm/submit/useFormOnSubmitSuccessful.mjs +0 -11
  29. package/dist/esm/submit/useResetFormOnSubmitError.mjs +0 -18
  30. package/dist/esm/submit/useResetFormOnSubmitSuccessful.mjs +0 -20
package/README.md CHANGED
@@ -171,7 +171,10 @@ Currently, only `zod` is supported.
171
171
  }}
172
172
  utils={{
173
173
  submitOnChange: true,
174
- resetValuesOnSubmitError: true,
174
+ resetValuesOnSubmitted: {
175
+ onSuccess: 'current',
176
+ onError: 'defaults',
177
+ },
175
178
  // custom option props
176
179
  // (see "Extend RhfUtilsFormOptions" section)
177
180
  enableMyFormNavigationPrompt: true,
@@ -235,17 +238,17 @@ These options can be set globally and/or per form.
235
238
 
236
239
  ```ts
237
240
  type RhfUtilsFormOptions = {
238
- /** Request submit via listener on form change. */
239
- submitOnChange?: boolean;
240
-
241
- /** Reset form values if submit throw errors. (Use case: optimistic UI toggle form that submits on each change.) */
242
- resetValuesOnSubmitError?: boolean;
243
-
244
241
  /** Stop propagation of submit event. Useful for portals. */
245
242
  stopSubmitPropagation?: boolean;
246
243
 
247
- /** Reset form after successful submit. */
248
- resetFormAfterSubmitSuccessful?: UseResetFormAfterSubmitSuccessfulOptions;
244
+ /** Request submit via listener on form change. */
245
+ submitOnChange?: boolean;
246
+
247
+ /** Reset form after submitted. */
248
+ resetFormOnSubmitted?: {
249
+ onSuccess?: 'defaults' | 'current';
250
+ onError?: 'defaults';
251
+ };
249
252
 
250
253
  /** Control dev tool options. (Lazy-loaded when truthy value supplied.) */
251
254
  devTool?: true | Pick<DevtoolUIProps, 'placement' | 'styles'>;
@@ -6,8 +6,7 @@ const a = e.lazy(
6
6
  default: o.DevTool
7
7
  }))
8
8
  ), u = ({ isDevelopment: o, props: r }) => {
9
- if (!o)
10
- return null;
9
+ if (!o) return null;
11
10
  const { control: l } = n();
12
11
  return /* @__PURE__ */ t(e.Suspense, { fallback: null, children: /* @__PURE__ */ t(a, { control: l, ...r }) });
13
12
  };
@@ -18,7 +18,7 @@ const C = ({
18
18
  orphans: s,
19
19
  // computed
20
20
  hasErrors: !e(t),
21
- hasOrphans: e(s)
21
+ hasOrphans: !e(s)
22
22
  };
23
23
  return /* @__PURE__ */ a(f, { value: i, children: m });
24
24
  };
@@ -6,8 +6,7 @@ const C = (r) => {
6
6
  const l = p(), t = F();
7
7
  u.useEffect(() => {
8
8
  var o, m;
9
- if (!t.hasErrors)
10
- return;
9
+ if (!t.hasErrors) return;
11
10
  const e = (o = r == null ? void 0 : r.console) == null ? void 0 : o.call(r, t);
12
11
  e && E(
13
12
  e.message ?? a,
@@ -9,8 +9,7 @@ const u = (t) => {
9
9
  d,
10
10
  ""
11
11
  );
12
- if (r === o)
13
- return e;
12
+ if (r === o) return e;
14
13
  const f = c(t, r, void 0);
15
14
  return f && e.push([r, f]), e;
16
15
  },
@@ -1,5 +1,5 @@
1
1
  import { default as e } from "./client/zod/context/RhfUtilsClientForZodContextProvider.mjs";
2
- import { default as s } from "./client/zod/context/RhfUtilsZodForm.mjs";
2
+ import { default as a } from "./client/zod/context/RhfUtilsZodForm.mjs";
3
3
  import { default as u } from "./client/zod/context/useRhfUtilsZodForm.mjs";
4
4
  import { default as m } from "./errors/flat/context/useFlatFieldErrorsContext.mjs";
5
5
  import { default as d } from "./errors/flat/context/useFlatFieldErrorsContextHasOnlyOrphans.mjs";
@@ -7,44 +7,46 @@ import { default as x } from "./errors/message/FormErrorMessageByPath.mjs";
7
7
  import { default as F } from "./errors/nonfield/FormNonFieldErrorMarker.mjs";
8
8
  import { default as C } from "./errors/root/RootErrorsListFromFlatFieldErrorsContext.mjs";
9
9
  import { getOnSubmitTrpcClientErrorHandler as E } from "./errors/trpc/getOnSubmitTrpcClientErrorHandler.mjs";
10
- import { trpcClientErrorToFormSubmitErrorsSchemaTransformer as R } from "./errors/trpc/trpcClientErrorToFormSubmitErrorsSchemaTransformer.mjs";
11
- import { default as b } from "./form/context/utils/useRhfUtilsContext.mjs";
10
+ import { trpcClientErrorToFormSubmitErrorsSchemaTransformer as c } from "./errors/trpc/trpcClientErrorToFormSubmitErrorsSchemaTransformer.mjs";
11
+ import { default as R } from "./form/context/utils/useRhfUtilsContext.mjs";
12
12
  import { default as y } from "./form/context/utils/useRhfUtilsContextRequestSubmit.mjs";
13
- import { default as B } from "./form/context/group/FormGroupContextProvider.mjs";
14
- import { default as P } from "./form/context/group/useFormGroupChildIsMountedTracker.mjs";
15
- import { default as U } from "./form/context/group/useFormGroupChildIsSubmittingTracker.mjs";
13
+ import { default as T } from "./form/context/group/FormGroupContextProvider.mjs";
14
+ import { default as I } from "./form/context/group/useFormGroupChildIsMountedTracker.mjs";
15
+ import { default as g } from "./form/context/group/useFormGroupChildIsSubmittingTracker.mjs";
16
16
  import { default as O } from "./form/context/group/useFormGroupChildTracker.mjs";
17
- import { default as Z } from "./form/context/group/useFormGroupIsAnyBusy.mjs";
18
- import { default as v } from "./form/context/group/useFormGroupIsChildBusy.mjs";
19
- import { default as A } from "./form/context/group/useFormGroupIsParentBusy.mjs";
20
- import { default as L } from "./form/context/group/useFormGroupParentTracker.mjs";
17
+ import { default as M } from "./form/context/group/useFormGroupIsAnyBusy.mjs";
18
+ import { default as q } from "./form/context/group/useFormGroupIsChildBusy.mjs";
19
+ import { default as N } from "./form/context/group/useFormGroupIsParentBusy.mjs";
20
+ import { default as D } from "./form/context/group/useFormGroupParentTracker.mjs";
21
21
  import { default as j } from "./form/context/group/useFormOrParentIsBusy.mjs";
22
22
  import { default as z } from "./form/utils/getSubmitterButtonData.mjs";
23
23
  import { default as K } from "./form/utils/useFormRequestSubmit.mjs";
24
- import { FormSubmitError as V } from "./submit/error/FormSubmitError.mjs";
24
+ import { default as V } from "./form/utils/useShouldFormBlockNavigation.mjs";
25
+ import { FormSubmitError as X } from "./submit/error/FormSubmitError.mjs";
25
26
  export {
26
27
  x as FormErrorMessageByPath,
27
- B as FormGroupContextProvider,
28
+ T as FormGroupContextProvider,
28
29
  F as FormNonFieldErrorMarker,
29
- V as FormSubmitError,
30
+ X as FormSubmitError,
30
31
  e as RhfUtilsClientForZodContextProvider,
31
- s as RhfUtilsZodForm,
32
+ a as RhfUtilsZodForm,
32
33
  C as RootErrorsListFromFlatFieldErrorsContext,
33
34
  E as getOnSubmitTrpcClientErrorHandler,
34
35
  z as getSubmitterButtonData,
35
- R as trpcClientErrorToFormSubmitErrorsSchemaTransformer,
36
+ c as trpcClientErrorToFormSubmitErrorsSchemaTransformer,
36
37
  m as useFlatFieldErrorsContext,
37
38
  d as useFlatFieldErrorsContextHasOnlyOrphans,
38
- P as useFormGroupChildIsMountedTracker,
39
- U as useFormGroupChildIsSubmittingTracker,
39
+ I as useFormGroupChildIsMountedTracker,
40
+ g as useFormGroupChildIsSubmittingTracker,
40
41
  O as useFormGroupChildTracker,
41
- Z as useFormGroupIsAnyBusy,
42
- v as useFormGroupIsChildBusy,
43
- A as useFormGroupIsParentBusy,
44
- L as useFormGroupParentTracker,
42
+ M as useFormGroupIsAnyBusy,
43
+ q as useFormGroupIsChildBusy,
44
+ N as useFormGroupIsParentBusy,
45
+ D as useFormGroupParentTracker,
45
46
  j as useFormOrParentIsBusy,
46
47
  K as useFormRequestSubmit,
47
- b as useRhfUtilsContext,
48
+ R as useRhfUtilsContext,
48
49
  y as useRhfUtilsContextRequestSubmit,
49
- u as useRhfUtilsZodForm
50
+ u as useRhfUtilsZodForm,
51
+ V as useShouldFormBlockNavigation
50
52
  };
@@ -1,9 +1,9 @@
1
- import { jsx as s, jsxs as j } from "react/jsx-runtime";
1
+ import { jsx as h, jsxs as T } from "react/jsx-runtime";
2
2
  import "react";
3
- import { useFormContext as v } from "react-hook-form";
3
+ import { useFormContext as j } from "react-hook-form";
4
4
  import w from "../client/config/useRhfUtilsClientConfigContext.mjs";
5
5
  import E from "../devtool/LazyDevTool.mjs";
6
- import { FormSubmitError as c } from "../submit/error/FormSubmitError.mjs";
6
+ import { FormSubmitError as s } from "../submit/error/FormSubmitError.mjs";
7
7
  import S from "../submit/error/setCtxErrorsByFormSubmitErrors.mjs";
8
8
  import U from "../utils/PassthroughChildren.mjs";
9
9
  import _ from "./_Controller.mjs";
@@ -12,66 +12,74 @@ function G({
12
12
  formRef: m,
13
13
  //
14
14
  onSubmit: a,
15
- onSubmitError: h,
15
+ onSubmitError: d,
16
16
  onSubmitInvalid: i,
17
17
  Children: l,
18
18
  //
19
19
  form: F,
20
- utils: o
20
+ utils: r
21
21
  }) {
22
- const n = v(), r = w(), y = async (t) => {
23
- o != null && o.stopSubmitPropagation && t.stopPropagation();
22
+ const n = j(), t = w(), y = async (o) => {
23
+ r != null && r.stopSubmitPropagation && o.stopPropagation();
24
24
  try {
25
- await n.handleSubmit(f, i)(t);
25
+ await n.handleSubmit(f, i)(o);
26
26
  } catch (e) {
27
- b(e, t);
27
+ b(e, o);
28
28
  }
29
- }, f = (t, e) => a == null ? void 0 : a(
30
- t,
29
+ }, f = (o, e) => a == null ? void 0 : a(
30
+ o,
31
31
  {
32
32
  formId: p,
33
33
  formRef: m,
34
34
  context: n,
35
- utils: o,
36
- FormSubmitError: c
35
+ utils: r,
36
+ FormSubmitError: s
37
37
  },
38
38
  e
39
- ), b = (t, e) => {
39
+ ), b = (o, e) => {
40
40
  var x;
41
- const C = t instanceof c ? (
41
+ const C = o instanceof s ? (
42
42
  // consumer can manually throw FormSubmitError (e.g., manual validation)
43
- t.errors
43
+ o.errors
44
44
  ) : (
45
45
  // if error is not FormSubmitError, consumer can provide global handler
46
- (x = r == null ? void 0 : r.onSubmitUnknownError) == null ? void 0 : x.call(r, t)
46
+ (x = t == null ? void 0 : t.onSubmitUnknownError) == null ? void 0 : x.call(t, o)
47
47
  );
48
- C && S(n, C), h == null || h(
49
- t,
48
+ C && S(n, C), d == null || d(
49
+ o,
50
50
  {
51
51
  formId: p,
52
52
  formRef: m,
53
53
  context: n,
54
- utils: o
54
+ utils: r
55
55
  },
56
56
  e
57
57
  );
58
- }, d = {
58
+ }, c = {
59
59
  formId: p,
60
60
  formRef: m,
61
61
  context: n,
62
- utils: o,
62
+ utils: r,
63
63
  Controller: _,
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,
69
- {
70
- props: typeof o.devTool == "object" ? o.devTool : void 0
71
- }
72
- ),
73
- /* @__PURE__ */ s(l, { ...d })
74
- ] }) });
64
+ FormSubmitError: s
65
+ }, v = (t == null ? void 0 : t.FormComponent) ?? "form", P = (t == null ? void 0 : t.FormChildren) ?? U;
66
+ return /* @__PURE__ */ h(
67
+ v,
68
+ {
69
+ ...F,
70
+ ref: m,
71
+ onSubmit: (o) => void y(o),
72
+ children: /* @__PURE__ */ T(P, { ...c, children: [
73
+ (r == null ? void 0 : r.devTool) && /* @__PURE__ */ h(
74
+ E,
75
+ {
76
+ props: typeof r.devTool == "object" ? r.devTool : void 0
77
+ }
78
+ ),
79
+ /* @__PURE__ */ h(l, { ...c })
80
+ ] })
81
+ }
82
+ );
75
83
  }
76
84
  export {
77
85
  G as default
@@ -1,30 +1,29 @@
1
1
  import { jsx as l } from "react/jsx-runtime";
2
- import C from "../../../client/config/useRhfUtilsClientConfigContext.mjs";
3
- import F from "../../../errors/flat/context/useFlatFieldErrorsContextOutput.mjs";
4
- import x from "../../../submit/useFormOnSubmitSuccessfulAndReset.mjs";
5
- import O from "../../../submit/useResetFormOnSubmitError.mjs";
6
- import b from "../../../submit/useResetFormOnSubmitSuccessful.mjs";
7
- import d from "../../../submit/useSubmitFormOnChange.mjs";
8
- import { _RhfUtilsContextProvider as h } from "./useRhfUtilsContext.mjs";
9
- const M = ({
10
- formId: f,
11
- formRef: t,
12
- onSubmitSuccessfulAndReset: e,
2
+ import d from "../../../client/config/useRhfUtilsClientConfigContext.mjs";
3
+ import i from "../../../errors/flat/context/useFlatFieldErrorsContextOutput.mjs";
4
+ import u from "../../../submit/useFormOnSubmitSuccessfulAndReset.mjs";
5
+ import x from "../../../submit/useResetFormOnSubmitted.mjs";
6
+ import F from "../../../submit/useSubmitFormOnChange.mjs";
7
+ import { _RhfUtilsContextProvider as O } from "./useRhfUtilsContext.mjs";
8
+ const P = ({
9
+ formId: C,
10
+ formRef: m,
11
+ onSubmitSuccessfulAndReset: t,
13
12
  options: r,
14
- children: a
13
+ children: f
15
14
  }) => {
16
- var u;
17
- const m = C();
18
- return F((u = m == null ? void 0 : m.fieldErrors) == null ? void 0 : u.output), d(t, {
15
+ var a;
16
+ const e = d();
17
+ return i((a = e == null ? void 0 : e.fieldErrors) == null ? void 0 : a.output), F(m, {
19
18
  disabled: !(r != null && r.submitOnChange)
20
- }), O({
21
- disabled: !(r != null && r.resetValuesOnSubmitError)
22
- }), b(
23
- (r == null ? void 0 : r.resetFormAfterSubmitSuccessful) || !!e
24
- ), x(() => {
25
- e == null || e();
26
- }), /* @__PURE__ */ l(h, { value: { formId: f, formRef: t, options: r }, children: a });
19
+ }), x(
20
+ (r == null ? void 0 : r.resetFormOnSubmitted) ?? (t && {
21
+ onSuccess: "defaults"
22
+ })
23
+ ), u(() => {
24
+ t == null || t();
25
+ }), /* @__PURE__ */ l(O, { value: { formId: C, formRef: m, options: r }, children: f });
27
26
  };
28
27
  export {
29
- M as default
28
+ P as default
30
29
  };
@@ -1,6 +1,5 @@
1
1
  const u = (t) => (r) => {
2
- if (!t.current)
3
- throw new Error();
2
+ if (!t.current) throw new Error();
4
3
  e(t.current, r);
5
4
  }, e = (t, r) => {
6
5
  t.requestSubmit(r);
@@ -0,0 +1,9 @@
1
+ const s = (o, { isDirty: a, isSubmitting: t, isValid: l }) => (
2
+ // enabled
3
+ o && // dirty
4
+ a && // allow redirecting in submit handler
5
+ !(t && l)
6
+ ), u = s;
7
+ export {
8
+ u as default
9
+ };
@@ -1,13 +1,11 @@
1
- import r from "react";
2
- import { useFormState as f } from "react-hook-form";
3
- import c from "./useFormOnSubmitSuccessful.mjs";
1
+ import f from "react";
2
+ import { useFormState as i } from "react-hook-form";
3
+ import { useRefIfValueWasTrue as m } from "../utils/useRefIfValueWasTrue.mjs";
4
4
  const n = (t) => {
5
- const { isSubmitSuccessful: u, isDirty: s } = f(), e = r.useRef(!1);
6
- c(() => {
7
- e.current = !0;
8
- }), r.useEffect(() => {
9
- t && e.current && !u && !s && (t(), e.current = !1);
10
- }, [u, s]);
5
+ const { isDirty: s, isSubmitSuccessful: e } = i(), [u, r] = m(e);
6
+ f.useEffect(() => {
7
+ t && (s || !e && !u || (t(), r()));
8
+ }, [e, s]);
11
9
  };
12
10
  export {
13
11
  n as default
@@ -0,0 +1,12 @@
1
+ import u from "react";
2
+ import { useFormState as o } from "react-hook-form";
3
+ import { useRefIfValueWasTrue as m } from "../utils/useRefIfValueWasTrue.mjs";
4
+ const c = (e, f) => {
5
+ const { isSubmitSuccessful: i, isSubmitting: t } = o(), [r, s] = m(t);
6
+ u.useEffect(() => {
7
+ e && (t || r && (s(), e(i)));
8
+ }, [t]);
9
+ };
10
+ export {
11
+ c as default
12
+ };
@@ -0,0 +1,21 @@
1
+ import { useFormContext as m } from "react-hook-form";
2
+ import n from "./useFormOnSubmitted.mjs";
3
+ const S = (e) => {
4
+ const { reset: r, getValues: u } = m();
5
+ n((s) => {
6
+ if (!e) return;
7
+ const t = e[s ? "onSuccess" : "onError"];
8
+ if (!t) return;
9
+ const o = t === "current" ? u() : void 0;
10
+ r(o, {
11
+ // keep submit stuff for tracking relevant state (e.g., `useFormOnSubmitSuccessful`)
12
+ keepIsSubmitSuccessful: !0,
13
+ keepIsSubmitted: !0,
14
+ keepSubmitCount: !0,
15
+ keepErrors: !0
16
+ });
17
+ });
18
+ };
19
+ export {
20
+ S as default
21
+ };
@@ -1,15 +1,13 @@
1
- import m from "react";
2
- import a from "../form/utils/useFormRequestSubmit.mjs";
3
- const o = (t, e) => {
4
- const u = a(t);
5
- m.useEffect(() => {
6
- if (e != null && e.disabled)
7
- return;
1
+ import c from "react";
2
+ import m from "../form/utils/useFormRequestSubmit.mjs";
3
+ const d = (t, e) => {
4
+ const u = !(e != null && e.disabled), a = m(t);
5
+ c.useEffect(() => {
6
+ if (!u) return;
8
7
  const r = t.current;
9
- if (!r)
10
- throw new Error();
8
+ if (!r) throw new Error();
11
9
  const n = () => {
12
- u();
10
+ a();
13
11
  };
14
12
  return r.addEventListener("change", n), () => {
15
13
  r.removeEventListener("change", n);
@@ -17,5 +15,5 @@ const o = (t, e) => {
17
15
  }, []);
18
16
  };
19
17
  export {
20
- o as default
18
+ d as default
21
19
  };
@@ -2,8 +2,7 @@ import r from "react";
2
2
  function i() {
3
3
  const e = r.createContext(void 0), t = () => r.useContext(e), n = () => {
4
4
  const o = t();
5
- if (o === void 0)
6
- throw new Error();
5
+ if (o === void 0) throw new Error();
7
6
  return o;
8
7
  };
9
8
  return {
@@ -0,0 +1,14 @@
1
+ import t from "react";
2
+ const u = (r) => {
3
+ const e = t.useRef(!1);
4
+ t.useEffect(() => {
5
+ r && (e.current = !0);
6
+ }, [r]);
7
+ const s = () => {
8
+ e.current = !1;
9
+ };
10
+ return [e.current, s];
11
+ };
12
+ export {
13
+ u as useRefIfValueWasTrue
14
+ };
@@ -28,4 +28,5 @@ export { default as useFormGroupParentTracker } from './form/context/group/useFo
28
28
  export { default as useFormOrParentIsBusy } from './form/context/group/useFormOrParentIsBusy';
29
29
  export { default as getSubmitterButtonData } from './form/utils/getSubmitterButtonData';
30
30
  export { default as useFormRequestSubmit } from './form/utils/useFormRequestSubmit';
31
+ export { default as useShouldFormBlockNavigation } from './form/utils/useShouldFormBlockNavigation';
31
32
  export { FormSubmitError } from './submit/error/FormSubmitError';
@@ -1,5 +1,5 @@
1
1
  import { DevtoolUIProps } from '@hookform/devtools/dist/devToolUI';
2
- import { UseResetFormAfterSubmitSuccessfulOptions } from '../submit/useResetFormOnSubmitSuccessful';
2
+ import { UseResetFormOnSubmittedOptions } from '../submit/useResetFormOnSubmitted';
3
3
  import { Register } from '../register';
4
4
 
5
5
  /**
@@ -8,14 +8,12 @@ import { Register } from '../register';
8
8
  * Can be extended using {@link Register.RhfUtilsFormOptions}.
9
9
  */
10
10
  export type RhfUtilsFormOptions = {
11
- /** Request submit via listener on form change. */
12
- submitOnChange?: boolean;
13
- /** Reset form values if submit throw errors. (Use case: optimistic UI toggle form that submits on each change.) */
14
- resetValuesOnSubmitError?: boolean;
15
11
  /** Stop propagation of submit event. Useful for portals. */
16
12
  stopSubmitPropagation?: boolean;
17
- /** Reset form after successful submit. */
18
- resetFormAfterSubmitSuccessful?: UseResetFormAfterSubmitSuccessfulOptions;
13
+ /** Request submit via listener on form change. */
14
+ submitOnChange?: boolean;
15
+ /** Reset form after submit. */
16
+ resetFormOnSubmitted?: UseResetFormOnSubmittedOptions;
19
17
  /**
20
18
  * Control dev tool options.
21
19
  * (Lazy-loaded when truthy value supplied.
@@ -1,3 +1,4 @@
1
+ import { MaybePromise } from '@trpc/server/unstable-core-do-not-import';
1
2
  import { default as React } from 'react';
2
3
  import { SubmitErrorHandler, UseFormProps } from 'react-hook-form';
3
4
  import { RhfUtilsFormOptions } from './RhfUtilsFormOptions';
@@ -7,7 +8,7 @@ import { UseRhfUtilsFormOnSubmitContext, UseRhfUtilsFormOnSubmitErrorContext } f
7
8
 
8
9
  export type UseRhfUtilsFormProps<TFieldValues extends SafeFieldValues, TTransformedValues extends SafeFieldValues> = {
9
10
  defaultValues?: UseFormProps<TFieldValues>['defaultValues'];
10
- onSubmit?: (values: TTransformedValues, context: UseRhfUtilsFormOnSubmitContext<TFieldValues, TTransformedValues>, event: React.BaseSyntheticEvent<SubmitEvent>) => unknown | Promise<unknown>;
11
+ onSubmit?: (values: TTransformedValues, context: UseRhfUtilsFormOnSubmitContext<TFieldValues, TTransformedValues>, event: React.BaseSyntheticEvent<SubmitEvent>) => MaybePromise<unknown>;
11
12
  /** Submit error handler. (Only for errors not of instance `FormError`, which are handled internally.) */
12
13
  onSubmitError?: (error: unknown, context: UseRhfUtilsFormOnSubmitErrorContext<TFieldValues, TTransformedValues>, event: React.BaseSyntheticEvent<SubmitEvent>) => void;
13
14
  /** Submit handler when form is invalid. */
@@ -0,0 +1,13 @@
1
+ import { FieldValues, FormState } from 'react-hook-form';
2
+
3
+ /**
4
+ * Returns `boolean` value when the form should block navigation.
5
+ *
6
+ * Evaluates to `true` when `enabled` and `isDirty` except when `isSubmitting` and `isValid`,
7
+ * because we don't want to block navigation when the form is submitting and valid.
8
+ *
9
+ * NOTE: If you need to block navigation during a potentially prolonged submission request,
10
+ * you will need to provide your own behaviors above and beyond this hook.
11
+ */
12
+ declare const useShouldFormBlockNavigation: (enabled: boolean, { isDirty, isSubmitting, isValid }: FormState<FieldValues>) => boolean;
13
+ export default useShouldFormBlockNavigation;
@@ -1,3 +1,5 @@
1
+ import { MaybePromise } from '@trpc/server/unstable-core-do-not-import';
2
+
1
3
  /**
2
4
  * Calls a callback after a successful submit and after a form reset.
3
5
  *
@@ -7,7 +9,7 @@
7
9
  * Using RHF and following its rules, we are not able to get the state `isSubmitSuccessful=true` and `isDirty=false`.
8
10
  * So, this has to keep track of previous state.
9
11
  *
10
- * SubmitSuccessfulAndReset = was `isSubmitSuccessful` and now `!isSubmitSuccessful && !isDirty`
12
+ * SubmitSuccessfulAndReset = was `isSubmitSuccessful` and now `!isDirty`
11
13
  */
12
- declare const useFormOnSubmitSuccessfulAndReset: (callback?: () => void) => void;
14
+ declare const useFormOnSubmitSuccessfulAndReset: (callback?: () => MaybePromise<unknown>) => void;
13
15
  export default useFormOnSubmitSuccessfulAndReset;
@@ -0,0 +1,6 @@
1
+ import { MaybePromise } from '@trpc/server/unstable-core-do-not-import';
2
+
3
+ declare const useFormOnSubmitted: (callback?: (success: boolean) => MaybePromise<unknown>, options?: {
4
+ successful?: boolean;
5
+ }) => void;
6
+ export default useFormOnSubmitted;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Configuration for hook.
3
+ * - `undefined`: disabled
4
+ */
5
+ export type UseResetFormOnSubmittedOptions = undefined | {
6
+ /**
7
+ * Reset values on submit successful.
8
+ * - `'defaults'`: reset to default values
9
+ * - `'current'`: reset to current values
10
+ */
11
+ onSuccess?: 'defaults' | 'current';
12
+ /**
13
+ * Reset values on submit error. (reset to default values)
14
+ */
15
+ onError?: 'defaults';
16
+ };
17
+ /**
18
+ * Handle resetting after successful submit with no server validation errors.
19
+ * See `Rules` section: https://react-hook-form.com/api/useform/reset/
20
+ * Specifically: "- It's recommended to reset inside useEffect after submission."
21
+ */
22
+ declare const useResetFormOnSubmitted: (options: UseResetFormOnSubmittedOptions) => void;
23
+ export default useResetFormOnSubmitted;
@@ -1,6 +1,7 @@
1
1
  import { default as React } from 'react';
2
2
 
3
3
  declare const useSubmitFormOnChange: (formRef: React.RefObject<HTMLFormElement>, options?: {
4
+ /** Disable-able so that default behavior is enabled for sake of simplicity of usage. */
4
5
  disabled?: boolean;
5
6
  }) => void;
6
7
  export default useSubmitFormOnChange;
@@ -0,0 +1 @@
1
+ export type MaybePromise<T> = T | Promise<T>;
@@ -0,0 +1 @@
1
+ export declare const useRefIfValueWasTrue: (value: boolean) => readonly [boolean, () => void];
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.121",
5
+ "version": "0.0.125",
6
6
  "description": "Integration utilities for react-hook-form.",
7
7
  "type": "module",
8
8
  "sideEffects": false,
@@ -1,11 +0,0 @@
1
- import s from "react";
2
- import { useFormState as u } from "react-hook-form";
3
- const r = (t) => {
4
- const { isSubmitSuccessful: e } = u();
5
- s.useEffect(() => {
6
- t && e && t();
7
- }, [t, e]);
8
- };
9
- export {
10
- r as default
11
- };
@@ -1,18 +0,0 @@
1
- import f from "react";
2
- import { useFormContext as n, useFormState as c } from "react-hook-form";
3
- const a = (t) => {
4
- const e = !!(t != null && t.disabled), { reset: r } = n(), { isSubmitting: u, isSubmitSuccessful: s, isSubmitted: i, submitCount: m } = c();
5
- f.useEffect(() => {
6
- e || u || s || i && m !== 0 && r();
7
- }, [
8
- e,
9
- u,
10
- s,
11
- i,
12
- m,
13
- r
14
- ]);
15
- };
16
- export {
17
- a as default
18
- };
@@ -1,20 +0,0 @@
1
- import { useFormContext as a } from "react-hook-form";
2
- import l from "./useFormOnSubmitSuccessful.mjs";
3
- const f = (e) => {
4
- const { reset: u, getValues: t } = a();
5
- l(() => {
6
- if (!e)
7
- return;
8
- const r = e === !0 || e.values === void 0 ? void 0 : e.values.resetToCurrentValues ? t() : e.values, s = e === !0 ? (
9
- // default
10
- void 0
11
- ) : (
12
- // custom settings
13
- e.state
14
- );
15
- u(r, s);
16
- });
17
- };
18
- export {
19
- f as default
20
- };