@tanstack/vue-form 0.10.3 → 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 +6 -6
- package/build/legacy/createFormFactory.d.ts +6 -6
- package/build/legacy/createFormFactory.js.map +1 -1
- package/build/legacy/formContext.cjs.map +1 -1
- package/build/legacy/formContext.d.cts +5 -5
- package/build/legacy/formContext.d.ts +5 -5
- 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 +14 -14
- package/build/legacy/useField.d.ts +14 -14
- package/build/legacy/useField.js.map +1 -1
- package/build/legacy/useForm.cjs.map +1 -1
- package/build/legacy/useForm.d.cts +5 -5
- package/build/legacy/useForm.d.ts +5 -5
- package/build/legacy/useForm.js +3 -1
- package/build/legacy/useForm.js.map +1 -1
- package/build/modern/createFormFactory.cjs.map +1 -1
- package/build/modern/createFormFactory.d.cts +6 -6
- package/build/modern/createFormFactory.d.ts +6 -6
- package/build/modern/createFormFactory.js.map +1 -1
- package/build/modern/formContext.cjs.map +1 -1
- package/build/modern/formContext.d.cts +5 -5
- package/build/modern/formContext.d.ts +5 -5
- 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 +14 -14
- package/build/modern/useField.d.ts +14 -14
- package/build/modern/useField.js.map +1 -1
- package/build/modern/useForm.cjs.map +1 -1
- package/build/modern/useForm.d.cts +5 -5
- package/build/modern/useForm.d.ts +5 -5
- package/build/modern/useForm.js +3 -1
- package/build/modern/useForm.js.map +1 -1
- package/package.json +2 -2
- package/src/createFormFactory.ts +16 -10
- package/src/formContext.ts +10 -4
- package/src/tests/useField.test.tsx +23 -15
- package/src/tests/useForm.test.tsx +57 -39
- package/src/types.ts +13 -4
- package/src/useField.tsx +68 -35
- 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
|
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
|
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: (
|
96
|
-
submittedData.value =
|
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
|
-
|
149
|
-
|
150
|
-
|
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
|
176
|
+
const formFactory = createFormFactory<Person>()
|
175
177
|
|
176
178
|
const Comp = defineComponent(() => {
|
177
179
|
const form = formFactory.useForm({
|
178
|
-
|
179
|
-
|
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
|
225
|
+
const formFactory = createFormFactory<Person>()
|
222
226
|
|
223
227
|
const Comp = defineComponent(() => {
|
224
228
|
const form = formFactory.useForm({
|
225
|
-
|
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
|
274
|
+
const formFactory = createFormFactory<Person>()
|
268
275
|
|
269
276
|
const Comp = defineComponent(() => {
|
270
277
|
const form = formFactory.useForm({
|
271
|
-
|
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
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
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
|
385
|
+
const formFactory = createFormFactory<Person>()
|
374
386
|
|
375
387
|
const Comp = defineComponent(() => {
|
376
388
|
const form = formFactory.useForm({
|
377
|
-
|
378
|
-
|
379
|
-
|
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
|
439
|
+
const formFactory = createFormFactory<Person>()
|
426
440
|
|
427
441
|
const Comp = defineComponent(() => {
|
428
442
|
const form = formFactory.useForm({
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
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
|
501
|
+
const formFactory = createFormFactory<Person>()
|
486
502
|
|
487
503
|
const Comp = defineComponent(() => {
|
488
504
|
const form = formFactory.useForm({
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
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 {
|
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
|
-
|
7
|
-
|
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,
|
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
|
-
|
15
|
-
|
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<
|
22
|
+
Field: FieldComponent<TParentData, TFormValidator>
|
19
23
|
}
|
20
24
|
}
|
21
25
|
|
22
|
-
export type UseField<
|
26
|
+
export type UseField<
|
27
|
+
TParentData,
|
28
|
+
TFormValidator extends
|
29
|
+
| Validator<TParentData, unknown>
|
30
|
+
| undefined = undefined,
|
31
|
+
> = <
|
23
32
|
TName extends DeepKeys<TParentData>,
|
24
|
-
|
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
|
-
|
30
|
-
|
40
|
+
TFieldValidator,
|
41
|
+
TFormValidator,
|
31
42
|
DeepValue<TParentData, TName>
|
32
43
|
>,
|
33
44
|
) => FieldApi<
|
34
45
|
TParentData,
|
35
46
|
TName,
|
36
|
-
|
37
|
-
|
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
|
-
|
45
|
-
|
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
|
-
|
52
|
-
|
66
|
+
TFieldValidator,
|
67
|
+
TFormValidator,
|
53
68
|
TData
|
54
69
|
>,
|
55
70
|
): {
|
56
71
|
api: FieldApi<
|
57
72
|
TParentData,
|
58
73
|
TName,
|
59
|
-
|
60
|
-
|
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
|
-
|
72
|
-
|
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
|
-
|
128
|
-
|
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,
|
155
|
+
UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,
|
140
156
|
'name' | 'index'
|
141
157
|
>
|
142
158
|
|
143
|
-
export type FieldComponent<
|
159
|
+
export type FieldComponent<
|
160
|
+
TParentData,
|
161
|
+
TFormValidator extends
|
162
|
+
| Validator<TParentData, unknown>
|
163
|
+
| undefined = undefined,
|
164
|
+
> = <
|
144
165
|
TName extends DeepKeys<TParentData>,
|
145
|
-
|
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
|
-
|
152
|
-
|
174
|
+
TFieldValidator,
|
175
|
+
TFormValidator
|
153
176
|
>,
|
154
177
|
context: SetupContext<
|
155
178
|
{},
|
156
179
|
SlotsType<{
|
157
180
|
default: {
|
158
|
-
field: FieldApi<
|
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
|
-
|
163
|
-
|
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
|
-
|
176
|
-
|
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
|
-
|
182
|
-
|
214
|
+
TFieldValidator,
|
215
|
+
TFormValidator
|
183
216
|
>,
|
184
217
|
context: SetupContext,
|
185
218
|
) => {
|
package/src/useForm.tsx
CHANGED
@@ -1,4 +1,9 @@
|
|
1
|
-
import {
|
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,
|
21
|
+
interface FormApi<TFormData, TFormValidator> {
|
17
22
|
Provider: (props: Record<string, any> & {}) => any
|
18
23
|
provideFormContext: () => void
|
19
|
-
Field: FieldComponent<TFormData,
|
20
|
-
useField: UseField<TFormData,
|
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<
|
37
|
-
|
38
|
-
|
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<
|
48
|
+
const api = new FormApi<TFormData, TFormValidator>(opts)
|
41
49
|
|
42
50
|
api.Provider = defineComponent(
|
43
51
|
(_, context) => {
|