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