@tanstack/react-form 0.10.2 → 0.11.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.
Files changed (49) hide show
  1. package/build/legacy/createFormFactory.cjs.map +1 -1
  2. package/build/legacy/createFormFactory.d.cts +5 -5
  3. package/build/legacy/createFormFactory.d.ts +5 -5
  4. package/build/legacy/createFormFactory.js.map +1 -1
  5. package/build/legacy/formContext.cjs.map +1 -1
  6. package/build/legacy/formContext.d.cts +3 -3
  7. package/build/legacy/formContext.d.ts +3 -3
  8. package/build/legacy/formContext.js.map +1 -1
  9. package/build/legacy/types.cjs.map +1 -1
  10. package/build/legacy/types.d.cts +2 -2
  11. package/build/legacy/types.d.ts +2 -2
  12. package/build/legacy/useField.cjs.map +1 -1
  13. package/build/legacy/useField.d.cts +13 -13
  14. package/build/legacy/useField.d.ts +13 -13
  15. package/build/legacy/useField.js.map +1 -1
  16. package/build/legacy/useForm.cjs.map +1 -1
  17. package/build/legacy/useForm.d.cts +7 -9
  18. package/build/legacy/useForm.d.ts +7 -9
  19. package/build/legacy/useForm.js.map +1 -1
  20. package/build/modern/createFormFactory.cjs.map +1 -1
  21. package/build/modern/createFormFactory.d.cts +5 -5
  22. package/build/modern/createFormFactory.d.ts +5 -5
  23. package/build/modern/createFormFactory.js.map +1 -1
  24. package/build/modern/formContext.cjs.map +1 -1
  25. package/build/modern/formContext.d.cts +3 -3
  26. package/build/modern/formContext.d.ts +3 -3
  27. package/build/modern/formContext.js.map +1 -1
  28. package/build/modern/types.cjs.map +1 -1
  29. package/build/modern/types.d.cts +2 -2
  30. package/build/modern/types.d.ts +2 -2
  31. package/build/modern/useField.cjs.map +1 -1
  32. package/build/modern/useField.d.cts +13 -13
  33. package/build/modern/useField.d.ts +13 -13
  34. package/build/modern/useField.js.map +1 -1
  35. package/build/modern/useForm.cjs.map +1 -1
  36. package/build/modern/useForm.d.cts +7 -9
  37. package/build/modern/useForm.d.ts +7 -9
  38. package/build/modern/useForm.js.map +1 -1
  39. package/package.json +2 -2
  40. package/src/createFormFactory.ts +15 -9
  41. package/src/formContext.ts +2 -2
  42. package/src/tests/createFormFactory.test.tsx +1 -1
  43. package/src/tests/useField.test-d.tsx +10 -6
  44. package/src/tests/useField.test.tsx +45 -33
  45. package/src/tests/useForm.test-d.tsx +36 -0
  46. package/src/tests/useForm.test.tsx +57 -39
  47. package/src/types.ts +13 -4
  48. package/src/useField.tsx +67 -37
  49. package/src/useForm.tsx +16 -11
@@ -1,27 +1,27 @@
1
- import { DeepKeys, DeepValue, Narrow, FieldApi } from '@tanstack/form-core';
1
+ import { DeepKeys, Validator, DeepValue, Narrow, FieldApi } from '@tanstack/form-core';
2
2
  import { UseFieldOptions } from './types.cjs';
3
3
 
4
4
  declare module '@tanstack/form-core' {
5
- interface FieldApi<TParentData, TName extends DeepKeys<TParentData>, ValidatorType, FormValidator, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> {
6
- Field: FieldComponent<TData, FormValidator>;
5
+ interface FieldApi<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> {
6
+ Field: FieldComponent<TParentData, TFormValidator>;
7
7
  }
8
8
  }
9
- type UseField<TParentData> = <TName extends DeepKeys<TParentData>, ValidatorType, FormValidator>(opts?: {
9
+ type UseField<TParentData> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>(opts?: {
10
10
  name: Narrow<TName>;
11
- } & UseFieldOptions<TParentData, TName, ValidatorType, FormValidator>) => FieldApi<TParentData, TName, ValidatorType, FormValidator, DeepValue<TParentData, TName>>;
12
- declare function useField<TParentData, TName extends DeepKeys<TParentData>, ValidatorType, FormValidator>(opts: UseFieldOptions<TParentData, TName, ValidatorType, FormValidator>): FieldApi<TParentData, TName, ValidatorType, FormValidator>;
13
- type FieldComponentProps<TParentData, TName extends DeepKeys<TParentData>, ValidatorType, FormValidator, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = {
14
- children: (fieldApi: FieldApi<TParentData, TName, ValidatorType, FormValidator, TData>) => any;
11
+ } & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>) => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, DeepValue<TParentData, TName>>;
12
+ declare function useField<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>(opts: UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>): FieldApi<TParentData, TName, TFieldValidator, TFormValidator>;
13
+ type FieldComponentProps<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = {
14
+ children: (fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>) => any;
15
15
  } & (TParentData extends any[] ? {
16
16
  name?: TName;
17
17
  index: number;
18
18
  } : {
19
19
  name: TName;
20
20
  index?: never;
21
- }) & Omit<UseFieldOptions<TParentData, TName, ValidatorType, FormValidator>, 'name' | 'index'>;
22
- type FieldComponent<TParentData, FormValidator> = <TName extends DeepKeys<TParentData>, ValidatorType, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>>({ children, ...fieldOptions }: FieldComponentProps<TParentData, TName, ValidatorType, FormValidator, TData>) => any;
23
- declare function Field<TParentData, TName extends DeepKeys<TParentData>, ValidatorType, FormValidator>({ children, ...fieldOptions }: {
24
- children: (fieldApi: FieldApi<TParentData, TName, ValidatorType, FormValidator>) => any;
25
- } & UseFieldOptions<TParentData, TName, ValidatorType, FormValidator>): JSX.Element;
21
+ }) & Omit<UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>, 'name' | 'index'>;
22
+ type FieldComponent<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>>({ children, ...fieldOptions }: FieldComponentProps<TParentData, TName, TFieldValidator, TFormValidator, TData>) => any;
23
+ declare function Field<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>({ children, ...fieldOptions }: {
24
+ children: (fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator>) => any;
25
+ } & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>): JSX.Element;
26
26
 
27
27
  export { Field, FieldComponent, UseField, useField };
@@ -1,27 +1,27 @@
1
- import { DeepKeys, DeepValue, Narrow, FieldApi } from '@tanstack/form-core';
1
+ import { DeepKeys, Validator, DeepValue, Narrow, FieldApi } from '@tanstack/form-core';
2
2
  import { UseFieldOptions } from './types.js';
3
3
 
4
4
  declare module '@tanstack/form-core' {
5
- interface FieldApi<TParentData, TName extends DeepKeys<TParentData>, ValidatorType, FormValidator, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> {
6
- Field: FieldComponent<TData, FormValidator>;
5
+ interface FieldApi<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> {
6
+ Field: FieldComponent<TParentData, TFormValidator>;
7
7
  }
8
8
  }
9
- type UseField<TParentData> = <TName extends DeepKeys<TParentData>, ValidatorType, FormValidator>(opts?: {
9
+ type UseField<TParentData> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>(opts?: {
10
10
  name: Narrow<TName>;
11
- } & UseFieldOptions<TParentData, TName, ValidatorType, FormValidator>) => FieldApi<TParentData, TName, ValidatorType, FormValidator, DeepValue<TParentData, TName>>;
12
- declare function useField<TParentData, TName extends DeepKeys<TParentData>, ValidatorType, FormValidator>(opts: UseFieldOptions<TParentData, TName, ValidatorType, FormValidator>): FieldApi<TParentData, TName, ValidatorType, FormValidator>;
13
- type FieldComponentProps<TParentData, TName extends DeepKeys<TParentData>, ValidatorType, FormValidator, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = {
14
- children: (fieldApi: FieldApi<TParentData, TName, ValidatorType, FormValidator, TData>) => any;
11
+ } & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>) => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, DeepValue<TParentData, TName>>;
12
+ declare function useField<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>(opts: UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>): FieldApi<TParentData, TName, TFieldValidator, TFormValidator>;
13
+ type FieldComponentProps<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = {
14
+ children: (fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>) => any;
15
15
  } & (TParentData extends any[] ? {
16
16
  name?: TName;
17
17
  index: number;
18
18
  } : {
19
19
  name: TName;
20
20
  index?: never;
21
- }) & Omit<UseFieldOptions<TParentData, TName, ValidatorType, FormValidator>, 'name' | 'index'>;
22
- type FieldComponent<TParentData, FormValidator> = <TName extends DeepKeys<TParentData>, ValidatorType, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>>({ children, ...fieldOptions }: FieldComponentProps<TParentData, TName, ValidatorType, FormValidator, TData>) => any;
23
- declare function Field<TParentData, TName extends DeepKeys<TParentData>, ValidatorType, FormValidator>({ children, ...fieldOptions }: {
24
- children: (fieldApi: FieldApi<TParentData, TName, ValidatorType, FormValidator>) => any;
25
- } & UseFieldOptions<TParentData, TName, ValidatorType, FormValidator>): JSX.Element;
21
+ }) & Omit<UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>, 'name' | 'index'>;
22
+ type FieldComponent<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>>({ children, ...fieldOptions }: FieldComponentProps<TParentData, TName, TFieldValidator, TFormValidator, TData>) => any;
23
+ declare function Field<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>({ children, ...fieldOptions }: {
24
+ children: (fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator>) => any;
25
+ } & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>): JSX.Element;
26
26
 
27
27
  export { Field, FieldComponent, UseField, useField };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/useField.tsx"],"sourcesContent":["import React, { useState } from 'react'\nimport { useStore } from '@tanstack/react-store'\nimport type { DeepKeys, DeepValue, Narrow } from '@tanstack/form-core'\nimport { FieldApi, functionalUpdate } from '@tanstack/form-core'\nimport { useFormContext, formContext } from './formContext'\nimport type { UseFieldOptions } from './types'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FieldApi<\n TParentData,\n TName extends DeepKeys<TParentData>,\n ValidatorType,\n FormValidator,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n > {\n Field: FieldComponent<TData, FormValidator>\n }\n}\n\nexport type UseField<TParentData> = <\n TName extends DeepKeys<TParentData>,\n ValidatorType,\n FormValidator,\n>(\n opts?: { name: Narrow<TName> } & UseFieldOptions<\n TParentData,\n TName,\n ValidatorType,\n FormValidator\n >,\n) => FieldApi<\n TParentData,\n TName,\n ValidatorType,\n FormValidator,\n DeepValue<TParentData, TName>\n>\n\nexport function useField<\n TParentData,\n TName extends DeepKeys<TParentData>,\n ValidatorType,\n FormValidator,\n>(\n opts: UseFieldOptions<TParentData, TName, ValidatorType, FormValidator>,\n): FieldApi<\n TParentData,\n TName,\n ValidatorType,\n FormValidator\n // Omit<typeof opts, 'onMount'> & {\n // form: FormApi<TParentData>\n // }\n> {\n // Get the form API either manually or from context\n const { formApi, parentFieldName } = useFormContext()\n\n const [fieldApi] = useState(() => {\n const name = (\n typeof opts.index === 'number'\n ? [parentFieldName, opts.index, opts.name]\n : [parentFieldName, opts.name]\n )\n .filter((d) => d !== undefined)\n .join('.')\n\n const api = new FieldApi({\n ...opts,\n form: formApi,\n // TODO: Fix typings to include `index` and `parentFieldName`, if present\n name: name as typeof opts.name,\n })\n\n api.Field = Field as never\n\n return api\n })\n\n /**\n * fieldApi.update should not have any side effects. Think of it like a `useRef`\n * that we need to keep updated every render with the most up-to-date information.\n */\n useIsomorphicLayoutEffect(() => {\n fieldApi.update({ ...opts, form: formApi } as never)\n })\n\n useStore(\n fieldApi.store,\n opts.mode === 'array'\n ? (state) => {\n return [state.meta, Object.keys(state.value).length]\n }\n : undefined,\n )\n // Instantiates field meta and removes it when unrendered\n useIsomorphicLayoutEffect(() => fieldApi.mount(), [fieldApi])\n\n return fieldApi\n}\n\ntype FieldComponentProps<\n TParentData,\n TName extends DeepKeys<TParentData>,\n ValidatorType,\n FormValidator,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = {\n children: (\n fieldApi: FieldApi<TParentData, TName, ValidatorType, FormValidator, TData>,\n ) => any\n} & (TParentData extends any[]\n ? {\n name?: TName\n index: number\n }\n : {\n name: TName\n index?: never\n }) &\n Omit<\n UseFieldOptions<TParentData, TName, ValidatorType, FormValidator>,\n 'name' | 'index'\n >\n\nexport type FieldComponent<TParentData, FormValidator> = <\n TName extends DeepKeys<TParentData>,\n ValidatorType,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n>({\n children,\n ...fieldOptions\n}: FieldComponentProps<\n TParentData,\n TName,\n ValidatorType,\n FormValidator,\n TData\n>) => any\n\nexport function Field<\n TParentData,\n TName extends DeepKeys<TParentData>,\n ValidatorType,\n FormValidator,\n>({\n children,\n ...fieldOptions\n}: {\n children: (\n fieldApi: FieldApi<TParentData, TName, ValidatorType, FormValidator>,\n ) => any\n} & UseFieldOptions<TParentData, TName, ValidatorType, FormValidator>) {\n const fieldApi = useField(fieldOptions as any)\n\n return (\n <formContext.Provider\n value={{\n formApi: fieldApi.form as never,\n parentFieldName: fieldApi.name,\n }}\n children={functionalUpdate(children, fieldApi as any)}\n />\n )\n}\n"],"mappings":";AAAA,OAAO,SAAS,gBAAgB;AAChC,SAAS,gBAAgB;AAEzB,SAAS,UAAU,wBAAwB;AAC3C,SAAS,gBAAgB,mBAAmB;AAE5C,SAAS,iCAAiC;AAkCnC,SAAS,SAMd,MASA;AAEA,QAAM,EAAE,SAAS,gBAAgB,IAAI,eAAe;AAEpD,QAAM,CAAC,QAAQ,IAAI,SAAS,MAAM;AAChC,UAAM,QACJ,OAAO,KAAK,UAAU,WAClB,CAAC,iBAAiB,KAAK,OAAO,KAAK,IAAI,IACvC,CAAC,iBAAiB,KAAK,IAAI,GAE9B,OAAO,CAAC,MAAM,MAAM,MAAS,EAC7B,KAAK,GAAG;AAEX,UAAM,MAAM,IAAI,SAAS;AAAA,MACvB,GAAG;AAAA,MACH,MAAM;AAAA;AAAA,MAEN;AAAA,IACF,CAAC;AAED,QAAI,QAAQ;AAEZ,WAAO;AAAA,EACT,CAAC;AAMD,4BAA0B,MAAM;AAC9B,aAAS,OAAO,EAAE,GAAG,MAAM,MAAM,QAAQ,CAAU;AAAA,EACrD,CAAC;AAED;AAAA,IACE,SAAS;AAAA,IACT,KAAK,SAAS,UACV,CAAC,UAAU;AACT,aAAO,CAAC,MAAM,MAAM,OAAO,KAAK,MAAM,KAAK,EAAE,MAAM;AAAA,IACrD,IACA;AAAA,EACN;AAEA,4BAA0B,MAAM,SAAS,MAAM,GAAG,CAAC,QAAQ,CAAC;AAE5D,SAAO;AACT;AAyCO,SAAS,MAKd;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAIuE;AACrE,QAAM,WAAW,SAAS,YAAmB;AAE7C,SACE;AAAA,IAAC,YAAY;AAAA,IAAZ;AAAA,MACC,OAAO;AAAA,QACL,SAAS,SAAS;AAAA,QAClB,iBAAiB,SAAS;AAAA,MAC5B;AAAA,MACA,UAAU,iBAAiB,UAAU,QAAe;AAAA;AAAA,EACtD;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/useField.tsx"],"sourcesContent":["import React, { useState } from 'react'\nimport { useStore } from '@tanstack/react-store'\nimport type {\n DeepKeys,\n DeepValue,\n Narrow,\n Validator,\n} from '@tanstack/form-core'\nimport { FieldApi, functionalUpdate } from '@tanstack/form-core'\nimport { useFormContext, formContext } from './formContext'\nimport type { UseFieldOptions } from './types'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FieldApi<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n > {\n Field: FieldComponent<TParentData, TFormValidator>\n }\n}\n\nexport type UseField<TParentData> = <\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n>(\n opts?: { name: Narrow<TName> } & UseFieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator\n >,\n) => FieldApi<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n DeepValue<TParentData, TName>\n>\n\nexport function useField<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n>(\n opts: UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,\n): FieldApi<TParentData, TName, TFieldValidator, TFormValidator> {\n // Get the form API either manually or from context\n const { formApi, parentFieldName } = useFormContext()\n\n const [fieldApi] = useState(() => {\n const name = (\n typeof opts.index === 'number'\n ? [parentFieldName, opts.index, opts.name]\n : [parentFieldName, opts.name]\n )\n .filter((d) => d !== undefined)\n .join('.')\n\n const api = new FieldApi({\n ...opts,\n form: formApi as never,\n // TODO: Fix typings to include `index` and `parentFieldName`, if present\n name: name as typeof opts.name as never,\n })\n\n api.Field = Field as never\n\n return api\n })\n\n /**\n * fieldApi.update should not have any side effects. Think of it like a `useRef`\n * that we need to keep updated every render with the most up-to-date information.\n */\n useIsomorphicLayoutEffect(() => {\n fieldApi.update({ ...opts, form: formApi } as never)\n })\n\n useStore(\n fieldApi.store,\n opts.mode === 'array'\n ? (state) => {\n return [state.meta, Object.keys(state.value).length]\n }\n : undefined,\n )\n // Instantiates field meta and removes it when unrendered\n useIsomorphicLayoutEffect(() => fieldApi.mount(), [fieldApi])\n\n return fieldApi as never\n}\n\ntype FieldComponentProps<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = {\n children: (\n fieldApi: FieldApi<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) => any\n} & (TParentData extends any[]\n ? {\n name?: TName\n index: number\n }\n : {\n name: TName\n index?: never\n }) &\n Omit<\n UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,\n 'name' | 'index'\n >\n\nexport type FieldComponent<\n TParentData,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n> = <\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n>({\n children,\n ...fieldOptions\n}: FieldComponentProps<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n>) => any\n\nexport function Field<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n>({\n children,\n ...fieldOptions\n}: {\n children: (\n fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator>,\n ) => any\n} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>) {\n const fieldApi = useField(fieldOptions as any)\n\n return (\n <formContext.Provider\n value={{\n formApi: fieldApi.form as never,\n parentFieldName: fieldApi.name,\n }}\n children={functionalUpdate(children, fieldApi as any)}\n />\n )\n}\n"],"mappings":";AAAA,OAAO,SAAS,gBAAgB;AAChC,SAAS,gBAAgB;AAOzB,SAAS,UAAU,wBAAwB;AAC3C,SAAS,gBAAgB,mBAAmB;AAE5C,SAAS,iCAAiC;AA0CnC,SAAS,SAUd,MAC+D;AAE/D,QAAM,EAAE,SAAS,gBAAgB,IAAI,eAAe;AAEpD,QAAM,CAAC,QAAQ,IAAI,SAAS,MAAM;AAChC,UAAM,QACJ,OAAO,KAAK,UAAU,WAClB,CAAC,iBAAiB,KAAK,OAAO,KAAK,IAAI,IACvC,CAAC,iBAAiB,KAAK,IAAI,GAE9B,OAAO,CAAC,MAAM,MAAM,MAAS,EAC7B,KAAK,GAAG;AAEX,UAAM,MAAM,IAAI,SAAS;AAAA,MACvB,GAAG;AAAA,MACH,MAAM;AAAA;AAAA,MAEN;AAAA,IACF,CAAC;AAED,QAAI,QAAQ;AAEZ,WAAO;AAAA,EACT,CAAC;AAMD,4BAA0B,MAAM;AAC9B,aAAS,OAAO,EAAE,GAAG,MAAM,MAAM,QAAQ,CAAU;AAAA,EACrD,CAAC;AAED;AAAA,IACE,SAAS;AAAA,IACT,KAAK,SAAS,UACV,CAAC,UAAU;AACT,aAAO,CAAC,MAAM,MAAM,OAAO,KAAK,MAAM,KAAK,EAAE,MAAM;AAAA,IACrD,IACA;AAAA,EACN;AAEA,4BAA0B,MAAM,SAAS,MAAM,GAAG,CAAC,QAAQ,CAAC;AAE5D,SAAO;AACT;AA0DO,SAAS,MASd;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAI0E;AACxE,QAAM,WAAW,SAAS,YAAmB;AAE7C,SACE;AAAA,IAAC,YAAY;AAAA,IAAZ;AAAA,MACC,OAAO;AAAA,QACL,SAAS,SAAS;AAAA,QAClB,iBAAiB,SAAS;AAAA,MAC5B;AAAA,MACA,UAAU,iBAAiB,UAAU,QAAe;AAAA;AAAA,EACtD;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/useForm.tsx"],"sourcesContent":["import type { FormState, FormOptions } from '@tanstack/form-core'\nimport { FormApi, functionalUpdate } from '@tanstack/form-core'\nimport type { NoInfer } from '@tanstack/react-store'\nimport { useStore } from '@tanstack/react-store'\nimport React, { type ReactNode, useState } from 'react'\nimport { type UseField, type FieldComponent, Field, useField } from './useField'\nimport { formContext } from './formContext'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FormApi<TFormData, ValidatorType> {\n Provider: (props: { children: any }) => any\n Field: FieldComponent<TFormData, ValidatorType>\n useField: UseField<TFormData>\n useStore: <TSelected = NoInfer<FormState<TFormData>>>(\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,\n ) => TSelected\n Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected\n children: ((state: NoInfer<TSelected>) => ReactNode) | ReactNode\n }) => any\n }\n}\n\nexport function useForm<TData, FormValidator>(\n opts?: FormOptions<TData, FormValidator>,\n): FormApi<TData, FormValidator> {\n const [formApi] = useState(() => {\n // @ts-ignore\n const api = new FormApi<TData>(opts)\n\n api.Provider = function Provider(props) {\n useIsomorphicLayoutEffect(api.mount, [])\n return <formContext.Provider {...props} value={{ formApi: api }} />\n }\n api.Field = Field as any\n api.useField = useField as any\n api.useStore = (\n // @ts-ignore\n selector,\n ) => {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useStore(api.store as any, selector as any) as any\n }\n api.Subscribe = (\n // @ts-ignore\n props,\n ) => {\n return functionalUpdate(\n props.children,\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useStore(api.store as any, props.selector as any),\n ) as any\n }\n\n return api\n })\n\n formApi.useStore((state) => state.isSubmitting)\n\n /**\n * formApi.update should not have any side effects. Think of it like a `useRef`\n * that we need to keep updated every render with the most up-to-date information.\n */\n useIsomorphicLayoutEffect(() => {\n formApi.update(opts)\n })\n\n return formApi as any\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,uBAA0C;AAE1C,yBAAyB;AACzB,mBAAgD;AAChD,sBAAoE;AACpE,yBAA4B;AAC5B,uCAA0C;AAkBnC,SAAS,QACd,MAC+B;AAC/B,QAAM,CAAC,OAAO,QAAI,uBAAS,MAAM;AAE/B,UAAM,MAAM,IAAI,yBAAe,IAAI;AAEnC,QAAI,WAAW,SAAS,SAAS,OAAO;AACtC,sEAA0B,IAAI,OAAO,CAAC,CAAC;AACvC,aAAO,6BAAAA,QAAA,cAAC,+BAAY,UAAZ,EAAsB,GAAG,OAAO,OAAO,EAAE,SAAS,IAAI,GAAG;AAAA,IACnE;AACA,QAAI,QAAQ;AACZ,QAAI,WAAW;AACf,QAAI,WAAW,CAEb,aACG;AAEH,iBAAO,6BAAS,IAAI,OAAc,QAAe;AAAA,IACnD;AACA,QAAI,YAAY,CAEd,UACG;AACH,iBAAO;AAAA,QACL,MAAM;AAAA;AAAA,YAEN,6BAAS,IAAI,OAAc,MAAM,QAAe;AAAA,MAClD;AAAA,IACF;AAEA,WAAO;AAAA,EACT,CAAC;AAED,UAAQ,SAAS,CAAC,UAAU,MAAM,YAAY;AAM9C,kEAA0B,MAAM;AAC9B,YAAQ,OAAO,IAAI;AAAA,EACrB,CAAC;AAED,SAAO;AACT;","names":["React"]}
1
+ {"version":3,"sources":["../../src/useForm.tsx"],"sourcesContent":["import type { FormState, FormOptions, Validator } from '@tanstack/form-core'\nimport { FormApi, functionalUpdate } from '@tanstack/form-core'\nimport type { NoInfer } from '@tanstack/react-store'\nimport { useStore } from '@tanstack/react-store'\nimport React, { type PropsWithChildren, type ReactNode, useState } from 'react'\nimport { type UseField, type FieldComponent, Field, useField } from './useField'\nimport { formContext } from './formContext'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FormApi<TFormData, TFormValidator> {\n Provider: (props: PropsWithChildren) => JSX.Element\n Field: FieldComponent<TFormData, TFormValidator>\n useField: UseField<TFormData>\n useStore: <TSelected = NoInfer<FormState<TFormData>>>(\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,\n ) => TSelected\n Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected\n children: ((state: NoInfer<TSelected>) => ReactNode) | ReactNode\n }) => JSX.Element\n }\n}\n\nexport function useForm<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(\n opts?: FormOptions<TFormData, TFormValidator>,\n): FormApi<TFormData, TFormValidator> {\n const [formApi] = useState(() => {\n // @ts-ignore\n const api = new FormApi<TFormData, TFormValidator>(opts)\n\n api.Provider = function Provider(props) {\n useIsomorphicLayoutEffect(api.mount, [])\n return (\n <formContext.Provider {...props} value={{ formApi: api as never }} />\n )\n }\n api.Field = Field as any\n api.useField = useField as any\n api.useStore = (\n // @ts-ignore\n selector,\n ) => {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useStore(api.store as any, selector as any) as any\n }\n api.Subscribe = (\n // @ts-ignore\n props,\n ) => {\n return functionalUpdate(\n props.children,\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useStore(api.store as any, props.selector as any),\n ) as any\n }\n\n return api\n })\n\n formApi.useStore((state) => state.isSubmitting)\n\n /**\n * formApi.update should not have any side effects. Think of it like a `useRef`\n * that we need to keep updated every render with the most up-to-date information.\n */\n useIsomorphicLayoutEffect(() => {\n formApi.update(opts)\n })\n\n return formApi as any\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,uBAA0C;AAE1C,yBAAyB;AACzB,mBAAwE;AACxE,sBAAoE;AACpE,yBAA4B;AAC5B,uCAA0C;AAkBnC,SAAS,QAId,MACoC;AACpC,QAAM,CAAC,OAAO,QAAI,uBAAS,MAAM;AAE/B,UAAM,MAAM,IAAI,yBAAmC,IAAI;AAEvD,QAAI,WAAW,SAAS,SAAS,OAAO;AACtC,sEAA0B,IAAI,OAAO,CAAC,CAAC;AACvC,aACE,6BAAAA,QAAA,cAAC,+BAAY,UAAZ,EAAsB,GAAG,OAAO,OAAO,EAAE,SAAS,IAAa,GAAG;AAAA,IAEvE;AACA,QAAI,QAAQ;AACZ,QAAI,WAAW;AACf,QAAI,WAAW,CAEb,aACG;AAEH,iBAAO,6BAAS,IAAI,OAAc,QAAe;AAAA,IACnD;AACA,QAAI,YAAY,CAEd,UACG;AACH,iBAAO;AAAA,QACL,MAAM;AAAA;AAAA,YAEN,6BAAS,IAAI,OAAc,MAAM,QAAe;AAAA,MAClD;AAAA,IACF;AAEA,WAAO;AAAA,EACT,CAAC;AAED,UAAQ,SAAS,CAAC,UAAU,MAAM,YAAY;AAM9C,kEAA0B,MAAM;AAC9B,YAAQ,OAAO,IAAI;AAAA,EACrB,CAAC;AAED,SAAO;AACT;","names":["React"]}
@@ -1,23 +1,21 @@
1
- import { FormState, FormOptions, FormApi } from '@tanstack/form-core';
1
+ import { FormState, Validator, FormOptions, FormApi } from '@tanstack/form-core';
2
2
  import { NoInfer } from '@tanstack/react-store';
3
- import { ReactNode } from 'react';
3
+ import { PropsWithChildren, ReactNode } from 'react';
4
4
  import { FieldComponent, UseField } from './useField.cjs';
5
5
  import './types.cjs';
6
6
 
7
7
  declare module '@tanstack/form-core' {
8
- interface FormApi<TFormData, ValidatorType> {
9
- Provider: (props: {
10
- children: any;
11
- }) => any;
12
- Field: FieldComponent<TFormData, ValidatorType>;
8
+ interface FormApi<TFormData, TFormValidator> {
9
+ Provider: (props: PropsWithChildren) => JSX.Element;
10
+ Field: FieldComponent<TFormData, TFormValidator>;
13
11
  useField: UseField<TFormData>;
14
12
  useStore: <TSelected = NoInfer<FormState<TFormData>>>(selector?: (state: NoInfer<FormState<TFormData>>) => TSelected) => TSelected;
15
13
  Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
16
14
  selector?: (state: NoInfer<FormState<TFormData>>) => TSelected;
17
15
  children: ((state: NoInfer<TSelected>) => ReactNode) | ReactNode;
18
- }) => any;
16
+ }) => JSX.Element;
19
17
  }
20
18
  }
21
- declare function useForm<TData, FormValidator>(opts?: FormOptions<TData, FormValidator>): FormApi<TData, FormValidator>;
19
+ declare function useForm<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(opts?: FormOptions<TFormData, TFormValidator>): FormApi<TFormData, TFormValidator>;
22
20
 
23
21
  export { useForm };
@@ -1,23 +1,21 @@
1
- import { FormState, FormOptions, FormApi } from '@tanstack/form-core';
1
+ import { FormState, Validator, FormOptions, FormApi } from '@tanstack/form-core';
2
2
  import { NoInfer } from '@tanstack/react-store';
3
- import { ReactNode } from 'react';
3
+ import { PropsWithChildren, ReactNode } from 'react';
4
4
  import { FieldComponent, UseField } from './useField.js';
5
5
  import './types.js';
6
6
 
7
7
  declare module '@tanstack/form-core' {
8
- interface FormApi<TFormData, ValidatorType> {
9
- Provider: (props: {
10
- children: any;
11
- }) => any;
12
- Field: FieldComponent<TFormData, ValidatorType>;
8
+ interface FormApi<TFormData, TFormValidator> {
9
+ Provider: (props: PropsWithChildren) => JSX.Element;
10
+ Field: FieldComponent<TFormData, TFormValidator>;
13
11
  useField: UseField<TFormData>;
14
12
  useStore: <TSelected = NoInfer<FormState<TFormData>>>(selector?: (state: NoInfer<FormState<TFormData>>) => TSelected) => TSelected;
15
13
  Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
16
14
  selector?: (state: NoInfer<FormState<TFormData>>) => TSelected;
17
15
  children: ((state: NoInfer<TSelected>) => ReactNode) | ReactNode;
18
- }) => any;
16
+ }) => JSX.Element;
19
17
  }
20
18
  }
21
- declare function useForm<TData, FormValidator>(opts?: FormOptions<TData, FormValidator>): FormApi<TData, FormValidator>;
19
+ declare function useForm<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(opts?: FormOptions<TFormData, TFormValidator>): FormApi<TFormData, TFormValidator>;
22
20
 
23
21
  export { useForm };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/useForm.tsx"],"sourcesContent":["import type { FormState, FormOptions } from '@tanstack/form-core'\nimport { FormApi, functionalUpdate } from '@tanstack/form-core'\nimport type { NoInfer } from '@tanstack/react-store'\nimport { useStore } from '@tanstack/react-store'\nimport React, { type ReactNode, useState } from 'react'\nimport { type UseField, type FieldComponent, Field, useField } from './useField'\nimport { formContext } from './formContext'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FormApi<TFormData, ValidatorType> {\n Provider: (props: { children: any }) => any\n Field: FieldComponent<TFormData, ValidatorType>\n useField: UseField<TFormData>\n useStore: <TSelected = NoInfer<FormState<TFormData>>>(\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,\n ) => TSelected\n Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected\n children: ((state: NoInfer<TSelected>) => ReactNode) | ReactNode\n }) => any\n }\n}\n\nexport function useForm<TData, FormValidator>(\n opts?: FormOptions<TData, FormValidator>,\n): FormApi<TData, FormValidator> {\n const [formApi] = useState(() => {\n // @ts-ignore\n const api = new FormApi<TData>(opts)\n\n api.Provider = function Provider(props) {\n useIsomorphicLayoutEffect(api.mount, [])\n return <formContext.Provider {...props} value={{ formApi: api }} />\n }\n api.Field = Field as any\n api.useField = useField as any\n api.useStore = (\n // @ts-ignore\n selector,\n ) => {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useStore(api.store as any, selector as any) as any\n }\n api.Subscribe = (\n // @ts-ignore\n props,\n ) => {\n return functionalUpdate(\n props.children,\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useStore(api.store as any, props.selector as any),\n ) as any\n }\n\n return api\n })\n\n formApi.useStore((state) => state.isSubmitting)\n\n /**\n * formApi.update should not have any side effects. Think of it like a `useRef`\n * that we need to keep updated every render with the most up-to-date information.\n */\n useIsomorphicLayoutEffect(() => {\n formApi.update(opts)\n })\n\n return formApi as any\n}\n"],"mappings":";AACA,SAAS,SAAS,wBAAwB;AAE1C,SAAS,gBAAgB;AACzB,OAAO,SAAyB,gBAAgB;AAChD,SAA6C,OAAO,gBAAgB;AACpE,SAAS,mBAAmB;AAC5B,SAAS,iCAAiC;AAkBnC,SAAS,QACd,MAC+B;AAC/B,QAAM,CAAC,OAAO,IAAI,SAAS,MAAM;AAE/B,UAAM,MAAM,IAAI,QAAe,IAAI;AAEnC,QAAI,WAAW,SAAS,SAAS,OAAO;AACtC,gCAA0B,IAAI,OAAO,CAAC,CAAC;AACvC,aAAO,oCAAC,YAAY,UAAZ,EAAsB,GAAG,OAAO,OAAO,EAAE,SAAS,IAAI,GAAG;AAAA,IACnE;AACA,QAAI,QAAQ;AACZ,QAAI,WAAW;AACf,QAAI,WAAW,CAEb,aACG;AAEH,aAAO,SAAS,IAAI,OAAc,QAAe;AAAA,IACnD;AACA,QAAI,YAAY,CAEd,UACG;AACH,aAAO;AAAA,QACL,MAAM;AAAA;AAAA,QAEN,SAAS,IAAI,OAAc,MAAM,QAAe;AAAA,MAClD;AAAA,IACF;AAEA,WAAO;AAAA,EACT,CAAC;AAED,UAAQ,SAAS,CAAC,UAAU,MAAM,YAAY;AAM9C,4BAA0B,MAAM;AAC9B,YAAQ,OAAO,IAAI;AAAA,EACrB,CAAC;AAED,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../src/useForm.tsx"],"sourcesContent":["import type { FormState, FormOptions, Validator } from '@tanstack/form-core'\nimport { FormApi, functionalUpdate } from '@tanstack/form-core'\nimport type { NoInfer } from '@tanstack/react-store'\nimport { useStore } from '@tanstack/react-store'\nimport React, { type PropsWithChildren, type ReactNode, useState } from 'react'\nimport { type UseField, type FieldComponent, Field, useField } from './useField'\nimport { formContext } from './formContext'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FormApi<TFormData, TFormValidator> {\n Provider: (props: PropsWithChildren) => JSX.Element\n Field: FieldComponent<TFormData, TFormValidator>\n useField: UseField<TFormData>\n useStore: <TSelected = NoInfer<FormState<TFormData>>>(\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,\n ) => TSelected\n Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected\n children: ((state: NoInfer<TSelected>) => ReactNode) | ReactNode\n }) => JSX.Element\n }\n}\n\nexport function useForm<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(\n opts?: FormOptions<TFormData, TFormValidator>,\n): FormApi<TFormData, TFormValidator> {\n const [formApi] = useState(() => {\n // @ts-ignore\n const api = new FormApi<TFormData, TFormValidator>(opts)\n\n api.Provider = function Provider(props) {\n useIsomorphicLayoutEffect(api.mount, [])\n return (\n <formContext.Provider {...props} value={{ formApi: api as never }} />\n )\n }\n api.Field = Field as any\n api.useField = useField as any\n api.useStore = (\n // @ts-ignore\n selector,\n ) => {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useStore(api.store as any, selector as any) as any\n }\n api.Subscribe = (\n // @ts-ignore\n props,\n ) => {\n return functionalUpdate(\n props.children,\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useStore(api.store as any, props.selector as any),\n ) as any\n }\n\n return api\n })\n\n formApi.useStore((state) => state.isSubmitting)\n\n /**\n * formApi.update should not have any side effects. Think of it like a `useRef`\n * that we need to keep updated every render with the most up-to-date information.\n */\n useIsomorphicLayoutEffect(() => {\n formApi.update(opts)\n })\n\n return formApi as any\n}\n"],"mappings":";AACA,SAAS,SAAS,wBAAwB;AAE1C,SAAS,gBAAgB;AACzB,OAAO,SAAiD,gBAAgB;AACxE,SAA6C,OAAO,gBAAgB;AACpE,SAAS,mBAAmB;AAC5B,SAAS,iCAAiC;AAkBnC,SAAS,QAId,MACoC;AACpC,QAAM,CAAC,OAAO,IAAI,SAAS,MAAM;AAE/B,UAAM,MAAM,IAAI,QAAmC,IAAI;AAEvD,QAAI,WAAW,SAAS,SAAS,OAAO;AACtC,gCAA0B,IAAI,OAAO,CAAC,CAAC;AACvC,aACE,oCAAC,YAAY,UAAZ,EAAsB,GAAG,OAAO,OAAO,EAAE,SAAS,IAAa,GAAG;AAAA,IAEvE;AACA,QAAI,QAAQ;AACZ,QAAI,WAAW;AACf,QAAI,WAAW,CAEb,aACG;AAEH,aAAO,SAAS,IAAI,OAAc,QAAe;AAAA,IACnD;AACA,QAAI,YAAY,CAEd,UACG;AACH,aAAO;AAAA,QACL,MAAM;AAAA;AAAA,QAEN,SAAS,IAAI,OAAc,MAAM,QAAe;AAAA,MAClD;AAAA,IACF;AAEA,WAAO;AAAA,EACT,CAAC;AAED,UAAQ,SAAS,CAAC,UAAU,MAAM,YAAY;AAM9C,4BAA0B,MAAM;AAC9B,YAAQ,OAAO,IAAI;AAAA,EACrB,CAAC;AAED,SAAO;AACT;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/react-form",
3
- "version": "0.10.2",
3
+ "version": "0.11.0",
4
4
  "description": "Powerful, type-safe forms for React.",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
@@ -53,7 +53,7 @@
53
53
  "dependencies": {
54
54
  "@tanstack/react-store": "0.1.3",
55
55
  "@tanstack/store": "0.1.3",
56
- "@tanstack/form-core": "0.10.2"
56
+ "@tanstack/form-core": "0.11.0"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "react": "^17.0.0 || ^18.0.0",
@@ -1,23 +1,29 @@
1
- import type { FormApi, FormOptions } from '@tanstack/form-core'
1
+ import type { FormApi, FormOptions, Validator } from '@tanstack/form-core'
2
2
 
3
3
  import { type UseField, type FieldComponent, Field, useField } from './useField'
4
4
  import { useForm } from './useForm'
5
5
 
6
- export type FormFactory<TFormData, FormValidator> = {
6
+ export type FormFactory<
7
+ TFormData,
8
+ TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
9
+ > = {
7
10
  useForm: (
8
- opts?: FormOptions<TFormData, FormValidator>,
9
- ) => FormApi<TFormData, FormValidator>
11
+ opts?: FormOptions<TFormData, TFormValidator>,
12
+ ) => FormApi<TFormData, TFormValidator>
10
13
  useField: UseField<TFormData>
11
- Field: FieldComponent<TFormData, FormValidator>
14
+ Field: FieldComponent<TFormData, TFormValidator>
12
15
  }
13
16
 
14
- export function createFormFactory<TFormData, FormValidator>(
15
- defaultOpts?: FormOptions<TFormData, FormValidator>,
16
- ): FormFactory<TFormData, FormValidator> {
17
+ export function createFormFactory<
18
+ TFormData,
19
+ TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
20
+ >(
21
+ defaultOpts?: FormOptions<TFormData, TFormValidator>,
22
+ ): FormFactory<TFormData, TFormValidator> {
17
23
  return {
18
24
  useForm: (opts) => {
19
25
  const formOptions = Object.assign({}, defaultOpts, opts)
20
- return useForm<TFormData, FormValidator>(formOptions)
26
+ return useForm<TFormData, TFormValidator>(formOptions)
21
27
  },
22
28
  useField: useField as any,
23
29
  Field: Field as any,
@@ -1,8 +1,8 @@
1
- import type { FormApi } from '@tanstack/form-core'
1
+ import type { FormApi, Validator } from '@tanstack/form-core'
2
2
  import * as React from 'react'
3
3
 
4
4
  export const formContext = React.createContext<{
5
- formApi: FormApi<any, unknown>
5
+ formApi: FormApi<any, Validator<any, unknown> | undefined>
6
6
  parentFieldName?: string
7
7
  } | null>(null!)
8
8
 
@@ -11,7 +11,7 @@ describe('createFormFactory', () => {
11
11
  lastName: string
12
12
  }
13
13
 
14
- const formFactory = createFormFactory<Person, unknown>({
14
+ const formFactory = createFormFactory<Person>({
15
15
  defaultValues: {
16
16
  firstName: 'FirstName',
17
17
  lastName: 'LastName',
@@ -43,17 +43,21 @@ it('should type onChange properly', () => {
43
43
  <form.Provider>
44
44
  <form.Field
45
45
  name="firstName"
46
- onChange={(val) => {
47
- assertType<'test'>(val)
48
- return null
46
+ validators={{
47
+ onChange: ({ value }) => {
48
+ assertType<'test'>(value)
49
+ return null
50
+ },
49
51
  }}
50
52
  children={(field) => null}
51
53
  />
52
54
  <form.Field
53
55
  name="age"
54
- onChange={(val) => {
55
- assertType<84>(val)
56
- return null
56
+ validators={{
57
+ onChange: ({ value }) => {
58
+ assertType<84>(value)
59
+ return null
60
+ },
57
61
  }}
58
62
  children={(field) => null}
59
63
  />
@@ -15,7 +15,7 @@ describe('useField', () => {
15
15
  lastName: string
16
16
  }
17
17
 
18
- const formFactory = createFormFactory<Person, unknown>()
18
+ const formFactory = createFormFactory<Person>()
19
19
 
20
20
  function Comp() {
21
21
  const form = formFactory.useForm({
@@ -55,7 +55,7 @@ describe('useField', () => {
55
55
  lastName: string
56
56
  }
57
57
 
58
- const formFactory = createFormFactory<Person, unknown>()
58
+ const formFactory = createFormFactory<Person>()
59
59
 
60
60
  function Comp() {
61
61
  const form = formFactory.useForm({
@@ -97,7 +97,7 @@ describe('useField', () => {
97
97
  }
98
98
  const error = 'Please enter a different value'
99
99
 
100
- const formFactory = createFormFactory<Person, unknown>()
100
+ const formFactory = createFormFactory<Person>()
101
101
 
102
102
  function Comp() {
103
103
  const form = formFactory.useForm()
@@ -106,7 +106,9 @@ describe('useField', () => {
106
106
  <form.Provider>
107
107
  <form.Field
108
108
  name="firstName"
109
- onChange={(value) => (value === 'other' ? error : undefined)}
109
+ validators={{
110
+ onChange: ({ value }) => (value === 'other' ? error : undefined),
111
+ }}
110
112
  children={(field) => (
111
113
  <div>
112
114
  <input
@@ -137,7 +139,7 @@ describe('useField', () => {
137
139
  }
138
140
  const error = 'Please enter a different value'
139
141
 
140
- const formFactory = createFormFactory<Person, unknown>()
142
+ const formFactory = createFormFactory<Person>()
141
143
 
142
144
  function Comp() {
143
145
  const form = formFactory.useForm()
@@ -147,7 +149,9 @@ describe('useField', () => {
147
149
  <form.Field
148
150
  name="firstName"
149
151
  defaultMeta={{ isTouched: true }}
150
- onChange={(value) => (value === 'other' ? error : undefined)}
152
+ validators={{
153
+ onChange: ({ value }) => (value === 'other' ? error : undefined),
154
+ }}
151
155
  children={(field) => (
152
156
  <div>
153
157
  <input
@@ -180,7 +184,7 @@ describe('useField', () => {
180
184
  const onChangeError = 'Please enter a different value (onChangeError)'
181
185
  const onBlurError = 'Please enter a different value (onBlurError)'
182
186
 
183
- const formFactory = createFormFactory<Person, unknown>()
187
+ const formFactory = createFormFactory<Person>()
184
188
 
185
189
  function Comp() {
186
190
  const form = formFactory.useForm()
@@ -190,10 +194,12 @@ describe('useField', () => {
190
194
  <form.Field
191
195
  name="firstName"
192
196
  defaultMeta={{ isTouched: true }}
193
- onChange={(value) =>
194
- value === 'other' ? onChangeError : undefined
195
- }
196
- onBlur={(value) => (value === 'other' ? onBlurError : undefined)}
197
+ validators={{
198
+ onChange: ({ value }) =>
199
+ value === 'other' ? onChangeError : undefined,
200
+ onBlur: ({ value }) =>
201
+ value === 'other' ? onBlurError : undefined,
202
+ }}
197
203
  children={(field) => (
198
204
  <div>
199
205
  <input
@@ -229,7 +235,7 @@ describe('useField', () => {
229
235
  }
230
236
  const error = 'Please enter a different value'
231
237
 
232
- const formFactory = createFormFactory<Person, unknown>()
238
+ const formFactory = createFormFactory<Person>()
233
239
 
234
240
  function Comp() {
235
241
  const form = formFactory.useForm()
@@ -239,9 +245,11 @@ describe('useField', () => {
239
245
  <form.Field
240
246
  name="firstName"
241
247
  defaultMeta={{ isTouched: true }}
242
- onChangeAsync={async () => {
243
- await sleep(10)
244
- return error
248
+ validators={{
249
+ onChangeAsync: async () => {
250
+ await sleep(10)
251
+ return error
252
+ },
245
253
  }}
246
254
  children={(field) => (
247
255
  <div>
@@ -276,7 +284,7 @@ describe('useField', () => {
276
284
  const onChangeError = 'Please enter a different value (onChangeError)'
277
285
  const onBlurError = 'Please enter a different value (onBlurError)'
278
286
 
279
- const formFactory = createFormFactory<Person, unknown>()
287
+ const formFactory = createFormFactory<Person>()
280
288
 
281
289
  function Comp() {
282
290
  const form = formFactory.useForm()
@@ -286,13 +294,15 @@ describe('useField', () => {
286
294
  <form.Field
287
295
  name="firstName"
288
296
  defaultMeta={{ isTouched: true }}
289
- onChangeAsync={async () => {
290
- await sleep(10)
291
- return onChangeError
292
- }}
293
- onBlurAsync={async () => {
294
- await sleep(10)
295
- return onBlurError
297
+ validators={{
298
+ onChangeAsync: async () => {
299
+ await sleep(10)
300
+ return onChangeError
301
+ },
302
+ onBlurAsync: async () => {
303
+ await sleep(10)
304
+ return onBlurError
305
+ },
296
306
  }}
297
307
  children={(field) => (
298
308
  <div>
@@ -332,7 +342,7 @@ describe('useField', () => {
332
342
  }
333
343
  const mockFn = vi.fn()
334
344
  const error = 'Please enter a different value'
335
- const formFactory = createFormFactory<Person, unknown>()
345
+ const formFactory = createFormFactory<Person>()
336
346
 
337
347
  function Comp() {
338
348
  const form = formFactory.useForm()
@@ -342,11 +352,13 @@ describe('useField', () => {
342
352
  <form.Field
343
353
  name="firstName"
344
354
  defaultMeta={{ isTouched: true }}
345
- onChangeAsyncDebounceMs={100}
346
- onChangeAsync={async () => {
347
- mockFn()
348
- await sleep(10)
349
- return error
355
+ validators={{
356
+ onChangeAsyncDebounceMs: 100,
357
+ onChangeAsync: async () => {
358
+ mockFn()
359
+ await sleep(10)
360
+ return error
361
+ },
350
362
  }}
351
363
  children={(field) => (
352
364
  <div>
@@ -379,8 +391,8 @@ describe('useField', () => {
379
391
  firstName: string
380
392
  lastName: string
381
393
  }
382
- const formFactory = createFormFactory<Person, unknown>()
383
- let form: FormApi<Person, unknown> | null = null
394
+ const formFactory = createFormFactory<Person>()
395
+ let form: FormApi<Person> | null = null
384
396
  function Comp() {
385
397
  form = formFactory.useForm()
386
398
  return (
@@ -417,8 +429,8 @@ describe('useField', () => {
417
429
  firstName: string
418
430
  lastName: string
419
431
  }
420
- const formFactory = createFormFactory<Person, unknown>()
421
- let form: FormApi<Person, unknown> | null = null
432
+ const formFactory = createFormFactory<Person>()
433
+ let form: FormApi<Person> | null = null
422
434
  function Comp() {
423
435
  form = formFactory.useForm()
424
436
  return (
@@ -0,0 +1,36 @@
1
+ import { assertType } from 'vitest'
2
+ import * as React from 'react'
3
+ import { useForm } from '../useForm'
4
+
5
+ it('should type onSubmit properly', () => {
6
+ function Comp() {
7
+ const form = useForm({
8
+ defaultValues: {
9
+ firstName: 'test',
10
+ age: 84,
11
+ // as const is required here
12
+ } as const,
13
+ onSubmit({ value }) {
14
+ assertType<84>(value.age)
15
+ },
16
+ })
17
+ }
18
+ })
19
+
20
+ it('should type a validator properly', () => {
21
+ function Comp() {
22
+ const form = useForm({
23
+ defaultValues: {
24
+ firstName: 'test',
25
+ age: 84,
26
+ // as const is required here
27
+ } as const,
28
+ validators: {
29
+ onChange({ value }) {
30
+ assertType<84>(value.age)
31
+ return undefined
32
+ },
33
+ },
34
+ })
35
+ }
36
+ })