@goodie-forms/react 1.2.6-alpha → 1.3.0

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 ADDED
@@ -0,0 +1,61 @@
1
+ <!-- Logo -->
2
+ <p align="center">
3
+ <img src="https://raw.githubusercontent.com/iGoodie/goodie-forms/master/.github/assets/logo.svg" height="200px" alt="Logo"/>
4
+ </p>
5
+
6
+ <!-- Slogan -->
7
+ <p align="center">
8
+ An unopinionated modern form state and data management library
9
+ </p>
10
+ <!-- Badges -->
11
+ <p align="center">
12
+
13
+ <!-- Main Badges -->
14
+ <img src="https://raw.githubusercontent.com/iGoodie/paper-editor/master/.github/assets/main-badge.svg" height="20px"/>
15
+ <a href="https://www.npmjs.com/package/@goodie-forms/react">
16
+ <img src="https://img.shields.io/npm/v/@goodie-forms/react"/>
17
+ </a>
18
+ <a href="https://github.com/iGoodie/goodie-forms/tags">
19
+ <img src="https://img.shields.io/github/v/tag/iGoodie/goodie-forms"/>
20
+ </a>
21
+ <a href="https://github.com/iGoodie/goodie-forms">
22
+ <img src="https://img.shields.io/github/languages/top/iGoodie/goodie-forms"/>
23
+ </a>
24
+
25
+ <br/>
26
+
27
+ <!-- Github Badges -->
28
+ <img src="https://raw.githubusercontent.com/iGoodie/paper-editor/master/.github/assets/github-badge.svg" height="20px"/>
29
+ <a href="https://github.com/iGoodie/goodie-forms/commits/master">
30
+ <img src="https://img.shields.io/github/last-commit/iGoodie/goodie-forms"/>
31
+ </a>
32
+ <a href="https://github.com/iGoodie/goodie-forms/issues">
33
+ <img src="https://img.shields.io/github/issues/iGoodie/goodie-forms"/>
34
+ </a>
35
+ <a href="https://github.com/iGoodie/goodie-forms/tree/master/src">
36
+ <img src="https://img.shields.io/github/languages/code-size/iGoodie/goodie-forms"/>
37
+ </a>
38
+
39
+ <br/>
40
+
41
+ <!-- Support Badges -->
42
+ <img src="https://raw.githubusercontent.com/iGoodie/paper-editor/master/.github/assets/support-badge.svg" height="20px"/>
43
+ <a href="https://discord.gg/KNxxdvN">
44
+ <img src="https://img.shields.io/discord/610497509437210624?label=discord"/>
45
+ </a>
46
+ <a href="https://www.patreon.com/iGoodie">
47
+ <img src="https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fshieldsio-patreon.vercel.app%2Fapi%3Fusername%3DiGoodie%26type%3Dpatrons"/>
48
+ </a>
49
+ </p>
50
+
51
+ # Description
52
+
53
+ React package of Goodie Forms.
54
+
55
+ ## License
56
+
57
+ &copy; 2026 Taha Anılcan Metinyurt (iGoodie)
58
+
59
+ For any part of this work for which the license is applicable, this work is licensed under the [Attribution-ShareAlike 4.0 International](http://creativecommons.org/licenses/by-sa/4.0/) license. (See LICENSE).
60
+
61
+ <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /></a>
@@ -13,18 +13,13 @@ export interface RenderParams<TOutput extends object, TValue> {
13
13
  field: FormField<TOutput, TValue>;
14
14
  form: UseForm<TOutput>;
15
15
  }
16
- type DefaultValueProps<TValue> = undefined extends TValue ? {
17
- defaultValue?: Suppliable<TValue>;
18
- } : {
19
- defaultValue: Suppliable<TValue>;
20
- };
21
- export type FieldRendererProps<TOutput extends object, TPath extends FieldPath.Segments> = DefaultValueProps<FieldPath.Resolve<TOutput, TPath>> & {
16
+ export interface FieldRendererProps<TOutput extends object, TPath extends FieldPath.Segments> {
22
17
  form: UseForm<TOutput>;
23
18
  path: TPath;
19
+ defaultValue?: Suppliable<FieldPath.Resolve<TOutput, TPath>>;
24
20
  overrideInitialValue?: boolean;
25
- unbindOnUnmount?: boolean;
21
+ unregisterOnUnmount?: boolean;
26
22
  render: (params: RenderParams<TOutput, FieldPath.Resolve<TOutput, TPath>>) => ReactNode;
27
- };
23
+ }
28
24
  export declare function FieldRenderer<TOutput extends object, const TPath extends FieldPath.Segments>(props: FieldRendererProps<TOutput, TPath>): import("react/jsx-runtime").JSX.Element;
29
- export {};
30
25
  //# sourceMappingURL=FieldRenderer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FieldRenderer.d.ts","sourceRoot":"","sources":["../../src/components/FieldRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,SAAS,EACT,SAAS,EACT,UAAU,EACX,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,EAAqB,MAAM,OAAO,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAI3C,MAAM,WAAW,YAAY,CAAC,OAAO,SAAS,MAAM,EAAE,MAAM;IAC1D,UAAU,EAAE;QACV,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;QAErB,IAAI,EAAE,MAAM,CAAC;QAEb,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;QAExC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,WAAW,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC;QAC7D,OAAO,EAAE,MAAM,IAAI,CAAC;QACpB,MAAM,EAAE,MAAM,IAAI,CAAC;KACpB,CAAC;IAEF,KAAK,EAAE,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAElC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;CACxB;AAED,KAAK,iBAAiB,CAAC,MAAM,IAAI,SAAS,SAAS,MAAM,GACrD;IAAE,YAAY,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;CAAE,GACrC;IAAE,YAAY,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC;AAEzC,MAAM,MAAM,kBAAkB,CAC5B,OAAO,SAAS,MAAM,EACtB,KAAK,SAAS,SAAS,CAAC,QAAQ,IAC9B,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,GAAG;IACzD,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACvB,IAAI,EAAE,KAAK,CAAC;IACZ,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,MAAM,EAAE,CACN,MAAM,EAAE,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,KAC7D,SAAS,CAAC;CAChB,CAAC;AAEF,wBAAgB,aAAa,CAC3B,OAAO,SAAS,MAAM,EACtB,KAAK,CAAC,KAAK,SAAS,SAAS,CAAC,QAAQ,EACtC,KAAK,EAAE,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,2CAqF1C"}
1
+ {"version":3,"file":"FieldRenderer.d.ts","sourceRoot":"","sources":["../../src/components/FieldRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,SAAS,EACT,SAAS,EACT,UAAU,EACX,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,EAAqB,MAAM,OAAO,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAI3C,MAAM,WAAW,YAAY,CAAC,OAAO,SAAS,MAAM,EAAE,MAAM;IAC1D,UAAU,EAAE;QACV,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;QAErB,IAAI,EAAE,MAAM,CAAC;QAEb,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;QAExC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,WAAW,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC;QAC7D,OAAO,EAAE,MAAM,IAAI,CAAC;QACpB,MAAM,EAAE,MAAM,IAAI,CAAC;KACpB,CAAC;IAEF,KAAK,EAAE,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAElC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB,CACjC,OAAO,SAAS,MAAM,EACtB,KAAK,SAAS,SAAS,CAAC,QAAQ;IAEhC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACvB,IAAI,EAAE,KAAK,CAAC;IACZ,YAAY,CAAC,EAAE,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;IAC7D,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,MAAM,EAAE,CACN,MAAM,EAAE,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,KAC7D,SAAS,CAAC;CAChB;AAED,wBAAgB,aAAa,CAC3B,OAAO,SAAS,MAAM,EACtB,KAAK,CAAC,KAAK,SAAS,SAAS,CAAC,QAAQ,EACtC,KAAK,EAAE,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,2CAqF1C"}
@@ -2,15 +2,11 @@ import { FormController } from '../../../core/src';
2
2
  export declare function useForm<TOutput extends object>(formConfigs: FormController.Configs<TOutput>, hookConfigs?: {
3
3
  validateMode?: "onChange" | "onBlur" | "onSubmit";
4
4
  revalidateMode?: "onChange" | "onBlur" | "onSubmit";
5
- watchIssues?: boolean;
6
- watchValues?: boolean;
7
5
  }): {
8
6
  formConfigs: FormController.Configs<TOutput>;
9
7
  hookConfigs: {
10
8
  validateMode?: "onChange" | "onBlur" | "onSubmit";
11
9
  revalidateMode?: "onChange" | "onBlur" | "onSubmit";
12
- watchIssues?: boolean;
13
- watchValues?: boolean;
14
10
  } | undefined;
15
11
  controller: FormController<TOutput>;
16
12
  path: import('../../../core/src').FieldPathBuilder<TOutput>;
@@ -1 +1 @@
1
- {"version":3,"file":"useForm.d.ts","sourceRoot":"","sources":["../../src/hooks/useForm.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAKpD,wBAAgB,OAAO,CAAC,OAAO,SAAS,MAAM,EAC5C,WAAW,EAAE,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,EAC5C,WAAW,CAAC,EAAE;IACZ,YAAY,CAAC,EAAE,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC;IAClD,cAAc,CAAC,EAAE,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC;IACpD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;;;uBAJgB,UAAU,GAAG,QAAQ,GAAG,UAAU;yBAChC,UAAU,GAAG,QAAQ,GAAG,UAAU;sBACrC,OAAO;sBACP,OAAO;;;;;;iBA0CA,CAAC,4RACX,CAAC,aACD,WAAW;;;;;;;;;;;;;UAAsC,CAAC,MAAM,CAAC;EAqBvE;AAED,MAAM,MAAM,OAAO,CAAC,OAAO,SAAS,MAAM,IAAI,UAAU,CACtD,OAAO,OAAO,CAAC,OAAO,CAAC,CACxB,CAAC"}
1
+ {"version":3,"file":"useForm.d.ts","sourceRoot":"","sources":["../../src/hooks/useForm.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIpD,wBAAgB,OAAO,CAAC,OAAO,SAAS,MAAM,EAC5C,WAAW,EAAE,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,EAC5C,WAAW,CAAC,EAAE;IACZ,YAAY,CAAC,EAAE,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC;IAClD,cAAc,CAAC,EAAE,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC;CACrD;;;uBAFgB,UAAU,GAAG,QAAQ,GAAG,UAAU;yBAChC,UAAU,GAAG,QAAQ,GAAG,UAAU;;;;;;iBAgC9B,CAAC,4RACX,CAAC,aACD,WAAW;;;;;;;;;;;;;UAAsC,CAAC,MAAM,CAAC;EAqBvE;AAED,MAAM,MAAM,OAAO,CAAC,OAAO,SAAS,MAAM,IAAI,UAAU,CACtD,OAAO,OAAO,CAAC,OAAO,CAAC,CACxB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { FieldPath, FormField } from '../../../core/src';
2
2
  import { UseForm } from '../hooks/useForm';
3
3
  export declare function useFormField<TOutput extends object, TPath extends FieldPath.Segments>(form: UseForm<TOutput>, path: TPath): FormField<TOutput, FieldPath.Resolve<TOutput, TPath>> | undefined;
4
- export declare function useFormField<TOutput extends object, TPath extends FieldPath.Segments>(form: UseForm<TOutput>, path: TPath, bindingConfig: Parameters<typeof form.controller.registerField<TPath>>[1]): FormField<TOutput, FieldPath.Resolve<TOutput, TPath>>;
4
+ export declare function useFormField<TOutput extends object, TPath extends FieldPath.Segments>(form: UseForm<TOutput>, path: TPath, registerConfig: Parameters<typeof form.controller.registerField<TPath>>[1]): FormField<TOutput, FieldPath.Resolve<TOutput, TPath>>;
5
5
  //# sourceMappingURL=useFormField.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useFormField.d.ts","sourceRoot":"","sources":["../../src/hooks/useFormField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAG3C,wBAAgB,YAAY,CAC1B,OAAO,SAAS,MAAM,EACtB,KAAK,SAAS,SAAS,CAAC,QAAQ,EAEhC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,EACtB,IAAI,EAAE,KAAK,GACV,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,GAAG,SAAS,CAAC;AAErE,wBAAgB,YAAY,CAC1B,OAAO,SAAS,MAAM,EACtB,KAAK,SAAS,SAAS,CAAC,QAAQ,EAEhC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,EACtB,IAAI,EAAE,KAAK,EACX,aAAa,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GACxE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"useFormField.d.ts","sourceRoot":"","sources":["../../src/hooks/useFormField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAI3C,wBAAgB,YAAY,CAC1B,OAAO,SAAS,MAAM,EACtB,KAAK,SAAS,SAAS,CAAC,QAAQ,EAEhC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,EACtB,IAAI,EAAE,KAAK,GACV,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,GAAG,SAAS,CAAC;AAErE,wBAAgB,YAAY,CAC1B,OAAO,SAAS,MAAM,EACtB,KAAK,SAAS,SAAS,CAAC,QAAQ,EAEhC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,EACtB,IAAI,EAAE,KAAK,EACX,cAAc,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GACzE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -2,6 +2,5 @@ export * from './hooks/useForm';
2
2
  export * from './hooks/useFormField';
3
3
  export * from './hooks/useFieldValue';
4
4
  export * from './hooks/useFieldIssues';
5
- export * from './hooks/useRenderControl';
6
5
  export * from './components/FieldRenderer';
7
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AAEzC,cAAc,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AAEvC,cAAc,4BAA4B,CAAC"}
package/dist/index.js CHANGED
@@ -1,164 +1,141 @@
1
- import { FormController as q, FieldPath as o } from "@goodie-forms/core";
2
- import { useRef as m, useCallback as f, useSyncExternalStore as a, useState as F, startTransition as I, useEffect as V } from "react";
3
- import { jsx as R, Fragment as U } from "react/jsx-runtime";
4
- function b(n, t) {
5
- const e = m(0), s = f(
6
- (l) => n(() => {
7
- e.current++, l();
1
+ import { FormController as V, FieldPath as i } from "@goodie-forms/core";
2
+ import { useRef as v, useCallback as d, useSyncExternalStore as f, useState as g, useEffect as m } from "react";
3
+ import { jsx as U, Fragment as I } from "react/jsx-runtime";
4
+ function a(u, n) {
5
+ const e = v(0), l = d(
6
+ (r) => u(() => {
7
+ e.current++, r();
8
8
  }),
9
- [n]
10
- ), u = f(() => e.current, []);
11
- return a(s, u, u), t();
9
+ [u]
10
+ ), o = d(() => e.current, []);
11
+ return f(l, o, o), n();
12
12
  }
13
- function v(...n) {
14
- return () => {
15
- for (const t of n)
16
- t();
17
- };
18
- }
19
- function E(n, t) {
20
- const [e] = F(() => new q(n)), s = f(
21
- (r) => {
22
- const d = () => {
23
- };
24
- return v(
25
- e.events.on("submissionStatusChange", r),
26
- t?.watchIssues ? e.events.on("fieldIssuesUpdated", r) : d,
27
- t?.watchValues ? e.events.on("fieldValueChanged", r) : d
28
- );
29
- },
30
- [e, t?.watchIssues, t?.watchValues]
13
+ function M(u, n) {
14
+ const [e] = g(() => new V(u)), l = d(
15
+ (t) => e.events.on("submissionStatusChange", t),
16
+ [e]
31
17
  );
32
- b(s, () => e);
33
- const u = () => a(
34
- (r) => e.events.on("fieldValueChanged", r),
18
+ a(l, () => e);
19
+ const o = () => f(
20
+ (t) => e.events.on("fieldValueChanged", t),
35
21
  () => e.data,
36
22
  () => e.data
37
- ), l = () => a(
38
- (r) => e.events.on("fieldIssuesUpdated", r),
23
+ ), r = () => f(
24
+ (t) => e.events.on("fieldIssuesUpdated", t),
39
25
  () => e.issues,
40
26
  () => e.issues
41
- ), i = (r, d) => b(
42
- (c) => e.events.on(r, (...g) => {
43
- d?.(...g), c();
27
+ ), s = (t, F) => a(
28
+ (b) => e.events.on(t, (...q) => {
29
+ F?.(...q), b();
44
30
  }),
45
31
  () => {
46
32
  }
47
33
  );
48
34
  return {
49
- formConfigs: n,
50
- hookConfigs: t,
35
+ formConfigs: u,
36
+ hookConfigs: n,
51
37
  controller: e,
52
38
  path: e.path,
53
- watchValues: u,
54
- watchIssues: l,
55
- watchEvent: i
39
+ watchValues: o,
40
+ watchIssues: r,
41
+ watchEvent: s
42
+ };
43
+ }
44
+ function c(...u) {
45
+ return () => {
46
+ for (const n of u)
47
+ n();
56
48
  };
57
49
  }
58
- function w(n, t, e) {
59
- const { controller: s } = n, u = m(0);
60
- F(() => (!s.getField(t) && e && s.registerField(t, e), null));
61
- const l = f(
50
+ function R(u, n, e) {
51
+ const { controller: l } = u;
52
+ g(() => (!l.getField(n) && e && l.registerField(n, e), null));
53
+ const o = d(
62
54
  (r) => {
63
- const { events: d } = s;
64
- return v(
65
- d.on("fieldRegistered", (c) => {
66
- o.equals(c, t) && (u.current++, r());
55
+ const { events: s } = l;
56
+ return c(
57
+ s.on("fieldRegistered", (t) => {
58
+ i.equals(t, n) && r();
67
59
  }),
68
- d.on("fieldUnregistered", (c) => {
69
- o.equals(c, t) && (u.current++, r());
60
+ s.on("fieldUnregistered", (t) => {
61
+ i.equals(t, n) && r();
70
62
  }),
71
- d.on("fieldValueChanged", (c) => {
72
- (o.equals(c, t) || o.isDescendant(c, t)) && (u.current++, r());
63
+ s.on("fieldValueChanged", (t) => {
64
+ (i.equals(t, n) || i.isDescendant(t, n)) && r();
73
65
  }),
74
- d.on("fieldTouchUpdated", (c) => {
75
- o.equals(c, t) && (u.current++, r());
66
+ s.on("fieldTouchUpdated", (t) => {
67
+ i.equals(t, n) && r();
76
68
  }),
77
- d.on("fieldDirtyUpdated", (c) => {
78
- o.equals(c, t) && (u.current++, r());
69
+ s.on("fieldDirtyUpdated", (t) => {
70
+ i.equals(t, n) && r();
79
71
  }),
80
- d.on("fieldIssuesUpdated", (c) => {
81
- o.equals(c, t) && (u.current++, r());
72
+ s.on("fieldIssuesUpdated", (t) => {
73
+ i.equals(t, n) && r();
82
74
  })
83
75
  );
84
76
  },
85
- [s, t]
86
- ), i = f(() => u.current, [s, t]);
87
- return a(l, i, i), s.getField(t);
77
+ [l, n]
78
+ );
79
+ return a(o, () => l.getField(n));
88
80
  }
89
- function h(n, t) {
90
- const { controller: e } = n, s = f(
91
- (l) => {
92
- const { events: i } = e;
93
- return v(
94
- i.on("fieldRegistered", (r) => {
95
- o.equals(t, r) && l();
81
+ function S(u, n) {
82
+ const { controller: e } = u, l = d(
83
+ (r) => {
84
+ const { events: s } = e;
85
+ return c(
86
+ s.on("fieldRegistered", (t) => {
87
+ i.equals(n, t) && r();
96
88
  }),
97
- i.on("fieldUnregistered", (r) => {
98
- o.equals(t, r) && l();
89
+ s.on("fieldUnregistered", (t) => {
90
+ i.equals(n, t) && r();
99
91
  }),
100
- i.on("fieldValueChanged", (r) => {
101
- (o.equals(r, t) || o.isDescendant(r, t)) && l();
92
+ s.on("fieldValueChanged", (t) => {
93
+ (i.equals(t, n) || i.isDescendant(t, n)) && r();
102
94
  })
103
95
  );
104
96
  },
105
- [e, t]
106
- ), u = f(() => e.getField(t)?.value, [e, t]);
107
- return a(s, u, u);
97
+ [e, n]
98
+ ), o = d(() => e.getField(n)?.value, [e, n]);
99
+ return f(l, o, o);
108
100
  }
109
- function D(n, t) {
110
- const { controller: e } = n, s = f(
111
- (l) => {
112
- const { events: i } = e;
113
- return v(
114
- i.on("fieldRegistered", (r) => {
115
- o.equals(t, r) && l();
101
+ function k(u, n) {
102
+ const { controller: e } = u, l = d(
103
+ (r) => {
104
+ const { events: s } = e;
105
+ return c(
106
+ s.on("fieldRegistered", (t) => {
107
+ i.equals(n, t) && r();
116
108
  }),
117
- i.on("fieldUnregistered", (r) => {
118
- o.equals(t, r) && l();
109
+ s.on("fieldUnregistered", (t) => {
110
+ i.equals(n, t) && r();
119
111
  }),
120
- i.on("fieldIssuesUpdated", (r) => {
121
- o.equals(t, r) && l();
112
+ s.on("fieldIssuesUpdated", (t) => {
113
+ i.equals(n, t) && r();
122
114
  })
123
115
  );
124
116
  },
125
- [e, t]
126
- ), u = f(() => e.getField(t)?.issues ?? [], [e, t]);
127
- return a(s, u, u);
128
- }
129
- function W() {
130
- const [, n] = F(0), t = m(0), e = m(!1);
131
- t.current++;
132
- const s = () => {
133
- e.current || (e.current = !0, queueMicrotask(() => {
134
- I(() => {
135
- n((u) => u + 1);
136
- }), e.current = !1;
137
- }));
138
- };
139
- return {
140
- renderCount: t.current,
141
- forceRerender: s
142
- };
117
+ [e, n]
118
+ ), o = d(() => e.getField(n)?.issues ?? [], [e, n]);
119
+ return f(l, o, o);
143
120
  }
144
- function S(n) {
145
- const t = m(null), e = w(n.form, n.path, {
146
- overrideInitialValue: n.overrideInitialValue ?? !0,
147
- defaultValue: n.defaultValue
148
- }), s = n.form.controller.triedSubmitting ? n.form.hookConfigs?.revalidateMode ?? n.form.hookConfigs?.validateMode : n.form.hookConfigs?.validateMode, u = n.render({
121
+ function w(u) {
122
+ const n = v(null), e = R(u.form, u.path, {
123
+ overrideInitialValue: u.overrideInitialValue ?? !0,
124
+ defaultValue: u.defaultValue
125
+ }), l = u.form.controller.triedSubmitting ? u.form.hookConfigs?.revalidateMode ?? u.form.hookConfigs?.validateMode : u.form.hookConfigs?.validateMode, o = u.render({
149
126
  fieldProps: {
150
- ref: t,
127
+ ref: n,
151
128
  name: e.stringPath,
152
129
  value: e.value,
153
- onChange(l) {
154
- let i;
155
- if (typeof l == "object" && "target" in l) {
156
- const { target: r } = l;
157
- if (r !== e.boundElement || !("value" in r) || typeof r.value != "string") return;
158
- i = r.value;
130
+ onChange(r) {
131
+ let s;
132
+ if (typeof r == "object" && "target" in r) {
133
+ const { target: t } = r;
134
+ if (t !== e.boundElement || !("value" in t) || typeof t.value != "string") return;
135
+ s = t.value;
159
136
  } else
160
- i = l;
161
- e.setValue(i, {
137
+ s = r;
138
+ e.setValue(s, {
162
139
  shouldTouch: !0,
163
140
  shouldMarkDirty: !0
164
141
  });
@@ -167,29 +144,28 @@ function S(n) {
167
144
  e.touch();
168
145
  },
169
146
  onBlur() {
170
- (e.issues.length !== 0 || s === "onBlur" || s === "onChange") && n.form.controller.validateField(n.path);
147
+ (e.issues.length !== 0 || l === "onBlur" || l === "onChange") && u.form.controller.validateField(u.path);
171
148
  }
172
149
  },
173
150
  field: e,
174
- form: n.form
151
+ form: u.form
175
152
  });
176
- return V(() => {
177
- const { events: l } = n.form.controller;
178
- return v(
179
- l.on("fieldValueChanged", (i) => {
180
- !o.equals(i, n.path) && !o.isDescendant(i, n.path) || (e.issues.length !== 0 || s === "onChange") && n.form.controller.validateField(n.path);
153
+ return m(() => {
154
+ const { events: r } = u.form.controller;
155
+ return c(
156
+ r.on("fieldValueChanged", (s) => {
157
+ !i.equals(s, u.path) && !i.isDescendant(s, u.path) || (e.issues.length !== 0 || l === "onChange") && u.form.controller.validateField(u.path);
181
158
  })
182
159
  );
183
- }, [s]), V(() => (e.bindElement(t.current), () => {
184
- n.unbindOnUnmount && n.form.controller.unregisterField(n.path);
185
- }), []), /* @__PURE__ */ R(U, { children: u });
160
+ }, [l]), m(() => (e.bindElement(n.current), () => {
161
+ u.unregisterOnUnmount && u.form.controller.unregisterField(u.path);
162
+ }), []), /* @__PURE__ */ U(I, { children: o });
186
163
  }
187
164
  export {
188
- S as FieldRenderer,
189
- D as useFieldIssues,
190
- h as useFieldValue,
191
- E as useForm,
192
- w as useFormField,
193
- W as useRenderControl
165
+ w as FieldRenderer,
166
+ k as useFieldIssues,
167
+ S as useFieldValue,
168
+ M as useForm,
169
+ R as useFormField
194
170
  };
195
171
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/hooks/useSyncMutableStore.ts","../src/utils/composeFns.ts","../src/hooks/useForm.tsx","../src/hooks/useFormField.tsx","../src/hooks/useFieldValue.ts","../src/hooks/useFieldIssues.ts","../src/hooks/useRenderControl.tsx","../src/components/FieldRenderer.tsx"],"sourcesContent":["import { useCallback, useRef, useSyncExternalStore } from \"react\";\r\n\r\nexport function useSyncMutableStore<T>(\r\n subscribe: (onVersionChange: () => void) => () => void,\r\n getValue: () => T,\r\n) {\r\n const versionRef = useRef(0);\r\n\r\n const subscribeWithVersion = useCallback(\r\n (onStoreChange: () => void) => {\r\n return subscribe(() => {\r\n versionRef.current++;\r\n onStoreChange();\r\n });\r\n },\r\n [subscribe],\r\n );\r\n\r\n const getSnapshot = useCallback(() => {\r\n return versionRef.current;\r\n }, []);\r\n\r\n useSyncExternalStore(subscribeWithVersion, getSnapshot, getSnapshot);\r\n\r\n return getValue();\r\n}\r\n","export function composeFns<TFns extends (() => void)[]>(...fns: TFns) {\r\n return () => {\r\n for (const fn of fns) {\r\n fn();\r\n }\r\n };\r\n}\r\n","import { FormController } from \"@goodie-forms/core\";\r\nimport { useCallback, useState, useSyncExternalStore } from \"react\";\r\nimport { useSyncMutableStore } from \"../hooks/useSyncMutableStore\";\r\nimport { composeFns } from \"../utils/composeFns\";\r\n\r\nexport function useForm<TOutput extends object>(\r\n formConfigs: FormController.Configs<TOutput>,\r\n hookConfigs?: {\r\n validateMode?: \"onChange\" | \"onBlur\" | \"onSubmit\";\r\n revalidateMode?: \"onChange\" | \"onBlur\" | \"onSubmit\";\r\n watchIssues?: boolean;\r\n watchValues?: boolean;\r\n },\r\n) {\r\n const [controller] = useState(() => new FormController(formConfigs));\r\n\r\n const subscribe = useCallback(\r\n (onVersionChange: () => void) => {\r\n const noop = () => {};\r\n\r\n return composeFns(\r\n controller.events.on(\"submissionStatusChange\", onVersionChange),\r\n hookConfigs?.watchIssues\r\n ? controller.events.on(\"fieldIssuesUpdated\", onVersionChange)\r\n : noop,\r\n hookConfigs?.watchValues\r\n ? controller.events.on(\"fieldValueChanged\", onVersionChange)\r\n : noop,\r\n );\r\n },\r\n [controller, hookConfigs?.watchIssues, hookConfigs?.watchValues],\r\n );\r\n\r\n useSyncMutableStore(subscribe, () => controller);\r\n\r\n const useWatchValues = () => {\r\n return useSyncExternalStore(\r\n (onStoreChange) =>\r\n controller.events.on(\"fieldValueChanged\", onStoreChange),\r\n () => controller.data,\r\n () => controller.data,\r\n );\r\n };\r\n\r\n const useWatchIssues = () => {\r\n return useSyncExternalStore(\r\n (onStoreChange) =>\r\n controller.events.on(\"fieldIssuesUpdated\", onStoreChange),\r\n () => controller.issues,\r\n () => controller.issues,\r\n );\r\n };\r\n\r\n const useWatchEvent = <E extends keyof typeof controller.events.events>(\r\n eventName: E,\r\n listener?: NonNullable<(typeof controller.events.events)[E]>[number],\r\n ) => {\r\n return useSyncMutableStore(\r\n (onVersionChange) =>\r\n controller.events.on(eventName, (...args: any[]) => {\r\n (listener as any)?.(...args);\r\n onVersionChange();\r\n }),\r\n () => undefined,\r\n );\r\n };\r\n\r\n return {\r\n formConfigs,\r\n hookConfigs,\r\n controller,\r\n path: controller.path,\r\n watchValues: useWatchValues,\r\n watchIssues: useWatchIssues,\r\n watchEvent: useWatchEvent,\r\n };\r\n}\r\n\r\nexport type UseForm<TOutput extends object> = ReturnType<\r\n typeof useForm<TOutput>\r\n>;\r\n","import { FieldPath, FormField } from \"@goodie-forms/core\";\r\nimport { useCallback, useRef, useState, useSyncExternalStore } from \"react\";\r\nimport { UseForm } from \"../hooks/useForm\";\r\nimport { composeFns } from \"../utils/composeFns\";\r\n\r\nexport function useFormField<\r\n TOutput extends object,\r\n TPath extends FieldPath.Segments,\r\n>(\r\n form: UseForm<TOutput>,\r\n path: TPath,\r\n): FormField<TOutput, FieldPath.Resolve<TOutput, TPath>> | undefined;\r\n\r\nexport function useFormField<\r\n TOutput extends object,\r\n TPath extends FieldPath.Segments,\r\n>(\r\n form: UseForm<TOutput>,\r\n path: TPath,\r\n bindingConfig: Parameters<typeof form.controller.registerField<TPath>>[1],\r\n): FormField<TOutput, FieldPath.Resolve<TOutput, TPath>>;\r\n\r\nexport function useFormField<\r\n TOutput extends object,\r\n TPath extends FieldPath.Segments,\r\n>(\r\n form: UseForm<TOutput>,\r\n path: TPath,\r\n bindingConfig?: Parameters<typeof form.controller.registerField<TPath>>[1],\r\n) {\r\n const { controller } = form;\r\n\r\n const version = useRef(0);\r\n\r\n useState(() => {\r\n let existing = controller.getField(path);\r\n\r\n if (!existing && bindingConfig) {\r\n controller.registerField(path, bindingConfig);\r\n }\r\n\r\n return null;\r\n });\r\n\r\n const subscribe = useCallback(\r\n (onStoreChange: () => void) => {\r\n const { events } = controller;\r\n\r\n return composeFns(\r\n events.on(\"fieldRegistered\", (_path) => {\r\n if (FieldPath.equals(_path, path)) {\r\n version.current++;\r\n onStoreChange();\r\n }\r\n }),\r\n events.on(\"fieldUnregistered\", (_path) => {\r\n if (FieldPath.equals(_path, path)) {\r\n version.current++;\r\n onStoreChange();\r\n }\r\n }),\r\n events.on(\"fieldValueChanged\", (changedPath) => {\r\n if (\r\n FieldPath.equals(changedPath, path) ||\r\n FieldPath.isDescendant(changedPath, path)\r\n ) {\r\n version.current++;\r\n onStoreChange();\r\n }\r\n }),\r\n events.on(\"fieldTouchUpdated\", (_path) => {\r\n if (FieldPath.equals(_path, path)) {\r\n version.current++;\r\n onStoreChange();\r\n }\r\n }),\r\n events.on(\"fieldDirtyUpdated\", (_path) => {\r\n if (FieldPath.equals(_path, path)) {\r\n version.current++;\r\n onStoreChange();\r\n }\r\n }),\r\n events.on(\"fieldIssuesUpdated\", (_path) => {\r\n if (FieldPath.equals(_path, path)) {\r\n version.current++;\r\n onStoreChange();\r\n }\r\n }),\r\n );\r\n },\r\n [controller, path],\r\n );\r\n\r\n const getSnapshot = useCallback(() => version.current, [controller, path]);\r\n\r\n useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\r\n\r\n return controller.getField(path);\r\n}\r\n","import { FieldPath } from \"@goodie-forms/core\";\r\nimport { useCallback, useSyncExternalStore } from \"react\";\r\nimport { UseForm } from \"../hooks/useForm\";\r\nimport { composeFns } from \"../utils/composeFns\";\r\n\r\nexport function useFieldValue<\r\n TOutput extends object,\r\n TPath extends FieldPath.Segments,\r\n>(form: UseForm<TOutput>, path: TPath) {\r\n const { controller } = form;\r\n\r\n const subscribe = useCallback(\r\n (onStoreChange: () => void) => {\r\n const { events } = controller;\r\n\r\n return composeFns(\r\n events.on(\"fieldRegistered\", (fieldPath) => {\r\n if (FieldPath.equals(path, fieldPath)) {\r\n onStoreChange();\r\n }\r\n }),\r\n events.on(\"fieldUnregistered\", (fieldPath) => {\r\n if (FieldPath.equals(path, fieldPath)) {\r\n onStoreChange();\r\n }\r\n }),\r\n events.on(\"fieldValueChanged\", (changedPath) => {\r\n if (\r\n FieldPath.equals(changedPath, path) ||\r\n FieldPath.isDescendant(changedPath, path)\r\n ) {\r\n onStoreChange();\r\n }\r\n }),\r\n );\r\n },\r\n [controller, path],\r\n );\r\n\r\n const getSnapshot = useCallback(() => {\r\n return controller.getField(path)?.value;\r\n }, [controller, path]);\r\n\r\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\r\n}\r\n","import { FieldPath } from \"@goodie-forms/core\";\r\nimport { useCallback, useSyncExternalStore } from \"react\";\r\nimport { composeFns } from \"../utils/composeFns\";\r\nimport { UseForm } from \"./useForm\";\r\n\r\nexport function useFieldIssues<\r\n TOutput extends object,\r\n TPath extends FieldPath.Segments,\r\n>(form: UseForm<TOutput>, path: TPath) {\r\n const { controller } = form;\r\n\r\n const subscribe = useCallback(\r\n (onStoreChange: () => void) => {\r\n const { events } = controller;\r\n\r\n return composeFns(\r\n events.on(\"fieldRegistered\", (fieldPath) => {\r\n if (FieldPath.equals(path, fieldPath)) {\r\n onStoreChange();\r\n }\r\n }),\r\n events.on(\"fieldUnregistered\", (fieldPath) => {\r\n if (FieldPath.equals(path, fieldPath)) {\r\n onStoreChange();\r\n }\r\n }),\r\n events.on(\"fieldIssuesUpdated\", (fieldPath) => {\r\n if (FieldPath.equals(path, fieldPath)) {\r\n onStoreChange();\r\n }\r\n }),\r\n );\r\n },\r\n [controller, path],\r\n );\r\n\r\n const getSnapshot = useCallback(() => {\r\n return controller.getField(path)?.issues ?? [];\r\n }, [controller, path]);\r\n\r\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\r\n}\r\n","import { startTransition, useRef, useState } from \"react\";\r\n\r\nexport function useRenderControl() {\r\n const [, rerender] = useState(0);\r\n const renderCount = useRef(0);\r\n const renderScheduled = useRef(false);\r\n renderCount.current++;\r\n\r\n const scheduleRerender = () => {\r\n if (renderScheduled.current) return;\r\n renderScheduled.current = true;\r\n\r\n queueMicrotask(() => {\r\n startTransition(() => {\r\n rerender((i) => i + 1);\r\n });\r\n\r\n renderScheduled.current = false;\r\n });\r\n };\r\n\r\n return {\r\n renderCount: renderCount.current,\r\n forceRerender: scheduleRerender,\r\n };\r\n}\r\n","import {\r\n DeepReadonly,\r\n FieldPath,\r\n FormField,\r\n Suppliable,\r\n} from \"@goodie-forms/core\";\r\nimport { ChangeEvent, ReactNode, Ref, useEffect, useRef } from \"react\";\r\nimport { UseForm } from \"../hooks/useForm\";\r\nimport { useFormField } from \"../hooks/useFormField\";\r\nimport { composeFns } from \"../utils/composeFns\";\r\n\r\nexport interface RenderParams<TOutput extends object, TValue> {\r\n fieldProps: {\r\n ref: Ref<any | null>;\r\n\r\n name: string;\r\n\r\n value: DeepReadonly<TValue> | undefined;\r\n\r\n onChange: (event: ChangeEvent<EventTarget> | TValue) => void;\r\n onFocus: () => void;\r\n onBlur: () => void;\r\n };\r\n\r\n field: FormField<TOutput, TValue>;\r\n\r\n form: UseForm<TOutput>;\r\n}\r\n\r\ntype DefaultValueProps<TValue> = undefined extends TValue\r\n ? { defaultValue?: Suppliable<TValue> }\r\n : { defaultValue: Suppliable<TValue> };\r\n\r\nexport type FieldRendererProps<\r\n TOutput extends object,\r\n TPath extends FieldPath.Segments,\r\n> = DefaultValueProps<FieldPath.Resolve<TOutput, TPath>> & {\r\n form: UseForm<TOutput>;\r\n path: TPath;\r\n overrideInitialValue?: boolean;\r\n unbindOnUnmount?: boolean;\r\n render: (\r\n params: RenderParams<TOutput, FieldPath.Resolve<TOutput, TPath>>,\r\n ) => ReactNode;\r\n};\r\n\r\nexport function FieldRenderer<\r\n TOutput extends object,\r\n const TPath extends FieldPath.Segments,\r\n>(props: FieldRendererProps<TOutput, TPath>) {\r\n type TValue = FieldPath.Resolve<TOutput, TPath>;\r\n\r\n const elementRef = useRef<HTMLElement>(null);\r\n\r\n const field = useFormField(props.form, props.path, {\r\n overrideInitialValue: props.overrideInitialValue ?? true,\r\n defaultValue: props.defaultValue,\r\n })!;\r\n\r\n const currentValidateMode = props.form.controller.triedSubmitting\r\n ? (props.form.hookConfigs?.revalidateMode ??\r\n props.form.hookConfigs?.validateMode)\r\n : props.form.hookConfigs?.validateMode;\r\n\r\n const renderedJsx = props.render({\r\n fieldProps: {\r\n ref: elementRef,\r\n name: field.stringPath,\r\n value: field.value,\r\n onChange(arg) {\r\n let newValue: TValue;\r\n\r\n if (typeof arg === \"object\" && \"target\" in arg) {\r\n const { target } = arg;\r\n if (target !== field.boundElement) return;\r\n if (!(\"value\" in target)) return;\r\n if (typeof target.value !== \"string\") return;\r\n newValue = target.value as TValue;\r\n } else {\r\n newValue = arg;\r\n }\r\n\r\n field.setValue(newValue, {\r\n shouldTouch: true,\r\n shouldMarkDirty: true,\r\n });\r\n },\r\n onFocus() {\r\n field.touch();\r\n },\r\n onBlur() {\r\n if (\r\n field.issues.length !== 0 ||\r\n currentValidateMode === \"onBlur\" ||\r\n currentValidateMode === \"onChange\"\r\n ) {\r\n props.form.controller.validateField(props.path);\r\n }\r\n },\r\n },\r\n field: field as any,\r\n form: props.form,\r\n });\r\n\r\n useEffect(() => {\r\n const { events } = props.form.controller;\r\n\r\n return composeFns(\r\n events.on(\"fieldValueChanged\", (_path) => {\r\n if (\r\n !FieldPath.equals(_path, props.path) &&\r\n !FieldPath.isDescendant(_path, props.path)\r\n ) {\r\n return;\r\n }\r\n\r\n if (field.issues.length !== 0 || currentValidateMode === \"onChange\") {\r\n props.form.controller.validateField(props.path);\r\n }\r\n }),\r\n );\r\n }, [currentValidateMode]);\r\n\r\n useEffect(() => {\r\n field.bindElement(elementRef.current!);\r\n\r\n return () => {\r\n if (props.unbindOnUnmount) {\r\n props.form.controller.unregisterField(props.path);\r\n }\r\n };\r\n }, []);\r\n\r\n return <>{renderedJsx}</>;\r\n}\r\n\r\n/* ---- TESTS ---------------- */\r\n\r\n// function TestComp() {\r\n// const form = useForm<{ a?: { b: 99 } }>({});\r\n\r\n// const jsx = (\r\n// <>\r\n// <FieldRenderer\r\n// form={form}\r\n// path={form.paths.fromProxy((data) => data.a.b)}\r\n// defaultValue={() => 99 as const}\r\n// render={({ fieldProps, field }) => {\r\n// // ^?\r\n// return <input {...fieldProps} />;\r\n// }}\r\n// />\r\n\r\n// {/* defaultField olmayabilir, çünkü \"a\" nullable */}\r\n// <FieldRenderer\r\n// form={form}\r\n// path={form.paths.fromProxy((data) => data.a)}\r\n// render={({ ref, value, handlers, field }) => {\r\n// // ^?\r\n// return <></>;\r\n// }}\r\n// />\r\n\r\n// <FieldRenderer\r\n// form={form}\r\n// path={form.paths.fromStringPath(\"a.b\")}\r\n// defaultValue={() => 99 as const}\r\n// render={({ ref, value, handlers, field }) => {\r\n// // ^?\r\n// return <></>;\r\n// }}\r\n// />\r\n// </>\r\n// );\r\n// }\r\n"],"names":["useSyncMutableStore","subscribe","getValue","versionRef","useRef","subscribeWithVersion","useCallback","onStoreChange","getSnapshot","useSyncExternalStore","composeFns","fns","fn","useForm","formConfigs","hookConfigs","controller","useState","FormController","onVersionChange","noop","useWatchValues","useWatchIssues","useWatchEvent","eventName","listener","args","useFormField","form","path","bindingConfig","version","events","_path","FieldPath","changedPath","useFieldValue","fieldPath","useFieldIssues","useRenderControl","rerender","renderCount","renderScheduled","scheduleRerender","startTransition","i","FieldRenderer","props","elementRef","field","currentValidateMode","renderedJsx","arg","newValue","target","useEffect"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/hooks/useSyncMutableStore.ts","../src/hooks/useForm.tsx","../src/utils/composeFns.ts","../src/hooks/useFormField.tsx","../src/hooks/useFieldValue.ts","../src/hooks/useFieldIssues.ts","../src/components/FieldRenderer.tsx"],"sourcesContent":["import { useCallback, useRef, useSyncExternalStore } from \"react\";\r\n\r\nexport function useSyncMutableStore<T>(\r\n subscribe: (onVersionChange: () => void) => () => void,\r\n getValue: () => T,\r\n) {\r\n const versionRef = useRef(0);\r\n\r\n const subscribeWithVersion = useCallback(\r\n (onStoreChange: () => void) => {\r\n return subscribe(() => {\r\n versionRef.current++;\r\n onStoreChange();\r\n });\r\n },\r\n [subscribe],\r\n );\r\n\r\n const getSnapshot = useCallback(() => {\r\n return versionRef.current;\r\n }, []);\r\n\r\n useSyncExternalStore(subscribeWithVersion, getSnapshot, getSnapshot);\r\n\r\n return getValue();\r\n}\r\n","import { FormController } from \"@goodie-forms/core\";\r\nimport { useCallback, useState, useSyncExternalStore } from \"react\";\r\nimport { useSyncMutableStore } from \"../hooks/useSyncMutableStore\";\r\n\r\nexport function useForm<TOutput extends object>(\r\n formConfigs: FormController.Configs<TOutput>,\r\n hookConfigs?: {\r\n validateMode?: \"onChange\" | \"onBlur\" | \"onSubmit\";\r\n revalidateMode?: \"onChange\" | \"onBlur\" | \"onSubmit\";\r\n },\r\n) {\r\n const [controller] = useState(() => new FormController(formConfigs));\r\n\r\n const subscribe = useCallback(\r\n (onVersionChange: () => void) => {\r\n return controller.events.on(\"submissionStatusChange\", onVersionChange);\r\n },\r\n [controller],\r\n );\r\n\r\n useSyncMutableStore(subscribe, () => controller);\r\n\r\n const useWatchValues = () => {\r\n return useSyncExternalStore(\r\n (onStoreChange) =>\r\n controller.events.on(\"fieldValueChanged\", onStoreChange),\r\n () => controller.data,\r\n () => controller.data,\r\n );\r\n };\r\n\r\n const useWatchIssues = () => {\r\n return useSyncExternalStore(\r\n (onStoreChange) =>\r\n controller.events.on(\"fieldIssuesUpdated\", onStoreChange),\r\n () => controller.issues,\r\n () => controller.issues,\r\n );\r\n };\r\n\r\n const useWatchEvent = <E extends keyof typeof controller.events.events>(\r\n eventName: E,\r\n listener?: NonNullable<(typeof controller.events.events)[E]>[number],\r\n ) => {\r\n return useSyncMutableStore(\r\n (onVersionChange) =>\r\n controller.events.on(eventName, (...args: any[]) => {\r\n (listener as any)?.(...args);\r\n onVersionChange();\r\n }),\r\n () => undefined,\r\n );\r\n };\r\n\r\n return {\r\n formConfigs,\r\n hookConfigs,\r\n controller,\r\n path: controller.path,\r\n watchValues: useWatchValues,\r\n watchIssues: useWatchIssues,\r\n watchEvent: useWatchEvent,\r\n };\r\n}\r\n\r\nexport type UseForm<TOutput extends object> = ReturnType<\r\n typeof useForm<TOutput>\r\n>;\r\n","export function composeFns<TFns extends (() => void)[]>(...fns: TFns) {\r\n return () => {\r\n for (const fn of fns) {\r\n fn();\r\n }\r\n };\r\n}\r\n","import { FieldPath, FormField } from \"@goodie-forms/core\";\r\nimport { useCallback, useState } from \"react\";\r\nimport { UseForm } from \"../hooks/useForm\";\r\nimport { useSyncMutableStore } from \"../hooks/useSyncMutableStore\";\r\nimport { composeFns } from \"../utils/composeFns\";\r\n\r\nexport function useFormField<\r\n TOutput extends object,\r\n TPath extends FieldPath.Segments,\r\n>(\r\n form: UseForm<TOutput>,\r\n path: TPath,\r\n): FormField<TOutput, FieldPath.Resolve<TOutput, TPath>> | undefined;\r\n\r\nexport function useFormField<\r\n TOutput extends object,\r\n TPath extends FieldPath.Segments,\r\n>(\r\n form: UseForm<TOutput>,\r\n path: TPath,\r\n registerConfig: Parameters<typeof form.controller.registerField<TPath>>[1],\r\n): FormField<TOutput, FieldPath.Resolve<TOutput, TPath>>;\r\n\r\nexport function useFormField<\r\n TOutput extends object,\r\n TPath extends FieldPath.Segments,\r\n>(\r\n form: UseForm<TOutput>,\r\n path: TPath,\r\n registerConfig?: Parameters<typeof form.controller.registerField<TPath>>[1],\r\n) {\r\n const { controller } = form;\r\n\r\n useState(() => {\r\n let existing = controller.getField(path);\r\n\r\n if (!existing && registerConfig) {\r\n controller.registerField(path, registerConfig);\r\n }\r\n\r\n return null;\r\n });\r\n\r\n const subscribe = useCallback(\r\n (onVersionChange: () => void) => {\r\n const { events } = controller;\r\n\r\n return composeFns(\r\n events.on(\"fieldRegistered\", (_path) => {\r\n if (FieldPath.equals(_path, path)) {\r\n onVersionChange();\r\n }\r\n }),\r\n events.on(\"fieldUnregistered\", (_path) => {\r\n if (FieldPath.equals(_path, path)) {\r\n onVersionChange();\r\n }\r\n }),\r\n events.on(\"fieldValueChanged\", (changedPath) => {\r\n if (\r\n FieldPath.equals(changedPath, path) ||\r\n FieldPath.isDescendant(changedPath, path)\r\n ) {\r\n onVersionChange();\r\n }\r\n }),\r\n events.on(\"fieldTouchUpdated\", (_path) => {\r\n if (FieldPath.equals(_path, path)) {\r\n onVersionChange();\r\n }\r\n }),\r\n events.on(\"fieldDirtyUpdated\", (_path) => {\r\n if (FieldPath.equals(_path, path)) {\r\n onVersionChange();\r\n }\r\n }),\r\n events.on(\"fieldIssuesUpdated\", (_path) => {\r\n if (FieldPath.equals(_path, path)) {\r\n onVersionChange();\r\n }\r\n }),\r\n );\r\n },\r\n [controller, path],\r\n );\r\n\r\n return useSyncMutableStore(subscribe, () => controller.getField(path));\r\n}\r\n","import { FieldPath } from \"@goodie-forms/core\";\r\nimport { useCallback, useSyncExternalStore } from \"react\";\r\nimport { UseForm } from \"../hooks/useForm\";\r\nimport { composeFns } from \"../utils/composeFns\";\r\n\r\nexport function useFieldValue<\r\n TOutput extends object,\r\n TPath extends FieldPath.Segments,\r\n>(form: UseForm<TOutput>, path: TPath) {\r\n const { controller } = form;\r\n\r\n const subscribe = useCallback(\r\n (onStoreChange: () => void) => {\r\n const { events } = controller;\r\n\r\n return composeFns(\r\n events.on(\"fieldRegistered\", (fieldPath) => {\r\n if (FieldPath.equals(path, fieldPath)) {\r\n onStoreChange();\r\n }\r\n }),\r\n events.on(\"fieldUnregistered\", (fieldPath) => {\r\n if (FieldPath.equals(path, fieldPath)) {\r\n onStoreChange();\r\n }\r\n }),\r\n events.on(\"fieldValueChanged\", (changedPath) => {\r\n if (\r\n FieldPath.equals(changedPath, path) ||\r\n FieldPath.isDescendant(changedPath, path)\r\n ) {\r\n onStoreChange();\r\n }\r\n }),\r\n );\r\n },\r\n [controller, path],\r\n );\r\n\r\n const getSnapshot = useCallback(() => {\r\n return controller.getField(path)?.value;\r\n }, [controller, path]);\r\n\r\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\r\n}\r\n","import { FieldPath } from \"@goodie-forms/core\";\r\nimport { useCallback, useSyncExternalStore } from \"react\";\r\nimport { composeFns } from \"../utils/composeFns\";\r\nimport { UseForm } from \"./useForm\";\r\n\r\nexport function useFieldIssues<\r\n TOutput extends object,\r\n TPath extends FieldPath.Segments,\r\n>(form: UseForm<TOutput>, path: TPath) {\r\n const { controller } = form;\r\n\r\n const subscribe = useCallback(\r\n (onStoreChange: () => void) => {\r\n const { events } = controller;\r\n\r\n return composeFns(\r\n events.on(\"fieldRegistered\", (fieldPath) => {\r\n if (FieldPath.equals(path, fieldPath)) {\r\n onStoreChange();\r\n }\r\n }),\r\n events.on(\"fieldUnregistered\", (fieldPath) => {\r\n if (FieldPath.equals(path, fieldPath)) {\r\n onStoreChange();\r\n }\r\n }),\r\n events.on(\"fieldIssuesUpdated\", (fieldPath) => {\r\n if (FieldPath.equals(path, fieldPath)) {\r\n onStoreChange();\r\n }\r\n }),\r\n );\r\n },\r\n [controller, path],\r\n );\r\n\r\n const getSnapshot = useCallback(() => {\r\n return controller.getField(path)?.issues ?? [];\r\n }, [controller, path]);\r\n\r\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\r\n}\r\n","import {\r\n DeepReadonly,\r\n FieldPath,\r\n FormField,\r\n Suppliable,\r\n} from \"@goodie-forms/core\";\r\nimport { ChangeEvent, ReactNode, Ref, useEffect, useRef } from \"react\";\r\nimport { UseForm } from \"../hooks/useForm\";\r\nimport { useFormField } from \"../hooks/useFormField\";\r\nimport { composeFns } from \"../utils/composeFns\";\r\n\r\nexport interface RenderParams<TOutput extends object, TValue> {\r\n fieldProps: {\r\n ref: Ref<any | null>;\r\n\r\n name: string;\r\n\r\n value: DeepReadonly<TValue> | undefined;\r\n\r\n onChange: (event: ChangeEvent<EventTarget> | TValue) => void;\r\n onFocus: () => void;\r\n onBlur: () => void;\r\n };\r\n\r\n field: FormField<TOutput, TValue>;\r\n\r\n form: UseForm<TOutput>;\r\n}\r\n\r\nexport interface FieldRendererProps<\r\n TOutput extends object,\r\n TPath extends FieldPath.Segments,\r\n> {\r\n form: UseForm<TOutput>;\r\n path: TPath;\r\n defaultValue?: Suppliable<FieldPath.Resolve<TOutput, TPath>>;\r\n overrideInitialValue?: boolean;\r\n unregisterOnUnmount?: boolean;\r\n render: (\r\n params: RenderParams<TOutput, FieldPath.Resolve<TOutput, TPath>>,\r\n ) => ReactNode;\r\n}\r\n\r\nexport function FieldRenderer<\r\n TOutput extends object,\r\n const TPath extends FieldPath.Segments,\r\n>(props: FieldRendererProps<TOutput, TPath>) {\r\n type TValue = FieldPath.Resolve<TOutput, TPath>;\r\n\r\n const elementRef = useRef<HTMLElement>(null);\r\n\r\n const field = useFormField(props.form, props.path, {\r\n overrideInitialValue: props.overrideInitialValue ?? true,\r\n defaultValue: props.defaultValue,\r\n })!;\r\n\r\n const currentValidateMode = props.form.controller.triedSubmitting\r\n ? (props.form.hookConfigs?.revalidateMode ??\r\n props.form.hookConfigs?.validateMode)\r\n : props.form.hookConfigs?.validateMode;\r\n\r\n const renderedJsx = props.render({\r\n fieldProps: {\r\n ref: elementRef,\r\n name: field.stringPath,\r\n value: field.value,\r\n onChange(arg) {\r\n let newValue: TValue;\r\n\r\n if (typeof arg === \"object\" && \"target\" in arg) {\r\n const { target } = arg;\r\n if (target !== field.boundElement) return;\r\n if (!(\"value\" in target)) return;\r\n if (typeof target.value !== \"string\") return;\r\n newValue = target.value as TValue;\r\n } else {\r\n newValue = arg;\r\n }\r\n\r\n field.setValue(newValue, {\r\n shouldTouch: true,\r\n shouldMarkDirty: true,\r\n });\r\n },\r\n onFocus() {\r\n field.touch();\r\n },\r\n onBlur() {\r\n if (\r\n field.issues.length !== 0 ||\r\n currentValidateMode === \"onBlur\" ||\r\n currentValidateMode === \"onChange\"\r\n ) {\r\n props.form.controller.validateField(props.path);\r\n }\r\n },\r\n },\r\n field: field as any,\r\n form: props.form,\r\n });\r\n\r\n useEffect(() => {\r\n const { events } = props.form.controller;\r\n\r\n return composeFns(\r\n events.on(\"fieldValueChanged\", (_path) => {\r\n if (\r\n !FieldPath.equals(_path, props.path) &&\r\n !FieldPath.isDescendant(_path, props.path)\r\n ) {\r\n return;\r\n }\r\n\r\n if (field.issues.length !== 0 || currentValidateMode === \"onChange\") {\r\n props.form.controller.validateField(props.path);\r\n }\r\n }),\r\n );\r\n }, [currentValidateMode]);\r\n\r\n useEffect(() => {\r\n field.bindElement(elementRef.current!);\r\n\r\n return () => {\r\n if (props.unregisterOnUnmount) {\r\n props.form.controller.unregisterField(props.path);\r\n }\r\n };\r\n }, []);\r\n\r\n return <>{renderedJsx}</>;\r\n}\r\n\r\n/* ---- TESTS ---------------- */\r\n\r\n// function TestComp() {\r\n// const form = useForm<{ a?: { b: 99 } }>({});\r\n\r\n// const jsx = (\r\n// <>\r\n// <FieldRenderer\r\n// form={form}\r\n// path={form.paths.fromProxy((data) => data.a.b)}\r\n// defaultValue={() => 99 as const}\r\n// render={({ fieldProps, field }) => {\r\n// // ^?\r\n// return <input {...fieldProps} />;\r\n// }}\r\n// />\r\n\r\n// {/* defaultField olmayabilir, çünkü \"a\" nullable */}\r\n// <FieldRenderer\r\n// form={form}\r\n// path={form.paths.fromProxy((data) => data.a)}\r\n// render={({ ref, value, handlers, field }) => {\r\n// // ^?\r\n// return <></>;\r\n// }}\r\n// />\r\n\r\n// <FieldRenderer\r\n// form={form}\r\n// path={form.paths.fromStringPath(\"a.b\")}\r\n// defaultValue={() => 99 as const}\r\n// render={({ ref, value, handlers, field }) => {\r\n// // ^?\r\n// return <></>;\r\n// }}\r\n// />\r\n// </>\r\n// );\r\n// }\r\n"],"names":["useSyncMutableStore","subscribe","getValue","versionRef","useRef","subscribeWithVersion","useCallback","onStoreChange","getSnapshot","useSyncExternalStore","useForm","formConfigs","hookConfigs","controller","useState","FormController","onVersionChange","useWatchValues","useWatchIssues","useWatchEvent","eventName","listener","args","composeFns","fns","fn","useFormField","form","path","registerConfig","events","_path","FieldPath","changedPath","useFieldValue","fieldPath","useFieldIssues","FieldRenderer","props","elementRef","field","currentValidateMode","renderedJsx","arg","newValue","target","useEffect"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,16 @@
1
1
  {
2
2
  "name": "@goodie-forms/react",
3
- "version": "1.2.6-alpha",
3
+ "version": "1.3.0",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/iGoodie/goodie-forms"
7
+ },
8
+ "author": {
9
+ "name": "Taha Anılcan Metinyurt",
10
+ "email": "igoodie@programmer.net",
11
+ "url": "https://github.com/iGoodie"
12
+ },
13
+ "license": "CC BY-SA 4.0",
4
14
  "type": "module",
5
15
  "main": "dist/index.js",
6
16
  "types": "dist/index.d.ts",
@@ -21,7 +31,7 @@
21
31
  "react-dom": "^18 || ^19"
22
32
  },
23
33
  "dependencies": {
24
- "@goodie-forms/core": "1.2.6-alpha"
34
+ "@goodie-forms/core": "1.3.0"
25
35
  },
26
36
  "devDependencies": {
27
37
  "@types/react": "^19.2.9",
@@ -1,5 +0,0 @@
1
- export declare function useRenderControl(): {
2
- renderCount: number;
3
- forceRerender: () => void;
4
- };
5
- //# sourceMappingURL=useRenderControl.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useRenderControl.d.ts","sourceRoot":"","sources":["../../src/hooks/useRenderControl.tsx"],"names":[],"mappings":"AAEA,wBAAgB,gBAAgB;;;EAuB/B"}