@tanstack/vue-form 0.10.3 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/dist/cjs/createFormFactory.d.ts +8 -0
  2. package/dist/cjs/formContext.d.ts +11 -0
  3. package/dist/cjs/index.cjs +119 -0
  4. package/dist/cjs/index.cjs.map +1 -0
  5. package/dist/cjs/index.d.cts +5 -0
  6. package/dist/cjs/index.d.ts +5 -0
  7. package/dist/cjs/index.js +119 -0
  8. package/dist/cjs/tests/useField.test.d.ts +1 -0
  9. package/dist/cjs/tests/useForm.test.d.ts +1 -0
  10. package/dist/cjs/tests/utils.d.ts +1 -0
  11. package/dist/cjs/types.d.ts +4 -0
  12. package/dist/cjs/useField.d.ts +38 -0
  13. package/dist/cjs/useForm.d.ts +19 -0
  14. package/dist/mjs/createFormFactory.d.ts +8 -0
  15. package/dist/mjs/formContext.d.ts +11 -0
  16. package/dist/mjs/index.d.mts +5 -0
  17. package/dist/mjs/index.d.ts +5 -0
  18. package/dist/mjs/index.js +113 -0
  19. package/dist/mjs/index.mjs +113 -0
  20. package/dist/mjs/index.mjs.map +1 -0
  21. package/dist/mjs/tests/useField.test.d.ts +1 -0
  22. package/dist/mjs/tests/useForm.test.d.ts +1 -0
  23. package/dist/mjs/tests/utils.d.ts +1 -0
  24. package/dist/mjs/types.d.ts +4 -0
  25. package/dist/mjs/useField.d.ts +38 -0
  26. package/dist/mjs/useForm.d.ts +19 -0
  27. package/package.json +17 -22
  28. package/src/createFormFactory.ts +16 -10
  29. package/src/formContext.ts +10 -4
  30. package/src/tests/useField.test.tsx +23 -15
  31. package/src/tests/useForm.test.tsx +57 -39
  32. package/src/types.ts +13 -4
  33. package/src/useField.tsx +68 -35
  34. package/src/useForm.tsx +16 -8
  35. package/build/legacy/createFormFactory.cjs +0 -42
  36. package/build/legacy/createFormFactory.cjs.map +0 -1
  37. package/build/legacy/createFormFactory.d.cts +0 -13
  38. package/build/legacy/createFormFactory.d.ts +0 -13
  39. package/build/legacy/createFormFactory.js +0 -17
  40. package/build/legacy/createFormFactory.js.map +0 -1
  41. package/build/legacy/formContext.cjs +0 -46
  42. package/build/legacy/formContext.cjs.map +0 -1
  43. package/build/legacy/formContext.d.cts +0 -14
  44. package/build/legacy/formContext.d.ts +0 -14
  45. package/build/legacy/formContext.js +0 -19
  46. package/build/legacy/formContext.js.map +0 -1
  47. package/build/legacy/index.cjs +0 -33
  48. package/build/legacy/index.cjs.map +0 -1
  49. package/build/legacy/index.d.cts +0 -8
  50. package/build/legacy/index.d.ts +0 -8
  51. package/build/legacy/index.js +0 -7
  52. package/build/legacy/index.js.map +0 -1
  53. package/build/legacy/types.cjs +0 -19
  54. package/build/legacy/types.cjs.map +0 -1
  55. package/build/legacy/types.d.cts +0 -7
  56. package/build/legacy/types.d.ts +0 -7
  57. package/build/legacy/types.js +0 -1
  58. package/build/legacy/types.js.map +0 -1
  59. package/build/legacy/useField.cjs +0 -77
  60. package/build/legacy/useField.cjs.map +0 -1
  61. package/build/legacy/useField.d.cts +0 -40
  62. package/build/legacy/useField.d.ts +0 -40
  63. package/build/legacy/useField.js +0 -51
  64. package/build/legacy/useField.js.map +0 -1
  65. package/build/legacy/useForm.cjs +0 -72
  66. package/build/legacy/useForm.cjs.map +0 -1
  67. package/build/legacy/useForm.d.cts +0 -23
  68. package/build/legacy/useForm.d.ts +0 -23
  69. package/build/legacy/useForm.js +0 -50
  70. package/build/legacy/useForm.js.map +0 -1
  71. package/build/modern/createFormFactory.cjs +0 -42
  72. package/build/modern/createFormFactory.cjs.map +0 -1
  73. package/build/modern/createFormFactory.d.cts +0 -13
  74. package/build/modern/createFormFactory.d.ts +0 -13
  75. package/build/modern/createFormFactory.js +0 -17
  76. package/build/modern/createFormFactory.js.map +0 -1
  77. package/build/modern/formContext.cjs +0 -46
  78. package/build/modern/formContext.cjs.map +0 -1
  79. package/build/modern/formContext.d.cts +0 -14
  80. package/build/modern/formContext.d.ts +0 -14
  81. package/build/modern/formContext.js +0 -19
  82. package/build/modern/formContext.js.map +0 -1
  83. package/build/modern/index.cjs +0 -33
  84. package/build/modern/index.cjs.map +0 -1
  85. package/build/modern/index.d.cts +0 -8
  86. package/build/modern/index.d.ts +0 -8
  87. package/build/modern/index.js +0 -7
  88. package/build/modern/index.js.map +0 -1
  89. package/build/modern/types.cjs +0 -19
  90. package/build/modern/types.cjs.map +0 -1
  91. package/build/modern/types.d.cts +0 -7
  92. package/build/modern/types.d.ts +0 -7
  93. package/build/modern/types.js +0 -1
  94. package/build/modern/types.js.map +0 -1
  95. package/build/modern/useField.cjs +0 -77
  96. package/build/modern/useField.cjs.map +0 -1
  97. package/build/modern/useField.d.cts +0 -40
  98. package/build/modern/useField.d.ts +0 -40
  99. package/build/modern/useField.js +0 -51
  100. package/build/modern/useField.js.map +0 -1
  101. package/build/modern/useForm.cjs +0 -72
  102. package/build/modern/useForm.cjs.map +0 -1
  103. package/build/modern/useForm.d.cts +0 -23
  104. package/build/modern/useForm.d.ts +0 -23
  105. package/build/modern/useForm.js +0 -50
  106. package/build/modern/useForm.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sources":["../../src/formContext.ts","../../src/useField.tsx","../../src/useForm.tsx","../../src/createFormFactory.ts"],"sourcesContent":["import type { FormApi, Validator } from '@tanstack/form-core'\nimport { inject, provide } from 'vue'\n\nexport type FormContext<\n TFormData = any,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = {\n formApi: FormApi<TFormData, TFormValidator>\n parentFieldName?: string\n} | null\n\nexport const formContext = Symbol('FormContext')\n\nexport function provideFormContext<\n TFormData = any,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(val: FormContext<TFormData, TFormValidator>) {\n provide(formContext, val)\n}\n\nexport function useFormContext() {\n const formApi = inject(formContext) as FormContext\n\n if (!formApi) {\n throw new Error(`You are trying to use the form API outside of a form!`)\n }\n\n return formApi\n}\n","import { FieldApi, type Validator } from '@tanstack/form-core'\nimport type { DeepKeys, DeepValue, Narrow } from '@tanstack/form-core'\nimport { useStore } from '@tanstack/vue-store'\nimport { defineComponent, onMounted, onUnmounted, watch } from 'vue'\nimport type { SlotsType, SetupContext, Ref } from 'vue'\nimport { provideFormContext, useFormContext } from './formContext'\nimport type { UseFieldOptions } from './types'\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 = DeepValue<TParentData, TName>,\n > {\n Field: FieldComponent<TParentData, TFormValidator>\n }\n}\n\nexport type UseField<\n TParentData,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n> = <\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n>(\n opts?: { name: Narrow<TName> } & UseFieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n DeepValue<TParentData, TName>\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 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 api: FieldApi<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n // Omit<typeof opts, 'onMount'> & {\n // form: FormApi<TParentData>\n // }\n >\n state: Readonly<\n Ref<\n FieldApi<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >['state']\n >\n >\n} {\n // Get the form API either manually or from context\n const { formApi, parentFieldName } = useFormContext()\n\n const fieldApi = (() => {\n const api = new FieldApi({\n ...opts,\n form: formApi,\n name: opts.name,\n } as never)\n\n api.Field = Field as never\n\n return api\n })()\n\n const fieldState = useStore(fieldApi.store, (state) => state)\n\n let cleanup!: () => void\n onMounted(() => {\n cleanup = fieldApi.mount()\n })\n\n onUnmounted(() => {\n cleanup()\n })\n\n watch(\n () => opts,\n () => {\n // Keep options up to date as they are rendered\n fieldApi.update({ ...opts, form: formApi } as never)\n },\n )\n\n return { api: fieldApi, state: fieldState } as never\n}\n\nexport type FieldValue<TParentData, TName> = TParentData extends any[]\n ? unknown extends TName\n ? TParentData[number]\n : DeepValue<TParentData[number], TName>\n : DeepValue<TParentData, TName>\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> = (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 fieldOptions: FieldComponentProps<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator\n >,\n context: SetupContext<\n {},\n SlotsType<{\n default: {\n field: FieldApi<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n state: FieldApi<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >['state']\n }\n }>\n >,\n) => any\n\nexport const Field = defineComponent(\n <\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 fieldOptions: UseFieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator\n >,\n context: SetupContext,\n ) => {\n const fieldApi = useField({ ...fieldOptions, ...context.attrs } as any)\n\n provideFormContext({\n formApi: fieldApi.api.form,\n parentFieldName: fieldApi.api.name,\n } as never)\n\n return () =>\n context.slots.default!({\n field: fieldApi.api,\n state: fieldApi.state.value,\n })\n },\n { name: 'Field', inheritAttrs: false },\n)\n","import {\n FormApi,\n type FormState,\n type FormOptions,\n type Validator,\n} from '@tanstack/form-core'\nimport { type NoInfer, useStore } from '@tanstack/vue-store'\nimport { type UseField, type FieldComponent, Field, useField } from './useField'\nimport { provideFormContext } from './formContext'\nimport {\n type EmitsOptions,\n type SlotsType,\n type SetupContext,\n type Ref,\n defineComponent,\n onMounted,\n} from 'vue'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FormApi<TFormData, TFormValidator> {\n Provider: (props: Record<string, any> & {}) => any\n provideFormContext: () => void\n Field: FieldComponent<TFormData, TFormValidator>\n useField: UseField<TFormData, TFormValidator>\n useStore: <TSelected = NoInfer<FormState<TFormData>>>(\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,\n ) => Readonly<Ref<TSelected>>\n Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(\n props: {\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected\n },\n context: SetupContext<\n EmitsOptions,\n SlotsType<{ default: NoInfer<FormState<TFormData>> }>\n >,\n ) => any\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 = (() => {\n const api = new FormApi<TFormData, TFormValidator>(opts)\n\n api.Provider = defineComponent(\n (_, context) => {\n onMounted(api.mount)\n provideFormContext({ formApi: formApi as never })\n return () => context.slots.default!()\n },\n { name: 'Provider' },\n )\n api.provideFormContext = () => {\n onMounted(api.mount)\n provideFormContext({ formApi: formApi as never })\n }\n api.Field = Field as never\n api.useField = useField as never\n api.useStore = (selector) => {\n return useStore(api.store as never, selector as never) as never\n }\n api.Subscribe = defineComponent(\n (props, context) => {\n const allProps = { ...props, ...context.attrs }\n const selector = allProps.selector ?? ((state) => state)\n const data = useStore(api.store as never, selector as never)\n return () => context.slots.default!(data.value)\n },\n {\n name: 'Subscribe',\n inheritAttrs: false,\n },\n )\n\n return api\n })()\n\n // formApi.useStore((state) => state.isSubmitting)\n formApi.update(opts)\n\n return formApi as never\n}\n","import type { FormApi, FormOptions, Validator } from '@tanstack/form-core'\n\nimport { type UseField, type FieldComponent, Field, useField } from './useField'\nimport { useForm } from './useForm'\n\nexport type FormFactory<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = {\n useForm: (\n opts?: FormOptions<TFormData, TFormValidator>,\n ) => FormApi<TFormData, TFormValidator>\n useField: UseField<TFormData, TFormValidator>\n Field: FieldComponent<TFormData, TFormValidator>\n}\n\nexport function createFormFactory<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(\n defaultOpts?: FormOptions<TFormData, TFormValidator>,\n): FormFactory<TFormData, TFormValidator> {\n return {\n useForm: (opts) => {\n const formOptions = Object.assign({}, defaultOpts, opts)\n return useForm<TFormData, TFormValidator>(formOptions)\n },\n useField: useField as any,\n Field: Field as any,\n }\n}\n"],"names":[],"mappings":";;;;AAWa,MAAA,cAAc,OAAO,aAAa;AAExC,SAAS,mBAGd,KAA6C;AAC7C,UAAQ,aAAa,GAAG;AAC1B;AAEO,SAAS,iBAAiB;AACzB,QAAA,UAAU,OAAO,WAAW;AAElC,MAAI,CAAC,SAAS;AACN,UAAA,IAAI,MAAM,uDAAuD;AAAA,EACzE;AAEO,SAAA;AACT;ACuBO,SAAS,SAWd,MA6BA;AAEA,QAAM,EAAE,SAAS,gBAAgB,IAAI,eAAe;AAEpD,QAAM,YAAY,MAAM;AAChB,UAAA,MAAM,IAAI,SAAS;AAAA,MACvB,GAAG;AAAA,MACH,MAAM;AAAA,MACN,MAAM,KAAK;AAAA,IAAA,CACH;AAEV,QAAI,QAAQ;AAEL,WAAA;AAAA,EAAA;AAGT,QAAM,aAAa,SAAS,SAAS,OAAO,CAAC,UAAU,KAAK;AAExD,MAAA;AACJ,YAAU,MAAM;AACd,cAAU,SAAS;EAAM,CAC1B;AAED,cAAY,MAAM;AACR;EAAA,CACT;AAED;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAEJ,eAAS,OAAO,EAAE,GAAG,MAAM,MAAM,SAAkB;AAAA,IACrD;AAAA,EAAA;AAGF,SAAO,EAAE,KAAK,UAAU,OAAO,WAAW;AAC5C;AAwEO,MAAM,QAAQ;AAAA,EACnB,CAUE,cAMA,YACG;AACG,UAAA,WAAW,SAAS,EAAE,GAAG,cAAc,GAAG,QAAQ,OAAc;AAEnD,uBAAA;AAAA,MACjB,SAAS,SAAS,IAAI;AAAA,MACtB,iBAAiB,SAAS,IAAI;AAAA,IAAA,CACtB;AAEH,WAAA,MACL,QAAQ,MAAM,QAAS;AAAA,MACrB,OAAO,SAAS;AAAA,MAChB,OAAO,SAAS,MAAM;AAAA,IAAA,CACvB;AAAA,EACL;AAAA,EACA,EAAE,MAAM,SAAS,cAAc,MAAM;AACvC;AChMO,SAAS,QAId,MACoC;AACpC,QAAM,WAAW,MAAM;AACf,UAAA,MAAM,IAAI,QAAmC,IAAI;AAEvD,QAAI,WAAW;AAAA,MACb,CAAC,GAAG,YAAY;AACd,kBAAU,IAAI,KAAK;AACA,2BAAA,EAAE,SAA2B;AACzC,eAAA,MAAM,QAAQ,MAAM;MAC7B;AAAA,MACA,EAAE,MAAM,WAAW;AAAA,IAAA;AAErB,QAAI,qBAAqB,MAAM;AAC7B,gBAAU,IAAI,KAAK;AACA,yBAAA,EAAE,SAA2B;AAAA,IAAA;AAElD,QAAI,QAAQ;AACZ,QAAI,WAAW;AACX,QAAA,WAAW,CAAC,aAAa;AACpB,aAAA,SAAS,IAAI,OAAgB,QAAiB;AAAA,IAAA;AAEvD,QAAI,YAAY;AAAA,MACd,CAAC,OAAO,YAAY;AAClB,cAAM,WAAW,EAAE,GAAG,OAAO,GAAG,QAAQ,MAAM;AAC9C,cAAM,WAAW,SAAS,aAAa,CAAC,UAAU;AAClD,cAAM,OAAO,SAAS,IAAI,OAAgB,QAAiB;AAC3D,eAAO,MAAM,QAAQ,MAAM,QAAS,KAAK,KAAK;AAAA,MAChD;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,cAAc;AAAA,MAChB;AAAA,IAAA;AAGK,WAAA;AAAA,EAAA;AAIT,UAAQ,OAAO,IAAI;AAEZ,SAAA;AACT;ACtEO,SAAS,kBAId,aACwC;AACjC,SAAA;AAAA,IACL,SAAS,CAAC,SAAS;AACjB,YAAM,cAAc,OAAO,OAAO,CAAA,GAAI,aAAa,IAAI;AACvD,aAAO,QAAmC,WAAW;AAAA,IACvD;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;"}
@@ -0,0 +1 @@
1
+ /// <reference lib="dom" />
@@ -0,0 +1 @@
1
+ /// <reference lib="dom" />
@@ -0,0 +1 @@
1
+ export declare function sleep(timeout: number): Promise<void>;
@@ -0,0 +1,4 @@
1
+ import type { FieldOptions, DeepKeys, DeepValue, Validator } from '@tanstack/form-core';
2
+ export type UseFieldOptions<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>> = FieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData> & {
3
+ mode?: 'value' | 'array';
4
+ };
@@ -0,0 +1,38 @@
1
+ import { FieldApi, type Validator } from '@tanstack/form-core';
2
+ import type { DeepKeys, DeepValue, Narrow } from '@tanstack/form-core';
3
+ import type { SlotsType, SetupContext, Ref } from 'vue';
4
+ import type { UseFieldOptions } from './types';
5
+ declare module '@tanstack/form-core' {
6
+ interface FieldApi<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData = DeepValue<TParentData, TName>> {
7
+ Field: FieldComponent<TParentData, TFormValidator>;
8
+ }
9
+ }
10
+ export type UseField<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined>(opts?: {
11
+ name: Narrow<TName>;
12
+ } & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, DeepValue<TParentData, TName>>) => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, DeepValue<TParentData, TName>>;
13
+ 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>): {
14
+ api: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>;
15
+ state: Readonly<Ref<FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>['state']>>;
16
+ };
17
+ export type FieldValue<TParentData, TName> = TParentData extends any[] ? unknown extends TName ? TParentData[number] : DeepValue<TParentData[number], TName> : DeepValue<TParentData, TName>;
18
+ type FieldComponentProps<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined> = (TParentData extends any[] ? {
19
+ name?: TName;
20
+ index: number;
21
+ } : {
22
+ name: TName;
23
+ index?: never;
24
+ }) & Omit<UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>, 'name' | 'index'>;
25
+ export type FieldComponent<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>>(fieldOptions: FieldComponentProps<TParentData, TName, TFieldValidator, TFormValidator>, context: SetupContext<{}, SlotsType<{
26
+ default: {
27
+ field: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>;
28
+ state: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>['state'];
29
+ };
30
+ }>>) => any;
31
+ export declare const Field: <TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>(props: import("@tanstack/form-core").FieldOptions<TParentData, TName, TFieldValidator, TFormValidator, DeepValue<TParentData, TName>> & {
32
+ mode?: "value" | "array" | undefined;
33
+ } & ({
34
+ [x: `on${Capitalize<string>}`]: ((...args: never) => any) | undefined;
35
+ } | {
36
+ [x: `on${Capitalize<string>}`]: ((...args: any[]) => any) | undefined;
37
+ })) => any;
38
+ export {};
@@ -0,0 +1,19 @@
1
+ import { FormApi, type FormState, type FormOptions, type Validator } from '@tanstack/form-core';
2
+ import { type NoInfer } from '@tanstack/vue-store';
3
+ import { type UseField, type FieldComponent } from './useField';
4
+ import { type EmitsOptions, type SlotsType, type SetupContext, type Ref } from 'vue';
5
+ declare module '@tanstack/form-core' {
6
+ interface FormApi<TFormData, TFormValidator> {
7
+ Provider: (props: Record<string, any> & {}) => any;
8
+ provideFormContext: () => void;
9
+ Field: FieldComponent<TFormData, TFormValidator>;
10
+ useField: UseField<TFormData, TFormValidator>;
11
+ useStore: <TSelected = NoInfer<FormState<TFormData>>>(selector?: (state: NoInfer<FormState<TFormData>>) => TSelected) => Readonly<Ref<TSelected>>;
12
+ Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
13
+ selector?: (state: NoInfer<FormState<TFormData>>) => TSelected;
14
+ }, context: SetupContext<EmitsOptions, SlotsType<{
15
+ default: NoInfer<FormState<TFormData>>;
16
+ }>>) => any;
17
+ }
18
+ }
19
+ export declare function useForm<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(opts?: FormOptions<TFormData, TFormValidator>): FormApi<TFormData, TFormValidator>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/vue-form",
3
- "version": "0.10.3",
3
+ "version": "0.12.0",
4
4
  "description": "Powerful, type-safe forms for Vue.",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
@@ -11,40 +11,31 @@
11
11
  "url": "https://github.com/sponsors/tannerlinsley"
12
12
  },
13
13
  "type": "module",
14
- "types": "build/legacy/index.d.ts",
15
- "main": "build/legacy/index.cjs",
16
- "module": "build/legacy/index.js",
14
+ "types": "dist/mjs/index.d.mts",
15
+ "main": "dist/cjs/index.cjs",
16
+ "module": "dist/mjs/index.mjs",
17
17
  "exports": {
18
18
  ".": {
19
19
  "import": {
20
- "types": "./build/modern/index.d.ts",
21
- "default": "./build/modern/index.js"
20
+ "types": "./dist/mjs/index.d.mts",
21
+ "default": "./dist/mjs/index.mjs"
22
22
  },
23
23
  "require": {
24
- "types": "./build/modern/index.d.cts",
25
- "default": "./build/modern/index.cjs"
24
+ "types": "./dist/cjs/index.d.cts",
25
+ "default": "./dist/cjs/index.cjs"
26
26
  }
27
27
  },
28
28
  "./package.json": "./package.json"
29
29
  },
30
30
  "sideEffects": false,
31
- "nx": {
32
- "targets": {
33
- "test:build": {
34
- "dependsOn": [
35
- "build"
36
- ]
37
- }
38
- }
39
- },
40
31
  "files": [
41
- "build",
32
+ "dist",
42
33
  "src"
43
34
  ],
44
35
  "dependencies": {
45
36
  "@tanstack/store": "0.1.3",
46
37
  "@tanstack/vue-store": "0.1.3",
47
- "@tanstack/form-core": "0.10.3"
38
+ "@tanstack/form-core": "0.12.0"
48
39
  },
49
40
  "devDependencies": {
50
41
  "vue": "^3.3.4"
@@ -53,13 +44,17 @@
53
44
  "vue": "^3.3.0"
54
45
  },
55
46
  "scripts": {
56
- "clean": "rimraf ./build && rimraf ./coverage",
47
+ "clean": "rimraf ./dist && rimraf ./coverage",
57
48
  "test:eslint": "eslint --ext .ts,.tsx ./src",
58
- "test:types": "tsc",
49
+ "test:types:versions49": "../../node_modules/typescript49/bin/tsc --noEmit",
50
+ "test:types:versions50": "../../node_modules/typescript50/bin/tsc --noEmit",
51
+ "test:types:versions51": "../../node_modules/typescript51/bin/tsc --noEmit",
52
+ "test:types:versions52": "tsc --noEmit",
53
+ "test:types": "pnpm run \"/^test:types:versions.*/\"",
59
54
  "fixme:test:lib": "pnpm run test:2 && pnpm run test:2.7 && pnpm run test:3",
60
55
  "test:lib": "vitest",
61
56
  "test:lib:dev": "pnpm run test:lib --watch",
62
57
  "test:build": "publint --strict",
63
- "build": "tsup"
58
+ "build": "vite build"
64
59
  }
65
60
  }
@@ -1,23 +1,29 @@
1
- import type { FormApi, FormOptions } from '@tanstack/form-core'
1
+ import type { FormApi, FormOptions, Validator } from '@tanstack/form-core'
2
2
 
3
3
  import { type UseField, type FieldComponent, Field, useField } from './useField'
4
4
  import { useForm } from './useForm'
5
5
 
6
- export type FormFactory<TFormData, FormValidator> = {
6
+ export type FormFactory<
7
+ TFormData,
8
+ TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
9
+ > = {
7
10
  useForm: (
8
- opts?: FormOptions<TFormData, FormValidator>,
9
- ) => FormApi<TFormData, FormValidator>
10
- useField: UseField<TFormData, FormValidator>
11
- Field: FieldComponent<TFormData, FormValidator>
11
+ opts?: FormOptions<TFormData, TFormValidator>,
12
+ ) => FormApi<TFormData, TFormValidator>
13
+ useField: UseField<TFormData, TFormValidator>
14
+ Field: FieldComponent<TFormData, TFormValidator>
12
15
  }
13
16
 
14
- export function createFormFactory<TFormData, FormValidator>(
15
- defaultOpts?: FormOptions<TFormData, FormValidator>,
16
- ): FormFactory<TFormData, FormValidator> {
17
+ export function createFormFactory<
18
+ TFormData,
19
+ TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
20
+ >(
21
+ defaultOpts?: FormOptions<TFormData, TFormValidator>,
22
+ ): FormFactory<TFormData, TFormValidator> {
17
23
  return {
18
24
  useForm: (opts) => {
19
25
  const formOptions = Object.assign({}, defaultOpts, opts)
20
- return useForm<TFormData, FormValidator>(formOptions)
26
+ return useForm<TFormData, TFormValidator>(formOptions)
21
27
  },
22
28
  useField: useField as any,
23
29
  Field: Field as any,
@@ -1,14 +1,20 @@
1
- import type { FormApi } from '@tanstack/form-core'
1
+ import type { FormApi, Validator } from '@tanstack/form-core'
2
2
  import { inject, provide } from 'vue'
3
3
 
4
- export type FormContext = {
5
- formApi: FormApi<any, unknown>
4
+ export type FormContext<
5
+ TFormData = any,
6
+ TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
7
+ > = {
8
+ formApi: FormApi<TFormData, TFormValidator>
6
9
  parentFieldName?: string
7
10
  } | null
8
11
 
9
12
  export const formContext = Symbol('FormContext')
10
13
 
11
- export function provideFormContext(val: FormContext) {
14
+ export function provideFormContext<
15
+ TFormData = any,
16
+ TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
17
+ >(val: FormContext<TFormData, TFormValidator>) {
12
18
  provide(formContext, val)
13
19
  }
14
20
 
@@ -15,7 +15,7 @@ describe('useField', () => {
15
15
  lastName: string
16
16
  }
17
17
 
18
- const formFactory = createFormFactory<Person, unknown>()
18
+ const formFactory = createFormFactory<Person>()
19
19
 
20
20
  const Comp = defineComponent(() => {
21
21
  const form = formFactory.useForm()
@@ -54,7 +54,7 @@ describe('useField', () => {
54
54
  }
55
55
  const error = 'Please enter a different value'
56
56
 
57
- const formFactory = createFormFactory<Person, unknown>()
57
+ const formFactory = createFormFactory<Person>()
58
58
 
59
59
  const Comp = defineComponent(() => {
60
60
  const form = formFactory.useForm()
@@ -64,7 +64,9 @@ describe('useField', () => {
64
64
  return () => (
65
65
  <form.Field
66
66
  name="firstName"
67
- onChange={(value) => (value === 'other' ? error : undefined)}
67
+ validators={{
68
+ onChange: ({ value }) => (value === 'other' ? error : undefined),
69
+ }}
68
70
  >
69
71
  {({
70
72
  field,
@@ -101,7 +103,7 @@ describe('useField', () => {
101
103
  }
102
104
  const error = 'Please enter a different value'
103
105
 
104
- const formFactory = createFormFactory<Person, unknown>()
106
+ const formFactory = createFormFactory<Person>()
105
107
 
106
108
  const Comp = defineComponent(() => {
107
109
  const form = formFactory.useForm()
@@ -111,7 +113,9 @@ describe('useField', () => {
111
113
  return () => (
112
114
  <form.Field
113
115
  name="firstName"
114
- onChange={(value) => (value === 'other' ? error : undefined)}
116
+ validators={{
117
+ onChange: ({ value }) => (value === 'other' ? error : undefined),
118
+ }}
115
119
  >
116
120
  {({
117
121
  field,
@@ -149,7 +153,7 @@ describe('useField', () => {
149
153
  }
150
154
  const error = 'Please enter a different value'
151
155
 
152
- const formFactory = createFormFactory<Person, unknown>()
156
+ const formFactory = createFormFactory<Person>()
153
157
 
154
158
  const Comp = defineComponent(() => {
155
159
  const form = formFactory.useForm()
@@ -160,9 +164,11 @@ describe('useField', () => {
160
164
  <form.Field
161
165
  name="firstName"
162
166
  defaultMeta={{ isTouched: true }}
163
- onChangeAsync={async () => {
164
- await sleep(10)
165
- return error
167
+ validators={{
168
+ onChangeAsync: async () => {
169
+ await sleep(10)
170
+ return error
171
+ },
166
172
  }}
167
173
  >
168
174
  {({
@@ -203,7 +209,7 @@ describe('useField', () => {
203
209
 
204
210
  const mockFn = vi.fn()
205
211
  const error = 'Please enter a different value'
206
- const formFactory = createFormFactory<Person, unknown>()
212
+ const formFactory = createFormFactory<Person>()
207
213
 
208
214
  const Comp = defineComponent(() => {
209
215
  const form = formFactory.useForm()
@@ -214,11 +220,13 @@ describe('useField', () => {
214
220
  <form.Field
215
221
  name="firstName"
216
222
  defaultMeta={{ isTouched: true }}
217
- onChangeAsyncDebounceMs={100}
218
- onChangeAsync={async () => {
219
- mockFn()
220
- await sleep(10)
221
- return error
223
+ validators={{
224
+ onChangeAsyncDebounceMs: 100,
225
+ onChangeAsync: async () => {
226
+ mockFn()
227
+ await sleep(10)
228
+ return error
229
+ },
222
230
  }}
223
231
  >
224
232
  {({
@@ -22,7 +22,7 @@ type Person = {
22
22
 
23
23
  describe('useForm', () => {
24
24
  it('preserved field state', async () => {
25
- const formFactory = createFormFactory<Person, unknown>()
25
+ const formFactory = createFormFactory<Person>()
26
26
 
27
27
  const Comp = defineComponent(() => {
28
28
  const form = formFactory.useForm()
@@ -57,7 +57,7 @@ describe('useForm', () => {
57
57
  })
58
58
 
59
59
  it('should allow default values to be set', async () => {
60
- const formFactory = createFormFactory<Person, unknown>()
60
+ const formFactory = createFormFactory<Person>()
61
61
 
62
62
  const Comp = defineComponent(() => {
63
63
  const form = formFactory.useForm({
@@ -92,8 +92,8 @@ describe('useForm', () => {
92
92
  defaultValues: {
93
93
  firstName: 'FirstName',
94
94
  },
95
- onSubmit: (data) => {
96
- submittedData.value = data
95
+ onSubmit: ({ value }) => {
96
+ submittedData.value = value
97
97
  },
98
98
  })
99
99
  form.provideFormContext()
@@ -145,9 +145,11 @@ describe('useForm', () => {
145
145
  defaultValues: {
146
146
  firstName: 'FirstName',
147
147
  },
148
- onMount: () => {
149
- formMounted.value = true
150
- return undefined
148
+ validators: {
149
+ onMount: () => {
150
+ formMounted.value = true
151
+ return undefined
152
+ },
151
153
  },
152
154
  })
153
155
 
@@ -171,12 +173,14 @@ describe('useForm', () => {
171
173
  it('should validate async on change for the form', async () => {
172
174
  const error = 'Please enter a different value'
173
175
 
174
- const formFactory = createFormFactory<Person, unknown>()
176
+ const formFactory = createFormFactory<Person>()
175
177
 
176
178
  const Comp = defineComponent(() => {
177
179
  const form = formFactory.useForm({
178
- onChange() {
179
- return error
180
+ validators: {
181
+ onChange() {
182
+ return error
183
+ },
180
184
  },
181
185
  })
182
186
 
@@ -218,11 +222,14 @@ describe('useForm', () => {
218
222
  it('should not validate on change if isTouched is false', async () => {
219
223
  const error = 'Please enter a different value'
220
224
 
221
- const formFactory = createFormFactory<Person, unknown>()
225
+ const formFactory = createFormFactory<Person>()
222
226
 
223
227
  const Comp = defineComponent(() => {
224
228
  const form = formFactory.useForm({
225
- onChange: (value) => (value.firstName === 'other' ? error : undefined),
229
+ validators: {
230
+ onChange: ({ value }) =>
231
+ value.firstName === 'other' ? error : undefined,
232
+ },
226
233
  })
227
234
 
228
235
  const errors = form.useStore((s) => s.errors)
@@ -264,11 +271,14 @@ describe('useForm', () => {
264
271
  it('should validate on change if isTouched is true', async () => {
265
272
  const error = 'Please enter a different value'
266
273
 
267
- const formFactory = createFormFactory<Person, unknown>()
274
+ const formFactory = createFormFactory<Person>()
268
275
 
269
276
  const Comp = defineComponent(() => {
270
277
  const form = formFactory.useForm({
271
- onChange: (value) => (value.firstName === 'other' ? error : undefined),
278
+ validators: {
279
+ onChange: ({ value }) =>
280
+ value.firstName === 'other' ? error : undefined,
281
+ },
272
282
  })
273
283
 
274
284
  const errors = form.useStore((s) => s.errorMap)
@@ -317,13 +327,15 @@ describe('useForm', () => {
317
327
  defaultValues: {
318
328
  firstName: '',
319
329
  },
320
- onChange: (vals) => {
321
- if (vals.firstName === 'other') return onChangeError
322
- return undefined
323
- },
324
- onBlur: (vals) => {
325
- if (vals.firstName === 'other') return onBlurError
326
- return undefined
330
+ validators: {
331
+ onChange: ({ value }) => {
332
+ if (value.firstName === 'other') return onChangeError
333
+ return undefined
334
+ },
335
+ onBlur: ({ value }) => {
336
+ if (value.firstName === 'other') return onBlurError
337
+ return undefined
338
+ },
327
339
  },
328
340
  })
329
341
 
@@ -370,13 +382,15 @@ describe('useForm', () => {
370
382
  it('should validate async on change', async () => {
371
383
  const error = 'Please enter a different value'
372
384
 
373
- const formFactory = createFormFactory<Person, unknown>()
385
+ const formFactory = createFormFactory<Person>()
374
386
 
375
387
  const Comp = defineComponent(() => {
376
388
  const form = formFactory.useForm({
377
- onChangeAsync: async () => {
378
- await sleep(10)
379
- return error
389
+ validators: {
390
+ onChangeAsync: async () => {
391
+ await sleep(10)
392
+ return error
393
+ },
380
394
  },
381
395
  })
382
396
 
@@ -422,17 +436,19 @@ describe('useForm', () => {
422
436
  const onChangeError = 'Please enter a different value (onChangeError)'
423
437
  const onBlurError = 'Please enter a different value (onBlurError)'
424
438
 
425
- const formFactory = createFormFactory<Person, unknown>()
439
+ const formFactory = createFormFactory<Person>()
426
440
 
427
441
  const Comp = defineComponent(() => {
428
442
  const form = formFactory.useForm({
429
- onChangeAsync: async () => {
430
- await sleep(10)
431
- return onChangeError
432
- },
433
- onBlurAsync: async () => {
434
- await sleep(10)
435
- return onBlurError
443
+ validators: {
444
+ onChangeAsync: async () => {
445
+ await sleep(10)
446
+ return onChangeError
447
+ },
448
+ onBlurAsync: async () => {
449
+ await sleep(10)
450
+ return onBlurError
451
+ },
436
452
  },
437
453
  })
438
454
  const errors = form.useStore((s) => s.errorMap)
@@ -482,15 +498,17 @@ describe('useForm', () => {
482
498
  it('should validate async on change with debounce', async () => {
483
499
  const mockFn = vi.fn()
484
500
  const error = 'Please enter a different value'
485
- const formFactory = createFormFactory<Person, unknown>()
501
+ const formFactory = createFormFactory<Person>()
486
502
 
487
503
  const Comp = defineComponent(() => {
488
504
  const form = formFactory.useForm({
489
- onChangeAsyncDebounceMs: 100,
490
- onChangeAsync: async () => {
491
- mockFn()
492
- await sleep(10)
493
- return error
505
+ validators: {
506
+ onChangeAsyncDebounceMs: 100,
507
+ onChangeAsync: async () => {
508
+ mockFn()
509
+ await sleep(10)
510
+ return error
511
+ },
494
512
  },
495
513
  })
496
514
  const errors = form.useStore((s) => s.errors)
package/src/types.ts CHANGED
@@ -1,11 +1,20 @@
1
- import type { FieldOptions, DeepKeys, DeepValue } from '@tanstack/form-core'
1
+ import type {
2
+ FieldOptions,
3
+ DeepKeys,
4
+ DeepValue,
5
+ Validator,
6
+ } from '@tanstack/form-core'
2
7
 
3
8
  export type UseFieldOptions<
4
9
  TParentData,
5
10
  TName extends DeepKeys<TParentData>,
6
- ValidatorType,
7
- FormValidator,
11
+ TFieldValidator extends
12
+ | Validator<DeepValue<TParentData, TName>, unknown>
13
+ | undefined = undefined,
14
+ TFormValidator extends
15
+ | Validator<TParentData, unknown>
16
+ | undefined = undefined,
8
17
  TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
9
- > = FieldOptions<TParentData, TName, ValidatorType, FormValidator, TData> & {
18
+ > = FieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData> & {
10
19
  mode?: 'value' | 'array'
11
20
  }