@tanstack/react-form 0.24.2 → 0.24.3

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.
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const decodeFormdata = require("decode-formdata");
4
4
  const createServerValidate = (defaultOpts) => async (formData, info) => {
5
- const { validatorAdapter, onServerValidate } = defaultOpts || {};
5
+ const { validatorAdapter, onServerValidate } = defaultOpts;
6
6
  const runValidator = (propsValue) => {
7
7
  if (validatorAdapter && typeof onServerValidate !== "function") {
8
8
  return validatorAdapter().validate(propsValue, onServerValidate);
@@ -1 +1 @@
1
- {"version":3,"file":"createServerValidate.cjs","sources":["../../src/createServerValidate.ts"],"sourcesContent":["import { decode } from 'decode-formdata'\nimport type {\n FormApi,\n FormOptions,\n ValidationError,\n Validator,\n} from '@tanstack/form-core'\n\ntype OnServerValidateFn<TFormData> = (props: {\n value: TFormData\n}) => ValidationError\n\ntype OnServerValidateOrFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = TFormValidator extends Validator<TFormData, infer FFN>\n ? FFN | OnServerValidateFn<TFormData>\n : OnServerValidateFn<TFormData>\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FormOptions<\n TFormData,\n TFormValidator extends\n | Validator<TFormData, unknown>\n | undefined = undefined,\n > {\n onServerValidate?: OnServerValidateOrFn<TFormData, TFormValidator>\n }\n}\n\ntype ValidateFormData<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = (\n formData: FormData,\n info?: Parameters<typeof decode>[1],\n) => Promise<Partial<FormApi<TFormData, TFormValidator>['state']>>\n\nexport const createServerValidate = <\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(\n defaultOpts?: FormOptions<TFormData, TFormValidator>,\n) =>\n (async (\n formData: FormData,\n info?: Parameters<typeof decode>[1],\n ): Promise<Partial<FormApi<TFormData, TFormValidator>['state']>> => {\n const { validatorAdapter, onServerValidate } = defaultOpts || {}\n\n const runValidator = (propsValue: { value: TFormData }) => {\n if (validatorAdapter && typeof onServerValidate !== 'function') {\n return validatorAdapter().validate(propsValue, onServerValidate)\n }\n\n return (onServerValidate as OnServerValidateFn<TFormData>)(propsValue)\n }\n\n const data = decode(formData, info) as never as TFormData\n\n const onServerError = runValidator({ value: data })\n\n return {\n errorMap: {\n onServer: onServerError,\n },\n errors: onServerError ? [onServerError] : [],\n }\n }) as ValidateFormData<TFormData, TFormValidator>\n\nexport const initialFormState = {\n errorMap: {\n onServer: undefined,\n },\n errors: [],\n}\n"],"names":["decode"],"mappings":";;;AAuCO,MAAM,uBAAuB,CAIlC,gBAEC,OACC,UACA,SACkE;AAClE,QAAM,EAAE,kBAAkB,qBAAqB,eAAe,CAAA;AAExD,QAAA,eAAe,CAAC,eAAqC;AACrD,QAAA,oBAAoB,OAAO,qBAAqB,YAAY;AAC9D,aAAO,iBAAiB,EAAE,SAAS,YAAY,gBAAgB;AAAA,IACjE;AAEA,WAAQ,iBAAmD,UAAU;AAAA,EAAA;AAGjE,QAAA,OAAOA,eAAAA,OAAO,UAAU,IAAI;AAElC,QAAM,gBAAgB,aAAa,EAAE,OAAO,KAAM,CAAA;AAE3C,SAAA;AAAA,IACL,UAAU;AAAA,MACR,UAAU;AAAA,IACZ;AAAA,IACA,QAAQ,gBAAgB,CAAC,aAAa,IAAI,CAAC;AAAA,EAAA;AAE/C;AAEK,MAAM,mBAAmB;AAAA,EAC9B,UAAU;AAAA,IACR,UAAU;AAAA,EACZ;AAAA,EACA,QAAQ,CAAC;AACX;;;"}
1
+ {"version":3,"file":"createServerValidate.cjs","sources":["../../src/createServerValidate.ts"],"sourcesContent":["import { decode } from 'decode-formdata'\nimport type {\n FormApi,\n FormOptions,\n ValidationError,\n Validator,\n} from '@tanstack/form-core'\n\ntype OnServerValidateFn<TFormData> = (props: {\n value: TFormData\n}) => ValidationError\n\ntype OnServerValidateOrFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = TFormValidator extends Validator<TFormData, infer FFN>\n ? FFN | OnServerValidateFn<TFormData>\n : OnServerValidateFn<TFormData>\n\ninterface ServerFormOptions<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> extends FormOptions<TFormData, TFormValidator> {\n onServerValidate?: OnServerValidateOrFn<TFormData, TFormValidator>\n}\n\ntype ValidateFormData<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = (\n formData: FormData,\n info?: Parameters<typeof decode>[1],\n) => Promise<Partial<FormApi<TFormData, TFormValidator>['state']>>\n\nexport const createServerValidate = <\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(\n defaultOpts: ServerFormOptions<TFormData, TFormValidator>,\n) =>\n (async (\n formData: FormData,\n info?: Parameters<typeof decode>[1],\n ): Promise<Partial<FormApi<TFormData, TFormValidator>['state']>> => {\n const { validatorAdapter, onServerValidate } = defaultOpts\n\n const runValidator = (propsValue: { value: TFormData }) => {\n if (validatorAdapter && typeof onServerValidate !== 'function') {\n return validatorAdapter().validate(propsValue, onServerValidate)\n }\n\n return (onServerValidate as OnServerValidateFn<TFormData>)(propsValue)\n }\n\n const data = decode(formData, info) as never as TFormData\n\n const onServerError = runValidator({ value: data })\n\n return {\n errorMap: {\n onServer: onServerError,\n },\n errors: onServerError ? [onServerError] : [],\n }\n }) as ValidateFormData<TFormData, TFormValidator>\n\nexport const initialFormState = {\n errorMap: {\n onServer: undefined,\n },\n errors: [],\n}\n"],"names":["decode"],"mappings":";;;AAkCO,MAAM,uBAAuB,CAIlC,gBAEC,OACC,UACA,SACkE;AAC5D,QAAA,EAAE,kBAAkB,iBAAqB,IAAA;AAEzC,QAAA,eAAe,CAAC,eAAqC;AACrD,QAAA,oBAAoB,OAAO,qBAAqB,YAAY;AAC9D,aAAO,iBAAiB,EAAE,SAAS,YAAY,gBAAgB;AAAA,IACjE;AAEA,WAAQ,iBAAmD,UAAU;AAAA,EAAA;AAGjE,QAAA,OAAOA,eAAAA,OAAO,UAAU,IAAI;AAElC,QAAM,gBAAgB,aAAa,EAAE,OAAO,KAAM,CAAA;AAE3C,SAAA;AAAA,IACL,UAAU;AAAA,MACR,UAAU;AAAA,IACZ;AAAA,IACA,QAAQ,gBAAgB,CAAC,aAAa,IAAI,CAAC;AAAA,EAAA;AAE/C;AAEK,MAAM,mBAAmB;AAAA,EAC9B,UAAU;AAAA,IACR,UAAU;AAAA,EACZ;AAAA,EACA,QAAQ,CAAC;AACX;;;"}
@@ -5,13 +5,11 @@ type OnServerValidateFn<TFormData> = (props: {
5
5
  value: TFormData;
6
6
  }) => ValidationError;
7
7
  type OnServerValidateOrFn<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = TFormValidator extends Validator<TFormData, infer FFN> ? FFN | OnServerValidateFn<TFormData> : OnServerValidateFn<TFormData>;
8
- declare module '@tanstack/form-core' {
9
- interface FormOptions<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> {
10
- onServerValidate?: OnServerValidateOrFn<TFormData, TFormValidator>;
11
- }
8
+ interface ServerFormOptions<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> extends FormOptions<TFormData, TFormValidator> {
9
+ onServerValidate?: OnServerValidateOrFn<TFormData, TFormValidator>;
12
10
  }
13
11
  type ValidateFormData<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = (formData: FormData, info?: Parameters<typeof decode>[1]) => Promise<Partial<FormApi<TFormData, TFormValidator>['state']>>;
14
- export declare const createServerValidate: <TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(defaultOpts?: FormOptions<TFormData, TFormValidator>) => ValidateFormData<TFormData, TFormValidator>;
12
+ export declare const createServerValidate: <TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(defaultOpts: ServerFormOptions<TFormData, TFormValidator>) => ValidateFormData<TFormData, TFormValidator>;
15
13
  export declare const initialFormState: {
16
14
  errorMap: {
17
15
  onServer: undefined;
@@ -12,8 +12,9 @@ function useField(opts) {
12
12
  form: opts.form,
13
13
  name: opts.name
14
14
  });
15
- api.Field = Field;
16
- return api;
15
+ const extendedApi = api;
16
+ extendedApi.Field = Field;
17
+ return extendedApi;
17
18
  });
18
19
  useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(fieldApi.mount, [fieldApi]);
19
20
  useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"useField.cjs","sources":["../../src/useField.tsx"],"sourcesContent":["import React, { type FunctionComponent, useState } from 'react'\nimport { useStore } from '@tanstack/react-store'\nimport { FieldApi, functionalUpdate } from '@tanstack/form-core'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\nimport type { NodeType, UseFieldOptions } from './types'\nimport type { DeepKeys, DeepValue, Validator } from '@tanstack/form-core'\n\ndeclare module '@tanstack/form-core' {\n /**\n * When using `@tanstack/react-form`, the core field API is extended at type level with additional methods for React-specific functionality:\n */\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 /**\n * A pre-bound and type-safe sub-field component using this field as a root.\n */\n Field: FieldComponent<TParentData, TFormValidator>\n }\n}\n\n/**\n * A type representing a hook for using a field in a form with the given form data type.\n *\n * A function that takes an optional object with a `name` property and field options, and returns a `FieldApi` instance for the specified field.\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\n/**\n * A hook for managing a field in a form.\n * @param opts An object with field options.\n *\n * @returns The `FieldApi` instance for the specified field.\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 ?? []).length]\n }\n : undefined,\n )\n\n return fieldApi as never\n}\n\n/**\n * @param children A render function that takes a field API instance and returns a React element.\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 ) => NodeType\n} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>\n\n/**\n * A type alias representing a field component for a specific form data type.\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>) => NodeType\n\n/**\n * A function component that takes field options and a render function as children and returns a React component.\n *\n * The `Field` component uses the `useField` hook internally to manage the field instance.\n */\nexport const 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}: FieldComponentProps<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n>): NodeType => {\n const fieldApi = useField(fieldOptions as any)\n\n return (<>{functionalUpdate(children, fieldApi as any)}</>) as never\n}) satisfies FunctionComponent<FieldComponentProps<any, any, any, any, any>>\n"],"names":["useState","FieldApi","useIsomorphicLayoutEffect","useStore","jsx","Fragment","functionalUpdate"],"mappings":";;;;;;;AA2DO,SAAS,SAWd,MAOsE;AACtE,QAAM,CAAC,QAAQ,IAAIA,MAAAA,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,SAAS,CAAA,CAAE,EAAE,MAAM;AAAA,IAE3D,IAAA;AAAA,EAAA;AAGC,SAAA;AACT;AA4DO,MAAM,QAAS,CAUpB;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAMgB;AACR,QAAA,WAAW,SAAS,YAAmB;AAE7C,SAAWC,2BAAA,IAAAC,WAAA,UAAA,EAAA,UAAAC,SAAA,iBAAiB,UAAU,QAAe,EAAE,CAAA;AACzD;;;"}
1
+ {"version":3,"file":"useField.cjs","sources":["../../src/useField.tsx"],"sourcesContent":["import React, { type FunctionComponent, useState } from 'react'\nimport { useStore } from '@tanstack/react-store'\nimport { FieldApi, functionalUpdate } from '@tanstack/form-core'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\nimport type { NodeType, UseFieldOptions } from './types'\nimport type { DeepKeys, DeepValue, Validator } from '@tanstack/form-core'\n\ninterface ReactFieldApi<\n TParentData,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n> {\n /**\n * A pre-bound and type-safe sub-field component using this field as a root.\n */\n Field: FieldComponent<TParentData, TFormValidator>\n}\n\n/**\n * A type representing a hook for using a field in a form with the given form data type.\n *\n * A function that takes an optional object with a `name` property and field options, and returns a `FieldApi` instance for the specified field.\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\n/**\n * A hook for managing a field in a form.\n * @param opts An object with field options.\n *\n * @returns The `FieldApi` instance for the specified field.\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) {\n const [fieldApi] = useState(() => {\n const api = new FieldApi({\n ...opts,\n form: opts.form,\n name: opts.name,\n })\n\n const extendedApi: typeof api & ReactFieldApi<TParentData, TFormValidator> =\n api as never\n\n extendedApi.Field = Field as never\n\n return extendedApi\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\n}\n\n/**\n * @param children A render function that takes a field API instance and returns a React element.\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 ) => NodeType\n} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>\n\n/**\n * A type alias representing a field component for a specific form data type.\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>) => NodeType\n\n/**\n * A function component that takes field options and a render function as children and returns a React component.\n *\n * The `Field` component uses the `useField` hook internally to manage the field instance.\n */\nexport const 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}: FieldComponentProps<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n>): NodeType => {\n const fieldApi = useField(fieldOptions as any)\n\n return (<>{functionalUpdate(children, fieldApi as any)}</>) as never\n}) satisfies FunctionComponent<FieldComponentProps<any, any, any, any, any>>\n"],"names":["useState","FieldApi","useIsomorphicLayoutEffect","useStore","jsx","Fragment","functionalUpdate"],"mappings":";;;;;;;AAgDO,SAAS,SAWd,MAOA;AACA,QAAM,CAAC,QAAQ,IAAIA,MAAAA,SAAS,MAAM;AAC1B,UAAA,MAAM,IAAIC,kBAAS;AAAA,MACvB,GAAG;AAAA,MACH,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,IAAA,CACZ;AAED,UAAM,cACJ;AAEF,gBAAY,QAAQ;AAEb,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,SAAS,CAAA,CAAE,EAAE,MAAM;AAAA,IAE3D,IAAA;AAAA,EAAA;AAGC,SAAA;AACT;AA4DO,MAAM,QAAS,CAUpB;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAMgB;AACR,QAAA,WAAW,SAAS,YAAmB;AAE7C,SAAWC,2BAAA,IAAAC,WAAA,UAAA,EAAA,UAAAC,SAAA,iBAAiB,UAAU,QAAe,EAAE,CAAA;AACzD;;;"}
@@ -1,16 +1,11 @@
1
1
  import { FieldApi, DeepKeys, DeepValue, Validator } from '@tanstack/form-core';
2
2
  import { NodeType, UseFieldOptions } from './types.cjs';
3
3
 
4
- declare module '@tanstack/form-core' {
4
+ interface ReactFieldApi<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined> {
5
5
  /**
6
- * When using `@tanstack/react-form`, the core field API is extended at type level with additional methods for React-specific functionality:
6
+ * A pre-bound and type-safe sub-field component using this field as a root.
7
7
  */
8
- 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>> {
9
- /**
10
- * A pre-bound and type-safe sub-field component using this field as a root.
11
- */
12
- Field: FieldComponent<TParentData, TFormValidator>;
13
- }
8
+ Field: FieldComponent<TParentData, TFormValidator>;
14
9
  }
15
10
  /**
16
11
  * A type representing a hook for using a field in a form with the given form data type.
@@ -24,7 +19,7 @@ export type UseField<TParentData, TFormValidator extends Validator<TParentData,
24
19
  *
25
20
  * @returns The `FieldApi` instance for the specified field.
26
21
  */
27
- 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>;
22
+ 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> & ReactFieldApi<TParentData, TFormValidator>;
28
23
  /**
29
24
  * @param children A render function that takes a field API instance and returns a React element.
30
25
  */
@@ -9,21 +9,22 @@ const useIsomorphicLayoutEffect = require("./useIsomorphicLayoutEffect.cjs");
9
9
  function useForm(opts) {
10
10
  const [formApi] = react.useState(() => {
11
11
  const api = new formCore.FormApi(opts);
12
- api.Field = function APIField(props) {
12
+ const extendedApi = api;
13
+ extendedApi.Field = function APIField(props) {
13
14
  return /* @__PURE__ */ jsxRuntime.jsx(useField.Field, { ...props, form: api });
14
15
  };
15
- api.useField = (props) => useField.useField({ ...props, form: api });
16
- api.useStore = (selector) => {
16
+ extendedApi.useField = (props) => useField.useField({ ...props, form: api });
17
+ extendedApi.useStore = (selector) => {
17
18
  return reactStore.useStore(api.store, selector);
18
19
  };
19
- api.Subscribe = (props) => {
20
+ extendedApi.Subscribe = (props) => {
20
21
  return formCore.functionalUpdate(
21
22
  props.children,
22
23
  // eslint-disable-next-line react-hooks/rules-of-hooks
23
24
  reactStore.useStore(api.store, props.selector)
24
25
  );
25
26
  };
26
- return api;
27
+ return extendedApi;
27
28
  });
28
29
  useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(formApi.mount, []);
29
30
  formApi.useStore((state) => state.isSubmitting);
@@ -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, { useState } from 'react'\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'\nimport type { NodeType } from './types'\n\ndeclare module '@tanstack/form-core' {\n /**\n * When using `@tanstack/react-form`, the core form API is extended at type level with additional methods for React-specific functionality:\n */\n // eslint-disable-next-line no-shadow\n interface FormApi<TFormData, TFormValidator> {\n /**\n * A React component to render form fields. With this, you can render and manage individual form fields.\n */\n Field: FieldComponent<TFormData, TFormValidator>\n /**\n * A custom React hook that provides functionalities related to individual form fields. It gives you access to field values, errors, and allows you to set or update field values.\n */\n useField: UseField<TFormData, TFormValidator>\n /**\n * A `useStore` hook that connects to the internal store of the form. It can be used to access the form's current state or any other related state information. You can optionally pass in a selector function to cherry-pick specific parts of the state\n */\n useStore: <TSelected = NoInfer<FormState<TFormData>>>(\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,\n ) => TSelected\n /**\n * A `Subscribe` function that allows you to listen and react to changes in the form's state. It's especially useful when you need to execute side effects or render specific components in response to state updates.\n */\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>) => NodeType) | NodeType\n }) => NodeType\n }\n}\n\n/**\n * A custom React Hook that returns an instance of the `FormApi` class.\n *\n * This API encapsulates all the necessary functionalities related to the form. It allows you to manage form state, handle submissions, and interact with form fields\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} />) as never\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":";;;;;;;;AAuDO,SAAS,QAId,MACoC;AACpC,QAAM,CAAC,OAAO,IAAIA,MAAAA,SAAS,MAAM;AACzB,UAAA,MAAM,IAAIC,iBAAmC,IAAI;AACnD,QAAA,QAAQ,SAAS,SAAS,OAAO;AACnC,aAASC,2BAAAA,IAAAC,SAAAA,OAAA,EAAO,GAAG,OAAO,MAAM,IAAK,CAAA;AAAA,IAAA;AAGnC,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, { useState } from 'react'\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'\nimport type { NodeType } from './types'\n\n/**\n * Fields that are added onto the `FormAPI` from `@tanstack/form-core` and returned from `useForm`\n */\ninterface ReactFormApi<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n /**\n * A React component to render form fields. With this, you can render and manage individual form fields.\n */\n Field: FieldComponent<TFormData, TFormValidator>\n /**\n * A custom React hook that provides functionalities related to individual form fields. It gives you access to field values, errors, and allows you to set or update field values.\n */\n useField: UseField<TFormData, TFormValidator>\n /**\n * A `useStore` hook that connects to the internal store of the form. It can be used to access the form's current state or any other related state information. You can optionally pass in a selector function to cherry-pick specific parts of the state\n */\n useStore: <TSelected = NoInfer<FormState<TFormData>>>(\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,\n ) => TSelected\n /**\n * A `Subscribe` function that allows you to listen and react to changes in the form's state. It's especially useful when you need to execute side effects or render specific components in response to state updates.\n */\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>) => NodeType) | NodeType\n }) => NodeType\n}\n\n/**\n * A custom React Hook that returns an extended instance of the `FormApi` class.\n *\n * This API encapsulates all the necessary functionalities related to the form. It allows you to manage form state, handle submissions, and interact with form fields\n */\nexport function useForm<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(opts?: FormOptions<TFormData, TFormValidator>) {\n const [formApi] = useState(() => {\n const api = new FormApi<TFormData, TFormValidator>(opts)\n\n const extendedApi: typeof api & ReactFormApi<TFormData, TFormValidator> =\n api as never\n extendedApi.Field = function APIField(props) {\n return (<Field {...props} form={api} />) as never\n }\n // eslint-disable-next-line react-hooks/rules-of-hooks\n extendedApi.useField = (props) => useField({ ...props, form: api })\n extendedApi.useStore = (selector) => {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useStore(api.store as any, selector as any) as any\n }\n extendedApi.Subscribe = (props) => {\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 extendedApi\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\n}\n"],"names":["useState","FormApi","jsx","Field","useField","useStore","functionalUpdate","useIsomorphicLayoutEffect"],"mappings":";;;;;;;;AAuDO,SAAS,QAGd,MAA+C;AAC/C,QAAM,CAAC,OAAO,IAAIA,MAAAA,SAAS,MAAM;AACzB,UAAA,MAAM,IAAIC,iBAAmC,IAAI;AAEvD,UAAM,cACJ;AACU,gBAAA,QAAQ,SAAS,SAAS,OAAO;AAC3C,aAASC,2BAAAA,IAAAC,SAAAA,OAAA,EAAO,GAAG,OAAO,MAAM,IAAK,CAAA;AAAA,IAAA;AAG3B,gBAAA,WAAW,CAAC,UAAUC,SAAA,SAAS,EAAE,GAAG,OAAO,MAAM,IAAA,CAAK;AACtD,gBAAA,WAAW,CAAC,aAAa;AAE5B,aAAAC,oBAAS,IAAI,OAAc,QAAe;AAAA,IAAA;AAEvC,gBAAA,YAAY,CAAC,UAAU;AAC1B,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;;"}
@@ -3,46 +3,45 @@ import { FieldComponent, UseField } from './useField.cjs';
3
3
  import { NoInfer } from '@tanstack/react-store';
4
4
  import { NodeType } from './types.cjs';
5
5
 
6
- declare module '@tanstack/form-core' {
6
+ /**
7
+ * Fields that are added onto the `FormAPI` from `@tanstack/form-core` and returned from `useForm`
8
+ */
9
+ interface ReactFormApi<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> {
7
10
  /**
8
- * When using `@tanstack/react-form`, the core form API is extended at type level with additional methods for React-specific functionality:
11
+ * A React component to render form fields. With this, you can render and manage individual form fields.
9
12
  */
10
- interface FormApi<TFormData, TFormValidator> {
11
- /**
12
- * A React component to render form fields. With this, you can render and manage individual form fields.
13
- */
14
- Field: FieldComponent<TFormData, TFormValidator>;
15
- /**
16
- * A custom React hook that provides functionalities related to individual form fields. It gives you access to field values, errors, and allows you to set or update field values.
17
- */
18
- useField: UseField<TFormData, TFormValidator>;
19
- /**
20
- * A `useStore` hook that connects to the internal store of the form. It can be used to access the form's current state or any other related state information. You can optionally pass in a selector function to cherry-pick specific parts of the state
21
- */
22
- useStore: <TSelected = NoInfer<FormState<TFormData>>>(selector?: (state: NoInfer<FormState<TFormData>>) => TSelected) => TSelected;
13
+ Field: FieldComponent<TFormData, TFormValidator>;
14
+ /**
15
+ * A custom React hook that provides functionalities related to individual form fields. It gives you access to field values, errors, and allows you to set or update field values.
16
+ */
17
+ useField: UseField<TFormData, TFormValidator>;
18
+ /**
19
+ * A `useStore` hook that connects to the internal store of the form. It can be used to access the form's current state or any other related state information. You can optionally pass in a selector function to cherry-pick specific parts of the state
20
+ */
21
+ useStore: <TSelected = NoInfer<FormState<TFormData>>>(selector?: (state: NoInfer<FormState<TFormData>>) => TSelected) => TSelected;
22
+ /**
23
+ * A `Subscribe` function that allows you to listen and react to changes in the form's state. It's especially useful when you need to execute side effects or render specific components in response to state updates.
24
+ */
25
+ Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
23
26
  /**
24
- * A `Subscribe` function that allows you to listen and react to changes in the form's state. It's especially useful when you need to execute side effects or render specific components in response to state updates.
25
- */
26
- Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
27
- /**
28
- TypeScript versions <=5.0.4 have a bug that prevents
29
- the type of the `TSelected` generic from being inferred
30
- from the return type of this method.
31
-
32
- In these versions, `TSelected` will fall back to the default
33
- type (or `unknown` if that's not defined).
34
-
35
- @see {@link https://github.com/TanStack/form/pull/606/files#r1506715714 | This discussion on GitHub for the details}
36
- @see {@link https://github.com/microsoft/TypeScript/issues/52786 | The bug report in `microsoft/TypeScript`}
37
- */
38
- selector?: (state: NoInfer<FormState<TFormData>>) => TSelected;
39
- children: ((state: NoInfer<TSelected>) => NodeType) | NodeType;
40
- }) => NodeType;
41
- }
27
+ TypeScript versions <=5.0.4 have a bug that prevents
28
+ the type of the `TSelected` generic from being inferred
29
+ from the return type of this method.
30
+
31
+ In these versions, `TSelected` will fall back to the default
32
+ type (or `unknown` if that's not defined).
33
+
34
+ @see {@link https://github.com/TanStack/form/pull/606/files#r1506715714 | This discussion on GitHub for the details}
35
+ @see {@link https://github.com/microsoft/TypeScript/issues/52786 | The bug report in `microsoft/TypeScript`}
36
+ */
37
+ selector?: (state: NoInfer<FormState<TFormData>>) => TSelected;
38
+ children: ((state: NoInfer<TSelected>) => NodeType) | NodeType;
39
+ }) => NodeType;
42
40
  }
43
41
  /**
44
- * A custom React Hook that returns an instance of the `FormApi` class.
42
+ * A custom React Hook that returns an extended instance of the `FormApi` class.
45
43
  *
46
44
  * This API encapsulates all the necessary functionalities related to the form. It allows you to manage form state, handle submissions, and interact with form fields
47
45
  */
48
- export declare function useForm<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(opts?: FormOptions<TFormData, TFormValidator>): FormApi<TFormData, TFormValidator>;
46
+ export declare function useForm<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(opts?: FormOptions<TFormData, TFormValidator>): FormApi<TFormData, TFormValidator> & ReactFormApi<TFormData, TFormValidator>;
47
+ export {};
@@ -1,9 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const react = require("react");
4
- const useIsomorphicLayoutEffect = (
5
- // @ts-ignore
6
- typeof window !== "undefined" ? react.useLayoutEffect : react.useEffect
7
- );
4
+ const useIsomorphicLayoutEffect = typeof window !== "undefined" ? react.useLayoutEffect : react.useEffect;
8
5
  exports.useIsomorphicLayoutEffect = useIsomorphicLayoutEffect;
9
6
  //# sourceMappingURL=useIsomorphicLayoutEffect.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useIsomorphicLayoutEffect.cjs","sources":["../../src/useIsomorphicLayoutEffect.ts"],"sourcesContent":["import { useEffect, useLayoutEffect } from 'react'\n\nexport const useIsomorphicLayoutEffect =\n // @ts-ignore\n typeof window !== 'undefined' ? useLayoutEffect : useEffect\n"],"names":["useLayoutEffect","useEffect"],"mappings":";;;AAEa,MAAA;AAAA;AAAA,EAEX,OAAO,WAAW,cAAcA,MAAAA,kBAAkBC,MAAA;AAAA;;"}
1
+ {"version":3,"file":"useIsomorphicLayoutEffect.cjs","sources":["../../src/useIsomorphicLayoutEffect.ts"],"sourcesContent":["import { useEffect, useLayoutEffect } from 'react'\n\nexport const useIsomorphicLayoutEffect =\n typeof window !== 'undefined' ? useLayoutEffect : useEffect\n"],"names":["useLayoutEffect","useEffect"],"mappings":";;;AAEO,MAAM,4BACX,OAAO,WAAW,cAAcA,wBAAkBC,MAAAA;;"}
@@ -5,13 +5,11 @@ type OnServerValidateFn<TFormData> = (props: {
5
5
  value: TFormData;
6
6
  }) => ValidationError;
7
7
  type OnServerValidateOrFn<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = TFormValidator extends Validator<TFormData, infer FFN> ? FFN | OnServerValidateFn<TFormData> : OnServerValidateFn<TFormData>;
8
- declare module '@tanstack/form-core' {
9
- interface FormOptions<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> {
10
- onServerValidate?: OnServerValidateOrFn<TFormData, TFormValidator>;
11
- }
8
+ interface ServerFormOptions<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> extends FormOptions<TFormData, TFormValidator> {
9
+ onServerValidate?: OnServerValidateOrFn<TFormData, TFormValidator>;
12
10
  }
13
11
  type ValidateFormData<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = (formData: FormData, info?: Parameters<typeof decode>[1]) => Promise<Partial<FormApi<TFormData, TFormValidator>['state']>>;
14
- export declare const createServerValidate: <TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(defaultOpts?: FormOptions<TFormData, TFormValidator>) => ValidateFormData<TFormData, TFormValidator>;
12
+ export declare const createServerValidate: <TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(defaultOpts: ServerFormOptions<TFormData, TFormValidator>) => ValidateFormData<TFormData, TFormValidator>;
15
13
  export declare const initialFormState: {
16
14
  errorMap: {
17
15
  onServer: undefined;
@@ -1,6 +1,6 @@
1
1
  import { decode } from "decode-formdata";
2
2
  const createServerValidate = (defaultOpts) => async (formData, info) => {
3
- const { validatorAdapter, onServerValidate } = defaultOpts || {};
3
+ const { validatorAdapter, onServerValidate } = defaultOpts;
4
4
  const runValidator = (propsValue) => {
5
5
  if (validatorAdapter && typeof onServerValidate !== "function") {
6
6
  return validatorAdapter().validate(propsValue, onServerValidate);
@@ -1 +1 @@
1
- {"version":3,"file":"createServerValidate.js","sources":["../../src/createServerValidate.ts"],"sourcesContent":["import { decode } from 'decode-formdata'\nimport type {\n FormApi,\n FormOptions,\n ValidationError,\n Validator,\n} from '@tanstack/form-core'\n\ntype OnServerValidateFn<TFormData> = (props: {\n value: TFormData\n}) => ValidationError\n\ntype OnServerValidateOrFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = TFormValidator extends Validator<TFormData, infer FFN>\n ? FFN | OnServerValidateFn<TFormData>\n : OnServerValidateFn<TFormData>\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FormOptions<\n TFormData,\n TFormValidator extends\n | Validator<TFormData, unknown>\n | undefined = undefined,\n > {\n onServerValidate?: OnServerValidateOrFn<TFormData, TFormValidator>\n }\n}\n\ntype ValidateFormData<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = (\n formData: FormData,\n info?: Parameters<typeof decode>[1],\n) => Promise<Partial<FormApi<TFormData, TFormValidator>['state']>>\n\nexport const createServerValidate = <\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(\n defaultOpts?: FormOptions<TFormData, TFormValidator>,\n) =>\n (async (\n formData: FormData,\n info?: Parameters<typeof decode>[1],\n ): Promise<Partial<FormApi<TFormData, TFormValidator>['state']>> => {\n const { validatorAdapter, onServerValidate } = defaultOpts || {}\n\n const runValidator = (propsValue: { value: TFormData }) => {\n if (validatorAdapter && typeof onServerValidate !== 'function') {\n return validatorAdapter().validate(propsValue, onServerValidate)\n }\n\n return (onServerValidate as OnServerValidateFn<TFormData>)(propsValue)\n }\n\n const data = decode(formData, info) as never as TFormData\n\n const onServerError = runValidator({ value: data })\n\n return {\n errorMap: {\n onServer: onServerError,\n },\n errors: onServerError ? [onServerError] : [],\n }\n }) as ValidateFormData<TFormData, TFormValidator>\n\nexport const initialFormState = {\n errorMap: {\n onServer: undefined,\n },\n errors: [],\n}\n"],"names":[],"mappings":";AAuCO,MAAM,uBAAuB,CAIlC,gBAEC,OACC,UACA,SACkE;AAClE,QAAM,EAAE,kBAAkB,qBAAqB,eAAe,CAAA;AAExD,QAAA,eAAe,CAAC,eAAqC;AACrD,QAAA,oBAAoB,OAAO,qBAAqB,YAAY;AAC9D,aAAO,iBAAiB,EAAE,SAAS,YAAY,gBAAgB;AAAA,IACjE;AAEA,WAAQ,iBAAmD,UAAU;AAAA,EAAA;AAGjE,QAAA,OAAO,OAAO,UAAU,IAAI;AAElC,QAAM,gBAAgB,aAAa,EAAE,OAAO,KAAM,CAAA;AAE3C,SAAA;AAAA,IACL,UAAU;AAAA,MACR,UAAU;AAAA,IACZ;AAAA,IACA,QAAQ,gBAAgB,CAAC,aAAa,IAAI,CAAC;AAAA,EAAA;AAE/C;AAEK,MAAM,mBAAmB;AAAA,EAC9B,UAAU;AAAA,IACR,UAAU;AAAA,EACZ;AAAA,EACA,QAAQ,CAAC;AACX;"}
1
+ {"version":3,"file":"createServerValidate.js","sources":["../../src/createServerValidate.ts"],"sourcesContent":["import { decode } from 'decode-formdata'\nimport type {\n FormApi,\n FormOptions,\n ValidationError,\n Validator,\n} from '@tanstack/form-core'\n\ntype OnServerValidateFn<TFormData> = (props: {\n value: TFormData\n}) => ValidationError\n\ntype OnServerValidateOrFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = TFormValidator extends Validator<TFormData, infer FFN>\n ? FFN | OnServerValidateFn<TFormData>\n : OnServerValidateFn<TFormData>\n\ninterface ServerFormOptions<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> extends FormOptions<TFormData, TFormValidator> {\n onServerValidate?: OnServerValidateOrFn<TFormData, TFormValidator>\n}\n\ntype ValidateFormData<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = (\n formData: FormData,\n info?: Parameters<typeof decode>[1],\n) => Promise<Partial<FormApi<TFormData, TFormValidator>['state']>>\n\nexport const createServerValidate = <\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(\n defaultOpts: ServerFormOptions<TFormData, TFormValidator>,\n) =>\n (async (\n formData: FormData,\n info?: Parameters<typeof decode>[1],\n ): Promise<Partial<FormApi<TFormData, TFormValidator>['state']>> => {\n const { validatorAdapter, onServerValidate } = defaultOpts\n\n const runValidator = (propsValue: { value: TFormData }) => {\n if (validatorAdapter && typeof onServerValidate !== 'function') {\n return validatorAdapter().validate(propsValue, onServerValidate)\n }\n\n return (onServerValidate as OnServerValidateFn<TFormData>)(propsValue)\n }\n\n const data = decode(formData, info) as never as TFormData\n\n const onServerError = runValidator({ value: data })\n\n return {\n errorMap: {\n onServer: onServerError,\n },\n errors: onServerError ? [onServerError] : [],\n }\n }) as ValidateFormData<TFormData, TFormValidator>\n\nexport const initialFormState = {\n errorMap: {\n onServer: undefined,\n },\n errors: [],\n}\n"],"names":[],"mappings":";AAkCO,MAAM,uBAAuB,CAIlC,gBAEC,OACC,UACA,SACkE;AAC5D,QAAA,EAAE,kBAAkB,iBAAqB,IAAA;AAEzC,QAAA,eAAe,CAAC,eAAqC;AACrD,QAAA,oBAAoB,OAAO,qBAAqB,YAAY;AAC9D,aAAO,iBAAiB,EAAE,SAAS,YAAY,gBAAgB;AAAA,IACjE;AAEA,WAAQ,iBAAmD,UAAU;AAAA,EAAA;AAGjE,QAAA,OAAO,OAAO,UAAU,IAAI;AAElC,QAAM,gBAAgB,aAAa,EAAE,OAAO,KAAM,CAAA;AAE3C,SAAA;AAAA,IACL,UAAU;AAAA,MACR,UAAU;AAAA,IACZ;AAAA,IACA,QAAQ,gBAAgB,CAAC,aAAa,IAAI,CAAC;AAAA,EAAA;AAE/C;AAEK,MAAM,mBAAmB;AAAA,EAC9B,UAAU;AAAA,IACR,UAAU;AAAA,EACZ;AAAA,EACA,QAAQ,CAAC;AACX;"}
@@ -1,16 +1,11 @@
1
1
  import { FieldApi, DeepKeys, DeepValue, Validator } from '@tanstack/form-core';
2
2
  import { NodeType, UseFieldOptions } from './types.js';
3
3
 
4
- declare module '@tanstack/form-core' {
4
+ interface ReactFieldApi<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined> {
5
5
  /**
6
- * When using `@tanstack/react-form`, the core field API is extended at type level with additional methods for React-specific functionality:
6
+ * A pre-bound and type-safe sub-field component using this field as a root.
7
7
  */
8
- 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>> {
9
- /**
10
- * A pre-bound and type-safe sub-field component using this field as a root.
11
- */
12
- Field: FieldComponent<TParentData, TFormValidator>;
13
- }
8
+ Field: FieldComponent<TParentData, TFormValidator>;
14
9
  }
15
10
  /**
16
11
  * A type representing a hook for using a field in a form with the given form data type.
@@ -24,7 +19,7 @@ export type UseField<TParentData, TFormValidator extends Validator<TParentData,
24
19
  *
25
20
  * @returns The `FieldApi` instance for the specified field.
26
21
  */
27
- 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>;
22
+ 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> & ReactFieldApi<TParentData, TFormValidator>;
28
23
  /**
29
24
  * @param children A render function that takes a field API instance and returns a React element.
30
25
  */
@@ -10,8 +10,9 @@ function useField(opts) {
10
10
  form: opts.form,
11
11
  name: opts.name
12
12
  });
13
- api.Field = Field;
14
- return api;
13
+ const extendedApi = api;
14
+ extendedApi.Field = Field;
15
+ return extendedApi;
15
16
  });
16
17
  useIsomorphicLayoutEffect(fieldApi.mount, [fieldApi]);
17
18
  useIsomorphicLayoutEffect(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"useField.js","sources":["../../src/useField.tsx"],"sourcesContent":["import React, { type FunctionComponent, useState } from 'react'\nimport { useStore } from '@tanstack/react-store'\nimport { FieldApi, functionalUpdate } from '@tanstack/form-core'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\nimport type { NodeType, UseFieldOptions } from './types'\nimport type { DeepKeys, DeepValue, Validator } from '@tanstack/form-core'\n\ndeclare module '@tanstack/form-core' {\n /**\n * When using `@tanstack/react-form`, the core field API is extended at type level with additional methods for React-specific functionality:\n */\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 /**\n * A pre-bound and type-safe sub-field component using this field as a root.\n */\n Field: FieldComponent<TParentData, TFormValidator>\n }\n}\n\n/**\n * A type representing a hook for using a field in a form with the given form data type.\n *\n * A function that takes an optional object with a `name` property and field options, and returns a `FieldApi` instance for the specified field.\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\n/**\n * A hook for managing a field in a form.\n * @param opts An object with field options.\n *\n * @returns The `FieldApi` instance for the specified field.\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 ?? []).length]\n }\n : undefined,\n )\n\n return fieldApi as never\n}\n\n/**\n * @param children A render function that takes a field API instance and returns a React element.\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 ) => NodeType\n} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>\n\n/**\n * A type alias representing a field component for a specific form data type.\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>) => NodeType\n\n/**\n * A function component that takes field options and a render function as children and returns a React component.\n *\n * The `Field` component uses the `useField` hook internally to manage the field instance.\n */\nexport const 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}: FieldComponentProps<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n>): NodeType => {\n const fieldApi = useField(fieldOptions as any)\n\n return (<>{functionalUpdate(children, fieldApi as any)}</>) as never\n}) satisfies FunctionComponent<FieldComponentProps<any, any, any, any, any>>\n"],"names":[],"mappings":";;;;;AA2DO,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,SAAS,CAAA,CAAE,EAAE,MAAM;AAAA,IAE3D,IAAA;AAAA,EAAA;AAGC,SAAA;AACT;AA4DO,MAAM,QAAS,CAUpB;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAMgB;AACR,QAAA,WAAW,SAAS,YAAmB;AAE7C,SAAW,oBAAA,UAAA,EAAA,UAAA,iBAAiB,UAAU,QAAe,EAAE,CAAA;AACzD;"}
1
+ {"version":3,"file":"useField.js","sources":["../../src/useField.tsx"],"sourcesContent":["import React, { type FunctionComponent, useState } from 'react'\nimport { useStore } from '@tanstack/react-store'\nimport { FieldApi, functionalUpdate } from '@tanstack/form-core'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\nimport type { NodeType, UseFieldOptions } from './types'\nimport type { DeepKeys, DeepValue, Validator } from '@tanstack/form-core'\n\ninterface ReactFieldApi<\n TParentData,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n> {\n /**\n * A pre-bound and type-safe sub-field component using this field as a root.\n */\n Field: FieldComponent<TParentData, TFormValidator>\n}\n\n/**\n * A type representing a hook for using a field in a form with the given form data type.\n *\n * A function that takes an optional object with a `name` property and field options, and returns a `FieldApi` instance for the specified field.\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\n/**\n * A hook for managing a field in a form.\n * @param opts An object with field options.\n *\n * @returns The `FieldApi` instance for the specified field.\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) {\n const [fieldApi] = useState(() => {\n const api = new FieldApi({\n ...opts,\n form: opts.form,\n name: opts.name,\n })\n\n const extendedApi: typeof api & ReactFieldApi<TParentData, TFormValidator> =\n api as never\n\n extendedApi.Field = Field as never\n\n return extendedApi\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\n}\n\n/**\n * @param children A render function that takes a field API instance and returns a React element.\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 ) => NodeType\n} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>\n\n/**\n * A type alias representing a field component for a specific form data type.\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>) => NodeType\n\n/**\n * A function component that takes field options and a render function as children and returns a React component.\n *\n * The `Field` component uses the `useField` hook internally to manage the field instance.\n */\nexport const 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}: FieldComponentProps<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n>): NodeType => {\n const fieldApi = useField(fieldOptions as any)\n\n return (<>{functionalUpdate(children, fieldApi as any)}</>) as never\n}) satisfies FunctionComponent<FieldComponentProps<any, any, any, any, any>>\n"],"names":[],"mappings":";;;;;AAgDO,SAAS,SAWd,MAOA;AACA,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,UAAM,cACJ;AAEF,gBAAY,QAAQ;AAEb,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,SAAS,CAAA,CAAE,EAAE,MAAM;AAAA,IAE3D,IAAA;AAAA,EAAA;AAGC,SAAA;AACT;AA4DO,MAAM,QAAS,CAUpB;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAMgB;AACR,QAAA,WAAW,SAAS,YAAmB;AAE7C,SAAW,oBAAA,UAAA,EAAA,UAAA,iBAAiB,UAAU,QAAe,EAAE,CAAA;AACzD;"}
@@ -3,46 +3,45 @@ import { FieldComponent, UseField } from './useField.js';
3
3
  import { NoInfer } from '@tanstack/react-store';
4
4
  import { NodeType } from './types.js';
5
5
 
6
- declare module '@tanstack/form-core' {
6
+ /**
7
+ * Fields that are added onto the `FormAPI` from `@tanstack/form-core` and returned from `useForm`
8
+ */
9
+ interface ReactFormApi<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> {
7
10
  /**
8
- * When using `@tanstack/react-form`, the core form API is extended at type level with additional methods for React-specific functionality:
11
+ * A React component to render form fields. With this, you can render and manage individual form fields.
9
12
  */
10
- interface FormApi<TFormData, TFormValidator> {
11
- /**
12
- * A React component to render form fields. With this, you can render and manage individual form fields.
13
- */
14
- Field: FieldComponent<TFormData, TFormValidator>;
15
- /**
16
- * A custom React hook that provides functionalities related to individual form fields. It gives you access to field values, errors, and allows you to set or update field values.
17
- */
18
- useField: UseField<TFormData, TFormValidator>;
19
- /**
20
- * A `useStore` hook that connects to the internal store of the form. It can be used to access the form's current state or any other related state information. You can optionally pass in a selector function to cherry-pick specific parts of the state
21
- */
22
- useStore: <TSelected = NoInfer<FormState<TFormData>>>(selector?: (state: NoInfer<FormState<TFormData>>) => TSelected) => TSelected;
13
+ Field: FieldComponent<TFormData, TFormValidator>;
14
+ /**
15
+ * A custom React hook that provides functionalities related to individual form fields. It gives you access to field values, errors, and allows you to set or update field values.
16
+ */
17
+ useField: UseField<TFormData, TFormValidator>;
18
+ /**
19
+ * A `useStore` hook that connects to the internal store of the form. It can be used to access the form's current state or any other related state information. You can optionally pass in a selector function to cherry-pick specific parts of the state
20
+ */
21
+ useStore: <TSelected = NoInfer<FormState<TFormData>>>(selector?: (state: NoInfer<FormState<TFormData>>) => TSelected) => TSelected;
22
+ /**
23
+ * A `Subscribe` function that allows you to listen and react to changes in the form's state. It's especially useful when you need to execute side effects or render specific components in response to state updates.
24
+ */
25
+ Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
23
26
  /**
24
- * A `Subscribe` function that allows you to listen and react to changes in the form's state. It's especially useful when you need to execute side effects or render specific components in response to state updates.
25
- */
26
- Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
27
- /**
28
- TypeScript versions <=5.0.4 have a bug that prevents
29
- the type of the `TSelected` generic from being inferred
30
- from the return type of this method.
31
-
32
- In these versions, `TSelected` will fall back to the default
33
- type (or `unknown` if that's not defined).
34
-
35
- @see {@link https://github.com/TanStack/form/pull/606/files#r1506715714 | This discussion on GitHub for the details}
36
- @see {@link https://github.com/microsoft/TypeScript/issues/52786 | The bug report in `microsoft/TypeScript`}
37
- */
38
- selector?: (state: NoInfer<FormState<TFormData>>) => TSelected;
39
- children: ((state: NoInfer<TSelected>) => NodeType) | NodeType;
40
- }) => NodeType;
41
- }
27
+ TypeScript versions <=5.0.4 have a bug that prevents
28
+ the type of the `TSelected` generic from being inferred
29
+ from the return type of this method.
30
+
31
+ In these versions, `TSelected` will fall back to the default
32
+ type (or `unknown` if that's not defined).
33
+
34
+ @see {@link https://github.com/TanStack/form/pull/606/files#r1506715714 | This discussion on GitHub for the details}
35
+ @see {@link https://github.com/microsoft/TypeScript/issues/52786 | The bug report in `microsoft/TypeScript`}
36
+ */
37
+ selector?: (state: NoInfer<FormState<TFormData>>) => TSelected;
38
+ children: ((state: NoInfer<TSelected>) => NodeType) | NodeType;
39
+ }) => NodeType;
42
40
  }
43
41
  /**
44
- * A custom React Hook that returns an instance of the `FormApi` class.
42
+ * A custom React Hook that returns an extended instance of the `FormApi` class.
45
43
  *
46
44
  * This API encapsulates all the necessary functionalities related to the form. It allows you to manage form state, handle submissions, and interact with form fields
47
45
  */
48
- export declare function useForm<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(opts?: FormOptions<TFormData, TFormValidator>): FormApi<TFormData, TFormValidator>;
46
+ export declare function useForm<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(opts?: FormOptions<TFormData, TFormValidator>): FormApi<TFormData, TFormValidator> & ReactFormApi<TFormData, TFormValidator>;
47
+ export {};
@@ -7,21 +7,22 @@ import { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect.js";
7
7
  function useForm(opts) {
8
8
  const [formApi] = useState(() => {
9
9
  const api = new FormApi(opts);
10
- api.Field = function APIField(props) {
10
+ const extendedApi = api;
11
+ extendedApi.Field = function APIField(props) {
11
12
  return /* @__PURE__ */ jsx(Field, { ...props, form: api });
12
13
  };
13
- api.useField = (props) => useField({ ...props, form: api });
14
- api.useStore = (selector) => {
14
+ extendedApi.useField = (props) => useField({ ...props, form: api });
15
+ extendedApi.useStore = (selector) => {
15
16
  return useStore(api.store, selector);
16
17
  };
17
- api.Subscribe = (props) => {
18
+ extendedApi.Subscribe = (props) => {
18
19
  return functionalUpdate(
19
20
  props.children,
20
21
  // eslint-disable-next-line react-hooks/rules-of-hooks
21
22
  useStore(api.store, props.selector)
22
23
  );
23
24
  };
24
- return api;
25
+ return extendedApi;
25
26
  });
26
27
  useIsomorphicLayoutEffect(formApi.mount, []);
27
28
  formApi.useStore((state) => state.isSubmitting);
@@ -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, { useState } from 'react'\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'\nimport type { NodeType } from './types'\n\ndeclare module '@tanstack/form-core' {\n /**\n * When using `@tanstack/react-form`, the core form API is extended at type level with additional methods for React-specific functionality:\n */\n // eslint-disable-next-line no-shadow\n interface FormApi<TFormData, TFormValidator> {\n /**\n * A React component to render form fields. With this, you can render and manage individual form fields.\n */\n Field: FieldComponent<TFormData, TFormValidator>\n /**\n * A custom React hook that provides functionalities related to individual form fields. It gives you access to field values, errors, and allows you to set or update field values.\n */\n useField: UseField<TFormData, TFormValidator>\n /**\n * A `useStore` hook that connects to the internal store of the form. It can be used to access the form's current state or any other related state information. You can optionally pass in a selector function to cherry-pick specific parts of the state\n */\n useStore: <TSelected = NoInfer<FormState<TFormData>>>(\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,\n ) => TSelected\n /**\n * A `Subscribe` function that allows you to listen and react to changes in the form's state. It's especially useful when you need to execute side effects or render specific components in response to state updates.\n */\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>) => NodeType) | NodeType\n }) => NodeType\n }\n}\n\n/**\n * A custom React Hook that returns an instance of the `FormApi` class.\n *\n * This API encapsulates all the necessary functionalities related to the form. It allows you to manage form state, handle submissions, and interact with form fields\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} />) as never\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":";;;;;;AAuDO,SAAS,QAId,MACoC;AACpC,QAAM,CAAC,OAAO,IAAI,SAAS,MAAM;AACzB,UAAA,MAAM,IAAI,QAAmC,IAAI;AACnD,QAAA,QAAQ,SAAS,SAAS,OAAO;AACnC,aAAS,oBAAA,OAAA,EAAO,GAAG,OAAO,MAAM,IAAK,CAAA;AAAA,IAAA;AAGnC,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, { useState } from 'react'\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'\nimport type { NodeType } from './types'\n\n/**\n * Fields that are added onto the `FormAPI` from `@tanstack/form-core` and returned from `useForm`\n */\ninterface ReactFormApi<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n /**\n * A React component to render form fields. With this, you can render and manage individual form fields.\n */\n Field: FieldComponent<TFormData, TFormValidator>\n /**\n * A custom React hook that provides functionalities related to individual form fields. It gives you access to field values, errors, and allows you to set or update field values.\n */\n useField: UseField<TFormData, TFormValidator>\n /**\n * A `useStore` hook that connects to the internal store of the form. It can be used to access the form's current state or any other related state information. You can optionally pass in a selector function to cherry-pick specific parts of the state\n */\n useStore: <TSelected = NoInfer<FormState<TFormData>>>(\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,\n ) => TSelected\n /**\n * A `Subscribe` function that allows you to listen and react to changes in the form's state. It's especially useful when you need to execute side effects or render specific components in response to state updates.\n */\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>) => NodeType) | NodeType\n }) => NodeType\n}\n\n/**\n * A custom React Hook that returns an extended instance of the `FormApi` class.\n *\n * This API encapsulates all the necessary functionalities related to the form. It allows you to manage form state, handle submissions, and interact with form fields\n */\nexport function useForm<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(opts?: FormOptions<TFormData, TFormValidator>) {\n const [formApi] = useState(() => {\n const api = new FormApi<TFormData, TFormValidator>(opts)\n\n const extendedApi: typeof api & ReactFormApi<TFormData, TFormValidator> =\n api as never\n extendedApi.Field = function APIField(props) {\n return (<Field {...props} form={api} />) as never\n }\n // eslint-disable-next-line react-hooks/rules-of-hooks\n extendedApi.useField = (props) => useField({ ...props, form: api })\n extendedApi.useStore = (selector) => {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useStore(api.store as any, selector as any) as any\n }\n extendedApi.Subscribe = (props) => {\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 extendedApi\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\n}\n"],"names":[],"mappings":";;;;;;AAuDO,SAAS,QAGd,MAA+C;AAC/C,QAAM,CAAC,OAAO,IAAI,SAAS,MAAM;AACzB,UAAA,MAAM,IAAI,QAAmC,IAAI;AAEvD,UAAM,cACJ;AACU,gBAAA,QAAQ,SAAS,SAAS,OAAO;AAC3C,aAAS,oBAAA,OAAA,EAAO,GAAG,OAAO,MAAM,IAAK,CAAA;AAAA,IAAA;AAG3B,gBAAA,WAAW,CAAC,UAAU,SAAS,EAAE,GAAG,OAAO,MAAM,IAAA,CAAK;AACtD,gBAAA,WAAW,CAAC,aAAa;AAE5B,aAAA,SAAS,IAAI,OAAc,QAAe;AAAA,IAAA;AAEvC,gBAAA,YAAY,CAAC,UAAU;AAC1B,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,8 +1,5 @@
1
1
  import { useLayoutEffect, useEffect } from "react";
2
- const useIsomorphicLayoutEffect = (
3
- // @ts-ignore
4
- typeof window !== "undefined" ? useLayoutEffect : useEffect
5
- );
2
+ const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
6
3
  export {
7
4
  useIsomorphicLayoutEffect
8
5
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useIsomorphicLayoutEffect.js","sources":["../../src/useIsomorphicLayoutEffect.ts"],"sourcesContent":["import { useEffect, useLayoutEffect } from 'react'\n\nexport const useIsomorphicLayoutEffect =\n // @ts-ignore\n typeof window !== 'undefined' ? useLayoutEffect : useEffect\n"],"names":[],"mappings":";AAEa,MAAA;AAAA;AAAA,EAEX,OAAO,WAAW,cAAc,kBAAkB;AAAA;"}
1
+ {"version":3,"file":"useIsomorphicLayoutEffect.js","sources":["../../src/useIsomorphicLayoutEffect.ts"],"sourcesContent":["import { useEffect, useLayoutEffect } from 'react'\n\nexport const useIsomorphicLayoutEffect =\n typeof window !== 'undefined' ? useLayoutEffect : useEffect\n"],"names":[],"mappings":";AAEO,MAAM,4BACX,OAAO,WAAW,cAAc,kBAAkB;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/react-form",
3
- "version": "0.24.2",
3
+ "version": "0.24.3",
4
4
  "description": "Powerful, type-safe forms for React.",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
@@ -57,7 +57,7 @@
57
57
  "dependencies": {
58
58
  "@tanstack/react-store": "^0.5.0",
59
59
  "decode-formdata": "^0.7.5",
60
- "@tanstack/form-core": "0.24.2"
60
+ "@tanstack/form-core": "0.24.3"
61
61
  },
62
62
  "peerDependencies": {
63
63
  "react": "^17.0.0 || ^18.0.0"
@@ -17,16 +17,11 @@ type OnServerValidateOrFn<
17
17
  ? FFN | OnServerValidateFn<TFormData>
18
18
  : OnServerValidateFn<TFormData>
19
19
 
20
- declare module '@tanstack/form-core' {
21
- // eslint-disable-next-line no-shadow
22
- interface FormOptions<
23
- TFormData,
24
- TFormValidator extends
25
- | Validator<TFormData, unknown>
26
- | undefined = undefined,
27
- > {
28
- onServerValidate?: OnServerValidateOrFn<TFormData, TFormValidator>
29
- }
20
+ interface ServerFormOptions<
21
+ TFormData,
22
+ TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
23
+ > extends FormOptions<TFormData, TFormValidator> {
24
+ onServerValidate?: OnServerValidateOrFn<TFormData, TFormValidator>
30
25
  }
31
26
 
32
27
  type ValidateFormData<
@@ -41,13 +36,13 @@ export const createServerValidate = <
41
36
  TFormData,
42
37
  TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
43
38
  >(
44
- defaultOpts?: FormOptions<TFormData, TFormValidator>,
39
+ defaultOpts: ServerFormOptions<TFormData, TFormValidator>,
45
40
  ) =>
46
41
  (async (
47
42
  formData: FormData,
48
43
  info?: Parameters<typeof decode>[1],
49
44
  ): Promise<Partial<FormApi<TFormData, TFormValidator>['state']>> => {
50
- const { validatorAdapter, onServerValidate } = defaultOpts || {}
45
+ const { validatorAdapter, onServerValidate } = defaultOpts
51
46
 
52
47
  const runValidator = (propsValue: { value: TFormData }) => {
53
48
  if (validatorAdapter && typeof onServerValidate !== 'function') {
package/src/useField.tsx CHANGED
@@ -5,27 +5,16 @@ import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'
5
5
  import type { NodeType, UseFieldOptions } from './types'
6
6
  import type { DeepKeys, DeepValue, Validator } from '@tanstack/form-core'
7
7
 
8
- declare module '@tanstack/form-core' {
8
+ interface ReactFieldApi<
9
+ TParentData,
10
+ TFormValidator extends
11
+ | Validator<TParentData, unknown>
12
+ | undefined = undefined,
13
+ > {
9
14
  /**
10
- * When using `@tanstack/react-form`, the core field API is extended at type level with additional methods for React-specific functionality:
15
+ * A pre-bound and type-safe sub-field component using this field as a root.
11
16
  */
12
- // eslint-disable-next-line no-shadow
13
- interface FieldApi<
14
- TParentData,
15
- TName extends DeepKeys<TParentData>,
16
- TFieldValidator extends
17
- | Validator<DeepValue<TParentData, TName>, unknown>
18
- | undefined = undefined,
19
- TFormValidator extends
20
- | Validator<TParentData, unknown>
21
- | undefined = undefined,
22
- TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
23
- > {
24
- /**
25
- * A pre-bound and type-safe sub-field component using this field as a root.
26
- */
27
- Field: FieldComponent<TParentData, TFormValidator>
28
- }
17
+ Field: FieldComponent<TParentData, TFormValidator>
29
18
  }
30
19
 
31
20
  /**
@@ -75,7 +64,7 @@ export function useField<
75
64
  TFormValidator,
76
65
  TData
77
66
  >,
78
- ): FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData> {
67
+ ) {
79
68
  const [fieldApi] = useState(() => {
80
69
  const api = new FieldApi({
81
70
  ...opts,
@@ -83,9 +72,12 @@ export function useField<
83
72
  name: opts.name,
84
73
  })
85
74
 
86
- api.Field = Field as never
75
+ const extendedApi: typeof api & ReactFieldApi<TParentData, TFormValidator> =
76
+ api as never
77
+
78
+ extendedApi.Field = Field as never
87
79
 
88
- return api
80
+ return extendedApi
89
81
  })
90
82
 
91
83
  useIsomorphicLayoutEffect(fieldApi.mount, [fieldApi])
@@ -107,7 +99,7 @@ export function useField<
107
99
  : undefined,
108
100
  )
109
101
 
110
- return fieldApi as never
102
+ return fieldApi
111
103
  }
112
104
 
113
105
  /**
package/src/useForm.tsx CHANGED
@@ -7,31 +7,32 @@ import type { NoInfer } from '@tanstack/react-store'
7
7
  import type { FormOptions, FormState, Validator } from '@tanstack/form-core'
8
8
  import type { NodeType } from './types'
9
9
 
10
- declare module '@tanstack/form-core' {
10
+ /**
11
+ * Fields that are added onto the `FormAPI` from `@tanstack/form-core` and returned from `useForm`
12
+ */
13
+ interface ReactFormApi<
14
+ TFormData,
15
+ TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
16
+ > {
11
17
  /**
12
- * When using `@tanstack/react-form`, the core form API is extended at type level with additional methods for React-specific functionality:
18
+ * A React component to render form fields. With this, you can render and manage individual form fields.
13
19
  */
14
- // eslint-disable-next-line no-shadow
15
- interface FormApi<TFormData, TFormValidator> {
16
- /**
17
- * A React component to render form fields. With this, you can render and manage individual form fields.
18
- */
19
- Field: FieldComponent<TFormData, TFormValidator>
20
- /**
21
- * A custom React hook that provides functionalities related to individual form fields. It gives you access to field values, errors, and allows you to set or update field values.
22
- */
23
- useField: UseField<TFormData, TFormValidator>
24
- /**
25
- * A `useStore` hook that connects to the internal store of the form. It can be used to access the form's current state or any other related state information. You can optionally pass in a selector function to cherry-pick specific parts of the state
26
- */
27
- useStore: <TSelected = NoInfer<FormState<TFormData>>>(
28
- selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,
29
- ) => TSelected
20
+ Field: FieldComponent<TFormData, TFormValidator>
21
+ /**
22
+ * A custom React hook that provides functionalities related to individual form fields. It gives you access to field values, errors, and allows you to set or update field values.
23
+ */
24
+ useField: UseField<TFormData, TFormValidator>
25
+ /**
26
+ * A `useStore` hook that connects to the internal store of the form. It can be used to access the form's current state or any other related state information. You can optionally pass in a selector function to cherry-pick specific parts of the state
27
+ */
28
+ useStore: <TSelected = NoInfer<FormState<TFormData>>>(
29
+ selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,
30
+ ) => TSelected
31
+ /**
32
+ * A `Subscribe` function that allows you to listen and react to changes in the form's state. It's especially useful when you need to execute side effects or render specific components in response to state updates.
33
+ */
34
+ Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
30
35
  /**
31
- * A `Subscribe` function that allows you to listen and react to changes in the form's state. It's especially useful when you need to execute side effects or render specific components in response to state updates.
32
- */
33
- Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
34
- /**
35
36
  TypeScript versions <=5.0.4 have a bug that prevents
36
37
  the type of the `TSelected` generic from being inferred
37
38
  from the return type of this method.
@@ -42,41 +43,35 @@ declare module '@tanstack/form-core' {
42
43
  @see {@link https://github.com/TanStack/form/pull/606/files#r1506715714 | This discussion on GitHub for the details}
43
44
  @see {@link https://github.com/microsoft/TypeScript/issues/52786 | The bug report in `microsoft/TypeScript`}
44
45
  */
45
- selector?: (state: NoInfer<FormState<TFormData>>) => TSelected
46
- children: ((state: NoInfer<TSelected>) => NodeType) | NodeType
47
- }) => NodeType
48
- }
46
+ selector?: (state: NoInfer<FormState<TFormData>>) => TSelected
47
+ children: ((state: NoInfer<TSelected>) => NodeType) | NodeType
48
+ }) => NodeType
49
49
  }
50
50
 
51
51
  /**
52
- * A custom React Hook that returns an instance of the `FormApi` class.
52
+ * A custom React Hook that returns an extended instance of the `FormApi` class.
53
53
  *
54
54
  * This API encapsulates all the necessary functionalities related to the form. It allows you to manage form state, handle submissions, and interact with form fields
55
55
  */
56
56
  export function useForm<
57
57
  TFormData,
58
58
  TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
59
- >(
60
- opts?: FormOptions<TFormData, TFormValidator>,
61
- ): FormApi<TFormData, TFormValidator> {
59
+ >(opts?: FormOptions<TFormData, TFormValidator>) {
62
60
  const [formApi] = useState(() => {
63
61
  const api = new FormApi<TFormData, TFormValidator>(opts)
64
- api.Field = function APIField(props) {
62
+
63
+ const extendedApi: typeof api & ReactFormApi<TFormData, TFormValidator> =
64
+ api as never
65
+ extendedApi.Field = function APIField(props) {
65
66
  return (<Field {...props} form={api} />) as never
66
67
  }
67
68
  // eslint-disable-next-line react-hooks/rules-of-hooks
68
- api.useField = (props) => useField({ ...props, form: api })
69
- api.useStore = (
70
- // @ts-ignore
71
- selector,
72
- ) => {
69
+ extendedApi.useField = (props) => useField({ ...props, form: api })
70
+ extendedApi.useStore = (selector) => {
73
71
  // eslint-disable-next-line react-hooks/rules-of-hooks
74
72
  return useStore(api.store as any, selector as any) as any
75
73
  }
76
- api.Subscribe = (
77
- // @ts-ignore
78
- props,
79
- ) => {
74
+ extendedApi.Subscribe = (props) => {
80
75
  return functionalUpdate(
81
76
  props.children,
82
77
  // eslint-disable-next-line react-hooks/rules-of-hooks
@@ -84,7 +79,7 @@ export function useForm<
84
79
  ) as any
85
80
  }
86
81
 
87
- return api
82
+ return extendedApi
88
83
  })
89
84
 
90
85
  useIsomorphicLayoutEffect(formApi.mount, [])
@@ -99,5 +94,5 @@ export function useForm<
99
94
  formApi.update(opts)
100
95
  })
101
96
 
102
- return formApi as any
97
+ return formApi
103
98
  }
@@ -1,5 +1,4 @@
1
1
  import { useEffect, useLayoutEffect } from 'react'
2
2
 
3
3
  export const useIsomorphicLayoutEffect =
4
- // @ts-ignore
5
4
  typeof window !== 'undefined' ? useLayoutEffect : useEffect