@tanstack/react-form 0.16.0 → 0.16.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"useField.cjs","sources":["../../src/useField.tsx"],"sourcesContent":["import React, { useState } from 'rehackt'\nimport { useStore } from '@tanstack/react-store'\nimport { FieldApi, functionalUpdate } from '@tanstack/form-core'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\nimport type { UseFieldOptions } from './types'\nimport type {\n DeepKeys,\n DeepValue,\n Narrow,\n Validator,\n} from '@tanstack/form-core'\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<\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>(\n opts: Omit<\n UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,\n 'form'\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 const [fieldApi] = useState(() => {\n const api = new FieldApi({\n ...opts,\n form: opts.form,\n name: opts.name,\n })\n\n api.Field = Field as never\n\n return api\n })\n\n useIsomorphicLayoutEffect(fieldApi.mount, [fieldApi])\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)\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\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} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>\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}: Omit<\n FieldComponentProps<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n 'form'\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 <>{functionalUpdate(children, fieldApi as any)}</>\n}\n"],"names":["useState","FieldApi","useIsomorphicLayoutEffect","useStore","jsx","Fragment","functionalUpdate"],"mappings":";;;;;;;AAoDO,SAAS,SAUd,MAC+D;AAC/D,QAAM,CAAC,QAAQ,IAAIA,QAAAA,SAAS,MAAM;AAC1B,UAAA,MAAM,IAAIC,kBAAS;AAAA,MACvB,GAAG;AAAA,MACH,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,IAAA,CACZ;AAED,QAAI,QAAQ;AAEL,WAAA;AAAA,EAAA,CACR;AAEDC,4BAAAA,0BAA0B,SAAS,OAAO,CAAC,QAAQ,CAAC;AAMpDA,4BAAAA,0BAA0B,MAAM;AAC9B,aAAS,OAAO,IAAI;AAAA,EAAA,CACrB;AAEDC,aAAA;AAAA,IACE,SAAS;AAAA,IACT,KAAK,SAAS,UACV,CAAC,UAAU;AACF,aAAA,CAAC,MAAM,MAAM,OAAO,KAAK,MAAM,KAAK,EAAE,MAAM;AAAA,IAErD,IAAA;AAAA,EAAA;AAGC,SAAA;AACT;AAiDO,SAAS,MASd;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAI0E;AAClE,QAAA,WAAW,SAAS,YAAmB;AAE7C,SAAUC,2BAAA,IAAAC,WAAA,UAAA,EAAA,UAAAC,SAAA,iBAAiB,UAAU,QAAe,EAAE,CAAA;AACxD;;;"}
1
+ {"version":3,"file":"useField.cjs","sources":["../../src/useField.tsx"],"sourcesContent":["import React, { useState } from 'rehackt'\nimport { useStore } from '@tanstack/react-store'\nimport { FieldApi, functionalUpdate } from '@tanstack/form-core'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\nimport type { UseFieldOptions } from './types'\nimport type {\n DeepKeys,\n DeepValue,\n Narrow,\n Validator,\n} from '@tanstack/form-core'\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<\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 opts: Omit<\n UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>,\n 'form'\n >,\n) => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>\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 TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n>(\n opts: UseFieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n): FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData> {\n const [fieldApi] = useState(() => {\n const api = new FieldApi({\n ...opts,\n form: opts.form,\n name: opts.name,\n })\n\n api.Field = Field as never\n\n return api\n })\n\n useIsomorphicLayoutEffect(fieldApi.mount, [fieldApi])\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)\n })\n\n useStore(\n fieldApi.store,\n opts.mode === 'array'\n ? (state) => {\n return [state.meta, Object.keys(state.value as never).length]\n }\n : undefined,\n )\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} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>\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}: Omit<\n FieldComponentProps<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n 'form'\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 TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n>({\n children,\n ...fieldOptions\n}: {\n children: (\n fieldApi: FieldApi<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) => any\n} & UseFieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n>) {\n const fieldApi = useField(fieldOptions as any)\n\n return <>{functionalUpdate(children, fieldApi as any)}</>\n}\n"],"names":["useState","FieldApi","useIsomorphicLayoutEffect","useStore","jsx","Fragment","functionalUpdate"],"mappings":";;;;;;;AA+CO,SAAS,SAWd,MAOsE;AACtE,QAAM,CAAC,QAAQ,IAAIA,QAAAA,SAAS,MAAM;AAC1B,UAAA,MAAM,IAAIC,kBAAS;AAAA,MACvB,GAAG;AAAA,MACH,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,IAAA,CACZ;AAED,QAAI,QAAQ;AAEL,WAAA;AAAA,EAAA,CACR;AAEDC,4BAAAA,0BAA0B,SAAS,OAAO,CAAC,QAAQ,CAAC;AAMpDA,4BAAAA,0BAA0B,MAAM;AAC9B,aAAS,OAAO,IAAI;AAAA,EAAA,CACrB;AAEDC,aAAA;AAAA,IACE,SAAS;AAAA,IACT,KAAK,SAAS,UACV,CAAC,UAAU;AACF,aAAA,CAAC,MAAM,MAAM,OAAO,KAAK,MAAM,KAAc,EAAE,MAAM;AAAA,IAE9D,IAAA;AAAA,EAAA;AAGC,SAAA;AACT;AAiDO,SAAS,MAUd;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAgBG;AACK,QAAA,WAAW,SAAS,YAAmB;AAE7C,SAAUC,2BAAA,IAAAC,WAAA,UAAA,EAAA,UAAAC,SAAA,iBAAiB,UAAU,QAAe,EAAE,CAAA;AACxD;;;"}
@@ -8,13 +8,13 @@ declare module '@tanstack/form-core' {
8
8
  Field: FieldComponent<TParentData, TFormValidator>;
9
9
  }
10
10
  }
11
- export type UseField<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined>(opts: Omit<UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>, 'form'>) => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, DeepValue<TParentData, TName>>;
12
- export 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>;
11
+ export type UseField<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>>(opts: Omit<UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>, 'form'>) => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>;
12
+ export declare function useField<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>>(opts: UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>): FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>;
13
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
14
  children: (fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>) => any;
15
- } & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>;
15
+ } & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>;
16
16
  export 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 }: Omit<FieldComponentProps<TParentData, TName, TFieldValidator, TFormValidator, TData>, 'form'>) => any;
17
- export 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 }: {
18
- children: (fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator>) => any;
19
- } & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>): React.JSX.Element;
17
+ export declare function Field<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>>({ children, ...fieldOptions }: {
18
+ children: (fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>) => any;
19
+ } & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>): React.JSX.Element;
20
20
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"useForm.cjs","sources":["../../src/useForm.tsx"],"sourcesContent":["import { FormApi, functionalUpdate } from '@tanstack/form-core'\nimport { useStore } from '@tanstack/react-store'\nimport React, {\n type PropsWithChildren,\n type ReactNode,\n useState,\n} from 'rehackt'\nimport { Field, type FieldComponent, type UseField, useField } from './useField'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\nimport type { NoInfer } from '@tanstack/react-store'\nimport type { FormOptions, FormState, Validator } from '@tanstack/form-core'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FormApi<TFormData, TFormValidator> {\n Field: FieldComponent<TFormData, TFormValidator>\n useField: UseField<TFormData, TFormValidator>\n useStore: <TSelected = NoInfer<FormState<TFormData>>>(\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,\n ) => TSelected\n Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {\n /**\n TypeScript versions <=5.0.4 have a bug that prevents\n the type of the `TSelected` generic from being inferred\n from the return type of this method.\n\n In these versions, `TSelected` will fall back to the default\n type (or `unknown` if that's not defined).\n\n @see {@link https://github.com/TanStack/form/pull/606/files#r1506715714 | This discussion on GitHub for the details}\n @see {@link https://github.com/microsoft/TypeScript/issues/52786 | The bug report in `microsoft/TypeScript`}\n */\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 const api = new FormApi<TFormData, TFormValidator>(opts)\n api.Field = function APIField(props) {\n return <Field {...props} form={api} />\n }\n // eslint-disable-next-line react-hooks/rules-of-hooks\n api.useField = (props) => useField({ ...props, form: api })\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 useIsomorphicLayoutEffect(formApi.mount, [])\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"],"names":["useState","FormApi","jsx","Field","useField","useStore","functionalUpdate","useIsomorphicLayoutEffect"],"mappings":";;;;;;;;AAsCO,SAAS,QAId,MACoC;AACpC,QAAM,CAAC,OAAO,IAAIA,QAAAA,SAAS,MAAM;AACzB,UAAA,MAAM,IAAIC,iBAAmC,IAAI;AACnD,QAAA,QAAQ,SAAS,SAAS,OAAO;AACnC,aAAQC,2BAAAA,IAAAC,SAAAA,OAAA,EAAO,GAAG,OAAO,MAAM,IAAK,CAAA;AAAA,IAAA;AAGlC,QAAA,WAAW,CAAC,UAAUC,SAAA,SAAS,EAAE,GAAG,OAAO,MAAM,IAAA,CAAK;AACtD,QAAA,WAAW,CAEb,aACG;AAEI,aAAAC,oBAAS,IAAI,OAAc,QAAe;AAAA,IAAA;AAE/C,QAAA,YAAY,CAEd,UACG;AACI,aAAAC,SAAA;AAAA,QACL,MAAM;AAAA;AAAA,QAEND,WAAAA,SAAS,IAAI,OAAc,MAAM,QAAe;AAAA,MAAA;AAAA,IAClD;AAGK,WAAA;AAAA,EAAA,CACR;AAEyBE,4BAAAA,0BAAA,QAAQ,OAAO,CAAA,CAAE;AAE3C,UAAQ,SAAS,CAAC,UAAU,MAAM,YAAY;AAM9CA,4BAAAA,0BAA0B,MAAM;AAC9B,YAAQ,OAAO,IAAI;AAAA,EAAA,CACpB;AAEM,SAAA;AACT;;"}
1
+ {"version":3,"file":"useForm.cjs","sources":["../../src/useForm.tsx"],"sourcesContent":["import { FormApi, functionalUpdate } from '@tanstack/form-core'\nimport { useStore } from '@tanstack/react-store'\nimport React, { type ReactNode, useState } from 'rehackt'\nimport { Field, type FieldComponent, type UseField, useField } from './useField'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\nimport type { NoInfer } from '@tanstack/react-store'\nimport type { FormOptions, FormState, Validator } from '@tanstack/form-core'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FormApi<TFormData, TFormValidator> {\n Field: FieldComponent<TFormData, TFormValidator>\n useField: UseField<TFormData, TFormValidator>\n useStore: <TSelected = NoInfer<FormState<TFormData>>>(\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,\n ) => TSelected\n Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {\n /**\n TypeScript versions <=5.0.4 have a bug that prevents\n the type of the `TSelected` generic from being inferred\n from the return type of this method.\n\n In these versions, `TSelected` will fall back to the default\n type (or `unknown` if that's not defined).\n\n @see {@link https://github.com/TanStack/form/pull/606/files#r1506715714 | This discussion on GitHub for the details}\n @see {@link https://github.com/microsoft/TypeScript/issues/52786 | The bug report in `microsoft/TypeScript`}\n */\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 const api = new FormApi<TFormData, TFormValidator>(opts)\n api.Field = function APIField(props) {\n return <Field {...props} form={api} />\n }\n // eslint-disable-next-line react-hooks/rules-of-hooks\n api.useField = (props) => useField({ ...props, form: api })\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 useIsomorphicLayoutEffect(formApi.mount, [])\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"],"names":["useState","FormApi","jsx","Field","useField","useStore","functionalUpdate","useIsomorphicLayoutEffect"],"mappings":";;;;;;;;AAkCO,SAAS,QAId,MACoC;AACpC,QAAM,CAAC,OAAO,IAAIA,QAAAA,SAAS,MAAM;AACzB,UAAA,MAAM,IAAIC,iBAAmC,IAAI;AACnD,QAAA,QAAQ,SAAS,SAAS,OAAO;AACnC,aAAQC,2BAAAA,IAAAC,SAAAA,OAAA,EAAO,GAAG,OAAO,MAAM,IAAK,CAAA;AAAA,IAAA;AAGlC,QAAA,WAAW,CAAC,UAAUC,SAAA,SAAS,EAAE,GAAG,OAAO,MAAM,IAAA,CAAK;AACtD,QAAA,WAAW,CAEb,aACG;AAEI,aAAAC,oBAAS,IAAI,OAAc,QAAe;AAAA,IAAA;AAE/C,QAAA,YAAY,CAEd,UACG;AACI,aAAAC,SAAA;AAAA,QACL,MAAM;AAAA;AAAA,QAEND,WAAAA,SAAS,IAAI,OAAc,MAAM,QAAe;AAAA,MAAA;AAAA,IAClD;AAGK,WAAA;AAAA,EAAA,CACR;AAEyBE,4BAAAA,0BAAA,QAAQ,OAAO,CAAA,CAAE;AAE3C,UAAQ,SAAS,CAAC,UAAU,MAAM,YAAY;AAM9CA,4BAAAA,0BAA0B,MAAM;AAC9B,YAAQ,OAAO,IAAI;AAAA,EAAA,CACpB;AAEM,SAAA;AACT;;"}
@@ -10,5 +10,5 @@ declare module '@tanstack/form-core' {
10
10
  }
11
11
  }
12
12
  export type ValidateFormData<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = (formData: FormData, info?: Parameters<typeof decode>[1]) => Promise<Partial<FormApi<TFormData, TFormValidator>['state']>>;
13
- export declare const getValidateFormData: <TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(defaultOpts?: FormOptions<TFormData, TFormValidator> | undefined) => ValidateFormData<TFormData, TFormValidator>;
13
+ export declare const getValidateFormData: <TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(defaultOpts?: FormOptions<TFormData, TFormValidator>) => ValidateFormData<TFormData, TFormValidator>;
14
14
  export {};
@@ -8,13 +8,13 @@ declare module '@tanstack/form-core' {
8
8
  Field: FieldComponent<TParentData, TFormValidator>;
9
9
  }
10
10
  }
11
- export type UseField<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined>(opts: Omit<UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>, 'form'>) => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, DeepValue<TParentData, TName>>;
12
- export 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>;
11
+ export type UseField<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>>(opts: Omit<UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>, 'form'>) => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>;
12
+ export declare function useField<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>>(opts: UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>): FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>;
13
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
14
  children: (fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>) => any;
15
- } & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>;
15
+ } & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>;
16
16
  export 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 }: Omit<FieldComponentProps<TParentData, TName, TFieldValidator, TFormValidator, TData>, 'form'>) => any;
17
- export 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 }: {
18
- children: (fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator>) => any;
19
- } & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>): React.JSX.Element;
17
+ export declare function Field<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>>({ children, ...fieldOptions }: {
18
+ children: (fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>) => any;
19
+ } & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>): React.JSX.Element;
20
20
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"useField.js","sources":["../../src/useField.tsx"],"sourcesContent":["import React, { useState } from 'rehackt'\nimport { useStore } from '@tanstack/react-store'\nimport { FieldApi, functionalUpdate } from '@tanstack/form-core'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\nimport type { UseFieldOptions } from './types'\nimport type {\n DeepKeys,\n DeepValue,\n Narrow,\n Validator,\n} from '@tanstack/form-core'\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<\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>(\n opts: Omit<\n UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,\n 'form'\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 const [fieldApi] = useState(() => {\n const api = new FieldApi({\n ...opts,\n form: opts.form,\n name: opts.name,\n })\n\n api.Field = Field as never\n\n return api\n })\n\n useIsomorphicLayoutEffect(fieldApi.mount, [fieldApi])\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)\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\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} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>\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}: Omit<\n FieldComponentProps<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n 'form'\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 <>{functionalUpdate(children, fieldApi as any)}</>\n}\n"],"names":[],"mappings":";;;;;AAoDO,SAAS,SAUd,MAC+D;AAC/D,QAAM,CAAC,QAAQ,IAAI,SAAS,MAAM;AAC1B,UAAA,MAAM,IAAI,SAAS;AAAA,MACvB,GAAG;AAAA,MACH,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,IAAA,CACZ;AAED,QAAI,QAAQ;AAEL,WAAA;AAAA,EAAA,CACR;AAED,4BAA0B,SAAS,OAAO,CAAC,QAAQ,CAAC;AAMpD,4BAA0B,MAAM;AAC9B,aAAS,OAAO,IAAI;AAAA,EAAA,CACrB;AAED;AAAA,IACE,SAAS;AAAA,IACT,KAAK,SAAS,UACV,CAAC,UAAU;AACF,aAAA,CAAC,MAAM,MAAM,OAAO,KAAK,MAAM,KAAK,EAAE,MAAM;AAAA,IAErD,IAAA;AAAA,EAAA;AAGC,SAAA;AACT;AAiDO,SAAS,MASd;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAI0E;AAClE,QAAA,WAAW,SAAS,YAAmB;AAE7C,SAAU,oBAAA,UAAA,EAAA,UAAA,iBAAiB,UAAU,QAAe,EAAE,CAAA;AACxD;"}
1
+ {"version":3,"file":"useField.js","sources":["../../src/useField.tsx"],"sourcesContent":["import React, { useState } from 'rehackt'\nimport { useStore } from '@tanstack/react-store'\nimport { FieldApi, functionalUpdate } from '@tanstack/form-core'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\nimport type { UseFieldOptions } from './types'\nimport type {\n DeepKeys,\n DeepValue,\n Narrow,\n Validator,\n} from '@tanstack/form-core'\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<\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 opts: Omit<\n UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>,\n 'form'\n >,\n) => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>\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 TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n>(\n opts: UseFieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n): FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData> {\n const [fieldApi] = useState(() => {\n const api = new FieldApi({\n ...opts,\n form: opts.form,\n name: opts.name,\n })\n\n api.Field = Field as never\n\n return api\n })\n\n useIsomorphicLayoutEffect(fieldApi.mount, [fieldApi])\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)\n })\n\n useStore(\n fieldApi.store,\n opts.mode === 'array'\n ? (state) => {\n return [state.meta, Object.keys(state.value as never).length]\n }\n : undefined,\n )\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} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>\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}: Omit<\n FieldComponentProps<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n 'form'\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 TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n>({\n children,\n ...fieldOptions\n}: {\n children: (\n fieldApi: FieldApi<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) => any\n} & UseFieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n>) {\n const fieldApi = useField(fieldOptions as any)\n\n return <>{functionalUpdate(children, fieldApi as any)}</>\n}\n"],"names":[],"mappings":";;;;;AA+CO,SAAS,SAWd,MAOsE;AACtE,QAAM,CAAC,QAAQ,IAAI,SAAS,MAAM;AAC1B,UAAA,MAAM,IAAI,SAAS;AAAA,MACvB,GAAG;AAAA,MACH,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,IAAA,CACZ;AAED,QAAI,QAAQ;AAEL,WAAA;AAAA,EAAA,CACR;AAED,4BAA0B,SAAS,OAAO,CAAC,QAAQ,CAAC;AAMpD,4BAA0B,MAAM;AAC9B,aAAS,OAAO,IAAI;AAAA,EAAA,CACrB;AAED;AAAA,IACE,SAAS;AAAA,IACT,KAAK,SAAS,UACV,CAAC,UAAU;AACF,aAAA,CAAC,MAAM,MAAM,OAAO,KAAK,MAAM,KAAc,EAAE,MAAM;AAAA,IAE9D,IAAA;AAAA,EAAA;AAGC,SAAA;AACT;AAiDO,SAAS,MAUd;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAgBG;AACK,QAAA,WAAW,SAAS,YAAmB;AAE7C,SAAU,oBAAA,UAAA,EAAA,UAAA,iBAAiB,UAAU,QAAe,EAAE,CAAA;AACxD;"}
@@ -1 +1 @@
1
- {"version":3,"file":"useForm.js","sources":["../../src/useForm.tsx"],"sourcesContent":["import { FormApi, functionalUpdate } from '@tanstack/form-core'\nimport { useStore } from '@tanstack/react-store'\nimport React, {\n type PropsWithChildren,\n type ReactNode,\n useState,\n} from 'rehackt'\nimport { Field, type FieldComponent, type UseField, useField } from './useField'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\nimport type { NoInfer } from '@tanstack/react-store'\nimport type { FormOptions, FormState, Validator } from '@tanstack/form-core'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FormApi<TFormData, TFormValidator> {\n Field: FieldComponent<TFormData, TFormValidator>\n useField: UseField<TFormData, TFormValidator>\n useStore: <TSelected = NoInfer<FormState<TFormData>>>(\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,\n ) => TSelected\n Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {\n /**\n TypeScript versions <=5.0.4 have a bug that prevents\n the type of the `TSelected` generic from being inferred\n from the return type of this method.\n\n In these versions, `TSelected` will fall back to the default\n type (or `unknown` if that's not defined).\n\n @see {@link https://github.com/TanStack/form/pull/606/files#r1506715714 | This discussion on GitHub for the details}\n @see {@link https://github.com/microsoft/TypeScript/issues/52786 | The bug report in `microsoft/TypeScript`}\n */\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 const api = new FormApi<TFormData, TFormValidator>(opts)\n api.Field = function APIField(props) {\n return <Field {...props} form={api} />\n }\n // eslint-disable-next-line react-hooks/rules-of-hooks\n api.useField = (props) => useField({ ...props, form: api })\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 useIsomorphicLayoutEffect(formApi.mount, [])\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"],"names":[],"mappings":";;;;;;AAsCO,SAAS,QAId,MACoC;AACpC,QAAM,CAAC,OAAO,IAAI,SAAS,MAAM;AACzB,UAAA,MAAM,IAAI,QAAmC,IAAI;AACnD,QAAA,QAAQ,SAAS,SAAS,OAAO;AACnC,aAAQ,oBAAA,OAAA,EAAO,GAAG,OAAO,MAAM,IAAK,CAAA;AAAA,IAAA;AAGlC,QAAA,WAAW,CAAC,UAAU,SAAS,EAAE,GAAG,OAAO,MAAM,IAAA,CAAK;AACtD,QAAA,WAAW,CAEb,aACG;AAEI,aAAA,SAAS,IAAI,OAAc,QAAe;AAAA,IAAA;AAE/C,QAAA,YAAY,CAEd,UACG;AACI,aAAA;AAAA,QACL,MAAM;AAAA;AAAA,QAEN,SAAS,IAAI,OAAc,MAAM,QAAe;AAAA,MAAA;AAAA,IAClD;AAGK,WAAA;AAAA,EAAA,CACR;AAEyB,4BAAA,QAAQ,OAAO,CAAA,CAAE;AAE3C,UAAQ,SAAS,CAAC,UAAU,MAAM,YAAY;AAM9C,4BAA0B,MAAM;AAC9B,YAAQ,OAAO,IAAI;AAAA,EAAA,CACpB;AAEM,SAAA;AACT;"}
1
+ {"version":3,"file":"useForm.js","sources":["../../src/useForm.tsx"],"sourcesContent":["import { FormApi, functionalUpdate } from '@tanstack/form-core'\nimport { useStore } from '@tanstack/react-store'\nimport React, { type ReactNode, useState } from 'rehackt'\nimport { Field, type FieldComponent, type UseField, useField } from './useField'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\nimport type { NoInfer } from '@tanstack/react-store'\nimport type { FormOptions, FormState, Validator } from '@tanstack/form-core'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FormApi<TFormData, TFormValidator> {\n Field: FieldComponent<TFormData, TFormValidator>\n useField: UseField<TFormData, TFormValidator>\n useStore: <TSelected = NoInfer<FormState<TFormData>>>(\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,\n ) => TSelected\n Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {\n /**\n TypeScript versions <=5.0.4 have a bug that prevents\n the type of the `TSelected` generic from being inferred\n from the return type of this method.\n\n In these versions, `TSelected` will fall back to the default\n type (or `unknown` if that's not defined).\n\n @see {@link https://github.com/TanStack/form/pull/606/files#r1506715714 | This discussion on GitHub for the details}\n @see {@link https://github.com/microsoft/TypeScript/issues/52786 | The bug report in `microsoft/TypeScript`}\n */\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 const api = new FormApi<TFormData, TFormValidator>(opts)\n api.Field = function APIField(props) {\n return <Field {...props} form={api} />\n }\n // eslint-disable-next-line react-hooks/rules-of-hooks\n api.useField = (props) => useField({ ...props, form: api })\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 useIsomorphicLayoutEffect(formApi.mount, [])\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"],"names":[],"mappings":";;;;;;AAkCO,SAAS,QAId,MACoC;AACpC,QAAM,CAAC,OAAO,IAAI,SAAS,MAAM;AACzB,UAAA,MAAM,IAAI,QAAmC,IAAI;AACnD,QAAA,QAAQ,SAAS,SAAS,OAAO;AACnC,aAAQ,oBAAA,OAAA,EAAO,GAAG,OAAO,MAAM,IAAK,CAAA;AAAA,IAAA;AAGlC,QAAA,WAAW,CAAC,UAAU,SAAS,EAAE,GAAG,OAAO,MAAM,IAAA,CAAK;AACtD,QAAA,WAAW,CAEb,aACG;AAEI,aAAA,SAAS,IAAI,OAAc,QAAe;AAAA,IAAA;AAE/C,QAAA,YAAY,CAEd,UACG;AACI,aAAA;AAAA,QACL,MAAM;AAAA;AAAA,QAEN,SAAS,IAAI,OAAc,MAAM,QAAe;AAAA,MAAA;AAAA,IAClD;AAGK,WAAA;AAAA,EAAA,CACR;AAEyB,4BAAA,QAAQ,OAAO,CAAA,CAAE;AAE3C,UAAQ,SAAS,CAAC,UAAU,MAAM,YAAY;AAM9C,4BAA0B,MAAM;AAC9B,YAAQ,OAAO,IAAI;AAAA,EAAA,CACpB;AAEM,SAAA;AACT;"}
@@ -10,5 +10,5 @@ declare module '@tanstack/form-core' {
10
10
  }
11
11
  }
12
12
  export type ValidateFormData<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = (formData: FormData, info?: Parameters<typeof decode>[1]) => Promise<Partial<FormApi<TFormData, TFormValidator>['state']>>;
13
- export declare const getValidateFormData: <TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(defaultOpts?: FormOptions<TFormData, TFormValidator> | undefined) => ValidateFormData<TFormData, TFormValidator>;
13
+ export declare const getValidateFormData: <TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(defaultOpts?: FormOptions<TFormData, TFormValidator>) => ValidateFormData<TFormData, TFormValidator>;
14
14
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/react-form",
3
- "version": "0.16.0",
3
+ "version": "0.16.2",
4
4
  "description": "Powerful, type-safe forms for React.",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
@@ -43,7 +43,7 @@
43
43
  "@tanstack/react-store": "^0.3.1",
44
44
  "decode-formdata": "^0.4.0",
45
45
  "rehackt": "^0.0.3",
46
- "@tanstack/form-core": "0.16.0"
46
+ "@tanstack/form-core": "0.16.2"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "react": "^17.0.0 || ^18.0.0"
@@ -65,3 +65,44 @@ it('should type onChange properly', () => {
65
65
  )
66
66
  }
67
67
  })
68
+
69
+ it('should type array subfields', () => {
70
+ type FormDefinition = {
71
+ nested: {
72
+ people: {
73
+ name: string
74
+ age: number
75
+ }[]
76
+ }
77
+ }
78
+
79
+ function App() {
80
+ const form = useForm({
81
+ defaultValues: {
82
+ nested: {
83
+ people: [],
84
+ },
85
+ } as FormDefinition,
86
+ onSubmit({ value }) {
87
+ alert(JSON.stringify(value))
88
+ },
89
+ })
90
+
91
+ return (
92
+ <form.Field name="nested.people" mode="array">
93
+ {(field) =>
94
+ field.state.value.map((_, i) => (
95
+ <form.Field key={i} name={`nested.people[${i}].name`}>
96
+ {(subField) => (
97
+ <input
98
+ value={subField.state.value}
99
+ onChange={(e) => subField.handleChange(e.target.value)}
100
+ />
101
+ )}
102
+ </form.Field>
103
+ ))
104
+ }
105
+ </form.Field>
106
+ )
107
+ }
108
+ })
@@ -608,6 +608,102 @@ describe('useField', () => {
608
608
  expect(queryByText('A first name is required')).not.toBeInTheDocument()
609
609
  })
610
610
 
611
+ it('should handle arrays with primitive values', async () => {
612
+ const fn = vi.fn()
613
+ function Comp() {
614
+ const form = useForm({
615
+ defaultValues: {
616
+ people: [] as Array<string>,
617
+ },
618
+ onSubmit: ({ value }) => fn(value),
619
+ })
620
+
621
+ return (
622
+ <div>
623
+ <form
624
+ onSubmit={(e) => {
625
+ e.preventDefault()
626
+ e.stopPropagation()
627
+ void form.handleSubmit()
628
+ }}
629
+ >
630
+ <form.Field name="people">
631
+ {(field) => {
632
+ return (
633
+ <div>
634
+ {field.state.value.map((_, i) => {
635
+ return (
636
+ <form.Field key={i} name={`people[${i}]`}>
637
+ {(subField) => {
638
+ return (
639
+ <div>
640
+ <label>
641
+ <div>Name for person {i}</div>
642
+ <input
643
+ value={subField.state.value}
644
+ onChange={(e) =>
645
+ subField.handleChange(e.target.value)
646
+ }
647
+ />
648
+ </label>
649
+ <button
650
+ onClick={() => field.removeValue(i)}
651
+ type="button"
652
+ >
653
+ Remove person {i}
654
+ </button>
655
+ </div>
656
+ )
657
+ }}
658
+ </form.Field>
659
+ )
660
+ })}
661
+ <button onClick={() => field.pushValue('')} type="button">
662
+ Add person
663
+ </button>
664
+ </div>
665
+ )
666
+ }}
667
+ </form.Field>
668
+ <form.Subscribe
669
+ selector={(state) => [state.canSubmit, state.isSubmitting]}
670
+ children={([canSubmit, isSubmitting]) => (
671
+ <button type="submit" disabled={!canSubmit}>
672
+ {isSubmitting ? '...' : 'Submit'}
673
+ </button>
674
+ )}
675
+ />
676
+ </form>
677
+ </div>
678
+ )
679
+ }
680
+
681
+ const { getByText, findByLabelText, queryByText, findByText } = render(
682
+ <Comp />,
683
+ )
684
+
685
+ expect(queryByText('Name for person 0')).not.toBeInTheDocument()
686
+ expect(queryByText('Name for person 1')).not.toBeInTheDocument()
687
+ await user.click(getByText('Add person'))
688
+ const input = await findByLabelText('Name for person 0')
689
+ expect(input).toBeInTheDocument()
690
+ await user.type(input, 'John')
691
+
692
+ await user.click(getByText('Add person'))
693
+ const input2 = await findByLabelText('Name for person 1')
694
+ expect(input).toBeInTheDocument()
695
+ await user.type(input2, 'Jack')
696
+
697
+ expect(queryByText('Name for person 0')).toBeInTheDocument()
698
+ expect(queryByText('Name for person 1')).toBeInTheDocument()
699
+ await user.click(getByText('Remove person 1'))
700
+ expect(queryByText('Name for person 0')).toBeInTheDocument()
701
+ expect(queryByText('Name for person 1')).not.toBeInTheDocument()
702
+
703
+ await user.click(await findByText('Submit'))
704
+ expect(fn).toHaveBeenCalledWith({ people: ['John'] })
705
+ })
706
+
611
707
  it('should handle arrays with subvalues', async () => {
612
708
  const fn = vi.fn()
613
709
  function Comp() {
@@ -646,6 +742,12 @@ describe('useField', () => {
646
742
  }
647
743
  />
648
744
  </label>
745
+ <button
746
+ onClick={() => field.removeValue(i)}
747
+ type="button"
748
+ >
749
+ Remove person {i}
750
+ </button>
649
751
  </div>
650
752
  )
651
753
  }}
@@ -680,10 +782,23 @@ describe('useField', () => {
680
782
  )
681
783
 
682
784
  expect(queryByText('Name for person 0')).not.toBeInTheDocument()
785
+ expect(queryByText('Name for person 1')).not.toBeInTheDocument()
683
786
  await user.click(getByText('Add person'))
684
787
  const input = await findByLabelText('Name for person 0')
685
788
  expect(input).toBeInTheDocument()
686
789
  await user.type(input, 'John')
790
+
791
+ await user.click(getByText('Add person'))
792
+ const input2 = await findByLabelText('Name for person 1')
793
+ expect(input).toBeInTheDocument()
794
+ await user.type(input2, 'Jack')
795
+
796
+ expect(queryByText('Name for person 0')).toBeInTheDocument()
797
+ expect(queryByText('Name for person 1')).toBeInTheDocument()
798
+ await user.click(getByText('Remove person 1'))
799
+ expect(queryByText('Name for person 0')).toBeInTheDocument()
800
+ expect(queryByText('Name for person 1')).not.toBeInTheDocument()
801
+
687
802
  await user.click(await findByText('Submit'))
688
803
  expect(fn).toHaveBeenCalledWith({ people: [{ name: 'John', age: 0 }] })
689
804
  })
package/src/useField.tsx CHANGED
@@ -37,18 +37,13 @@ export type UseField<
37
37
  TFieldValidator extends
38
38
  | Validator<DeepValue<TParentData, TName>, unknown>
39
39
  | undefined = undefined,
40
+ TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
40
41
  >(
41
42
  opts: Omit<
42
- UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,
43
+ UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>,
43
44
  'form'
44
45
  >,
45
- ) => FieldApi<
46
- TParentData,
47
- TName,
48
- TFieldValidator,
49
- TFormValidator,
50
- DeepValue<TParentData, TName>
51
- >
46
+ ) => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>
52
47
 
53
48
  export function useField<
54
49
  TParentData,
@@ -59,9 +54,16 @@ export function useField<
59
54
  TFormValidator extends
60
55
  | Validator<TParentData, unknown>
61
56
  | undefined = undefined,
57
+ TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
62
58
  >(
63
- opts: UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,
64
- ): FieldApi<TParentData, TName, TFieldValidator, TFormValidator> {
59
+ opts: UseFieldOptions<
60
+ TParentData,
61
+ TName,
62
+ TFieldValidator,
63
+ TFormValidator,
64
+ TData
65
+ >,
66
+ ): FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData> {
65
67
  const [fieldApi] = useState(() => {
66
68
  const api = new FieldApi({
67
69
  ...opts,
@@ -88,7 +90,7 @@ export function useField<
88
90
  fieldApi.store,
89
91
  opts.mode === 'array'
90
92
  ? (state) => {
91
- return [state.meta, Object.keys(state.value).length]
93
+ return [state.meta, Object.keys(state.value as never).length]
92
94
  }
93
95
  : undefined,
94
96
  )
@@ -116,7 +118,7 @@ type FieldComponentProps<
116
118
  TData
117
119
  >,
118
120
  ) => any
119
- } & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>
121
+ } & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>
120
122
 
121
123
  export type FieldComponent<
122
124
  TParentData,
@@ -152,14 +154,27 @@ export function Field<
152
154
  TFormValidator extends
153
155
  | Validator<TParentData, unknown>
154
156
  | undefined = undefined,
157
+ TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
155
158
  >({
156
159
  children,
157
160
  ...fieldOptions
158
161
  }: {
159
162
  children: (
160
- fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator>,
163
+ fieldApi: FieldApi<
164
+ TParentData,
165
+ TName,
166
+ TFieldValidator,
167
+ TFormValidator,
168
+ TData
169
+ >,
161
170
  ) => any
162
- } & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>) {
171
+ } & UseFieldOptions<
172
+ TParentData,
173
+ TName,
174
+ TFieldValidator,
175
+ TFormValidator,
176
+ TData
177
+ >) {
163
178
  const fieldApi = useField(fieldOptions as any)
164
179
 
165
180
  return <>{functionalUpdate(children, fieldApi as any)}</>
package/src/useForm.tsx CHANGED
@@ -1,10 +1,6 @@
1
1
  import { FormApi, functionalUpdate } from '@tanstack/form-core'
2
2
  import { useStore } from '@tanstack/react-store'
3
- import React, {
4
- type PropsWithChildren,
5
- type ReactNode,
6
- useState,
7
- } from 'rehackt'
3
+ import React, { type ReactNode, useState } from 'rehackt'
8
4
  import { Field, type FieldComponent, type UseField, useField } from './useField'
9
5
  import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'
10
6
  import type { NoInfer } from '@tanstack/react-store'