@tanstack/vue-form 0.10.2 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/build/legacy/createFormFactory.cjs.map +1 -1
  2. package/build/legacy/createFormFactory.d.cts +6 -6
  3. package/build/legacy/createFormFactory.d.ts +6 -6
  4. package/build/legacy/createFormFactory.js.map +1 -1
  5. package/build/legacy/formContext.cjs.map +1 -1
  6. package/build/legacy/formContext.d.cts +5 -5
  7. package/build/legacy/formContext.d.ts +5 -5
  8. package/build/legacy/formContext.js.map +1 -1
  9. package/build/legacy/types.cjs.map +1 -1
  10. package/build/legacy/types.d.cts +2 -2
  11. package/build/legacy/types.d.ts +2 -2
  12. package/build/legacy/useField.cjs.map +1 -1
  13. package/build/legacy/useField.d.cts +14 -14
  14. package/build/legacy/useField.d.ts +14 -14
  15. package/build/legacy/useField.js.map +1 -1
  16. package/build/legacy/useForm.cjs.map +1 -1
  17. package/build/legacy/useForm.d.cts +5 -5
  18. package/build/legacy/useForm.d.ts +5 -5
  19. package/build/legacy/useForm.js +3 -1
  20. package/build/legacy/useForm.js.map +1 -1
  21. package/build/modern/createFormFactory.cjs.map +1 -1
  22. package/build/modern/createFormFactory.d.cts +6 -6
  23. package/build/modern/createFormFactory.d.ts +6 -6
  24. package/build/modern/createFormFactory.js.map +1 -1
  25. package/build/modern/formContext.cjs.map +1 -1
  26. package/build/modern/formContext.d.cts +5 -5
  27. package/build/modern/formContext.d.ts +5 -5
  28. package/build/modern/formContext.js.map +1 -1
  29. package/build/modern/types.cjs.map +1 -1
  30. package/build/modern/types.d.cts +2 -2
  31. package/build/modern/types.d.ts +2 -2
  32. package/build/modern/useField.cjs.map +1 -1
  33. package/build/modern/useField.d.cts +14 -14
  34. package/build/modern/useField.d.ts +14 -14
  35. package/build/modern/useField.js.map +1 -1
  36. package/build/modern/useForm.cjs.map +1 -1
  37. package/build/modern/useForm.d.cts +5 -5
  38. package/build/modern/useForm.d.ts +5 -5
  39. package/build/modern/useForm.js +3 -1
  40. package/build/modern/useForm.js.map +1 -1
  41. package/package.json +2 -2
  42. package/src/createFormFactory.ts +16 -10
  43. package/src/formContext.ts +10 -4
  44. package/src/tests/useField.test.tsx +23 -15
  45. package/src/tests/useForm.test.tsx +57 -39
  46. package/src/types.ts +13 -4
  47. package/src/useField.tsx +68 -35
  48. package/src/useForm.tsx +16 -8
@@ -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
  }
package/src/useField.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import { FieldApi } from '@tanstack/form-core'
1
+ import { FieldApi, type Validator } from '@tanstack/form-core'
2
2
  import type { DeepKeys, DeepValue, Narrow } from '@tanstack/form-core'
3
3
  import { useStore } from '@tanstack/vue-store'
4
4
  import { defineComponent, onMounted, onUnmounted, watch } from 'vue'
@@ -11,53 +11,68 @@ declare module '@tanstack/form-core' {
11
11
  interface FieldApi<
12
12
  TParentData,
13
13
  TName extends DeepKeys<TParentData>,
14
- ValidatorType,
15
- FormValidator,
14
+ TFieldValidator extends
15
+ | Validator<DeepValue<TParentData, TName>, unknown>
16
+ | undefined = undefined,
17
+ TFormValidator extends
18
+ | Validator<TParentData, unknown>
19
+ | undefined = undefined,
16
20
  TData = DeepValue<TParentData, TName>,
17
21
  > {
18
- Field: FieldComponent<TData, FormValidator>
22
+ Field: FieldComponent<TParentData, TFormValidator>
19
23
  }
20
24
  }
21
25
 
22
- export type UseField<TParentData, FormValidator> = <
26
+ export type UseField<
27
+ TParentData,
28
+ TFormValidator extends
29
+ | Validator<TParentData, unknown>
30
+ | undefined = undefined,
31
+ > = <
23
32
  TName extends DeepKeys<TParentData>,
24
- ValidatorType,
33
+ TFieldValidator extends
34
+ | Validator<DeepValue<TParentData, TName>, unknown>
35
+ | undefined = undefined,
25
36
  >(
26
37
  opts?: { name: Narrow<TName> } & UseFieldOptions<
27
38
  TParentData,
28
39
  TName,
29
- ValidatorType,
30
- FormValidator,
40
+ TFieldValidator,
41
+ TFormValidator,
31
42
  DeepValue<TParentData, TName>
32
43
  >,
33
44
  ) => FieldApi<
34
45
  TParentData,
35
46
  TName,
36
- ValidatorType,
37
- FormValidator,
47
+ TFieldValidator,
48
+ TFormValidator,
38
49
  DeepValue<TParentData, TName>
39
50
  >
40
51
 
41
52
  export function useField<
42
53
  TParentData,
43
54
  TName extends DeepKeys<TParentData>,
44
- ValidatorType,
45
- FormValidator,
55
+ TFieldValidator extends
56
+ | Validator<DeepValue<TParentData, TName>, unknown>
57
+ | undefined = undefined,
58
+ TFormValidator extends
59
+ | Validator<TParentData, unknown>
60
+ | undefined = undefined,
46
61
  TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
47
62
  >(
48
63
  opts: UseFieldOptions<
49
64
  TParentData,
50
65
  TName,
51
- ValidatorType,
52
- FormValidator,
66
+ TFieldValidator,
67
+ TFormValidator,
53
68
  TData
54
69
  >,
55
70
  ): {
56
71
  api: FieldApi<
57
72
  TParentData,
58
73
  TName,
59
- ValidatorType,
60
- FormValidator,
74
+ TFieldValidator,
75
+ TFormValidator,
61
76
  TData
62
77
  // Omit<typeof opts, 'onMount'> & {
63
78
  // form: FormApi<TParentData>
@@ -68,12 +83,9 @@ export function useField<
68
83
  FieldApi<
69
84
  TParentData,
70
85
  TName,
71
- ValidatorType,
72
- FormValidator,
86
+ TFieldValidator,
87
+ TFormValidator,
73
88
  TData
74
- // Omit<typeof opts, 'onMount'> & {
75
- // form: FormApi<TParentData>
76
- // }
77
89
  >['state']
78
90
  >
79
91
  >
@@ -124,8 +136,12 @@ export type FieldValue<TParentData, TName> = TParentData extends any[]
124
136
  type FieldComponentProps<
125
137
  TParentData,
126
138
  TName extends DeepKeys<TParentData>,
127
- ValidatorType,
128
- FormValidator,
139
+ TFieldValidator extends
140
+ | Validator<DeepValue<TParentData, TName>, unknown>
141
+ | undefined = undefined,
142
+ TFormValidator extends
143
+ | Validator<TParentData, unknown>
144
+ | undefined = undefined,
129
145
  > = (TParentData extends any[]
130
146
  ? {
131
147
  name?: TName
@@ -136,31 +152,44 @@ type FieldComponentProps<
136
152
  index?: never
137
153
  }) &
138
154
  Omit<
139
- UseFieldOptions<TParentData, TName, ValidatorType, FormValidator>,
155
+ UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,
140
156
  'name' | 'index'
141
157
  >
142
158
 
143
- export type FieldComponent<TParentData, FormValidator> = <
159
+ export type FieldComponent<
160
+ TParentData,
161
+ TFormValidator extends
162
+ | Validator<TParentData, unknown>
163
+ | undefined = undefined,
164
+ > = <
144
165
  TName extends DeepKeys<TParentData>,
145
- ValidatorType,
166
+ TFieldValidator extends
167
+ | Validator<DeepValue<TParentData, TName>, unknown>
168
+ | undefined = undefined,
146
169
  TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
147
170
  >(
148
171
  fieldOptions: FieldComponentProps<
149
172
  TParentData,
150
173
  TName,
151
- ValidatorType,
152
- FormValidator
174
+ TFieldValidator,
175
+ TFormValidator
153
176
  >,
154
177
  context: SetupContext<
155
178
  {},
156
179
  SlotsType<{
157
180
  default: {
158
- field: FieldApi<TParentData, TName, ValidatorType, FormValidator, TData>
181
+ field: FieldApi<
182
+ TParentData,
183
+ TName,
184
+ TFieldValidator,
185
+ TFormValidator,
186
+ TData
187
+ >
159
188
  state: FieldApi<
160
189
  TParentData,
161
190
  TName,
162
- ValidatorType,
163
- FormValidator,
191
+ TFieldValidator,
192
+ TFormValidator,
164
193
  TData
165
194
  >['state']
166
195
  }
@@ -172,14 +201,18 @@ export const Field = defineComponent(
172
201
  <
173
202
  TParentData,
174
203
  TName extends DeepKeys<TParentData>,
175
- ValidatorType,
176
- FormValidator,
204
+ TFieldValidator extends
205
+ | Validator<DeepValue<TParentData, TName>, unknown>
206
+ | undefined = undefined,
207
+ TFormValidator extends
208
+ | Validator<TParentData, unknown>
209
+ | undefined = undefined,
177
210
  >(
178
211
  fieldOptions: UseFieldOptions<
179
212
  TParentData,
180
213
  TName,
181
- ValidatorType,
182
- FormValidator
214
+ TFieldValidator,
215
+ TFormValidator
183
216
  >,
184
217
  context: SetupContext,
185
218
  ) => {
package/src/useForm.tsx CHANGED
@@ -1,4 +1,9 @@
1
- import { FormApi, type FormState, type FormOptions } from '@tanstack/form-core'
1
+ import {
2
+ FormApi,
3
+ type FormState,
4
+ type FormOptions,
5
+ type Validator,
6
+ } from '@tanstack/form-core'
2
7
  import { type NoInfer, useStore } from '@tanstack/vue-store'
3
8
  import { type UseField, type FieldComponent, Field, useField } from './useField'
4
9
  import { provideFormContext } from './formContext'
@@ -13,11 +18,11 @@ import {
13
18
 
14
19
  declare module '@tanstack/form-core' {
15
20
  // eslint-disable-next-line no-shadow
16
- interface FormApi<TFormData, ValidatorType> {
21
+ interface FormApi<TFormData, TFormValidator> {
17
22
  Provider: (props: Record<string, any> & {}) => any
18
23
  provideFormContext: () => void
19
- Field: FieldComponent<TFormData, ValidatorType>
20
- useField: UseField<TFormData, ValidatorType>
24
+ Field: FieldComponent<TFormData, TFormValidator>
25
+ useField: UseField<TFormData, TFormValidator>
21
26
  useStore: <TSelected = NoInfer<FormState<TFormData>>>(
22
27
  selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,
23
28
  ) => Readonly<Ref<TSelected>>
@@ -33,11 +38,14 @@ declare module '@tanstack/form-core' {
33
38
  }
34
39
  }
35
40
 
36
- export function useForm<TData, FormValidator>(
37
- opts?: FormOptions<TData, FormValidator>,
38
- ): FormApi<TData, FormValidator> {
41
+ export function useForm<
42
+ TFormData,
43
+ TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
44
+ >(
45
+ opts?: FormOptions<TFormData, TFormValidator>,
46
+ ): FormApi<TFormData, TFormValidator> {
39
47
  const formApi = (() => {
40
- const api = new FormApi<TData, FormValidator>(opts)
48
+ const api = new FormApi<TFormData, TFormValidator>(opts)
41
49
 
42
50
  api.Provider = defineComponent(
43
51
  (_, context) => {