@tanstack/vue-form 1.33.4 → 2.0.0-alpha.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 (92) hide show
  1. package/dist/AppForm/Components.lib.js +16 -0
  2. package/dist/AppForm/VueAppFormApi.public.d.ts +14 -0
  3. package/dist/AppForm/appFormOptions.public.d.ts +14 -0
  4. package/dist/AppForm/componentMap.public.d.ts +10 -0
  5. package/dist/AppForm/contexts.lib.js +18 -0
  6. package/dist/AppForm/createFormHook.public.d.ts +6 -0
  7. package/dist/AppForm/createFormHook.public.js +24 -0
  8. package/dist/AppForm/createFormHookTypes.public.d.ts +15 -0
  9. package/dist/AppForm/fieldComponentHelpers.lib.js +22 -0
  10. package/dist/AppForm/getFormHookHelpers.public.d.ts +37 -0
  11. package/dist/AppForm/getFormHookHelpers.public.js +18 -0
  12. package/dist/AppForm/initializeAppForm.lib.js +10 -0
  13. package/dist/FieldGroup/FieldGroupApi.public.d.ts +30 -0
  14. package/dist/FieldGroup/withFields.lib.js +62 -0
  15. package/dist/FieldGroup/withFields.public.d.ts +57 -0
  16. package/dist/FieldGroup/withFields.public.js +8 -0
  17. package/dist/Subscribe.public.d.ts +15 -0
  18. package/dist/Subscribe.public.js +22 -0
  19. package/dist/VueForm/Components.lib.js +94 -0
  20. package/dist/VueForm/Components.public.d.ts +71 -0
  21. package/dist/VueForm/VueFormApi.lib.js +26 -0
  22. package/dist/VueForm/fieldSubscriptions.lib.js +34 -0
  23. package/dist/VueForm/formApiTypes.public.d.ts +10 -0
  24. package/dist/VueForm/formType.public.d.ts +9 -0
  25. package/dist/VueForm/useField.lib.js +44 -0
  26. package/dist/VueForm/useForm.public.d.ts +8 -0
  27. package/dist/VueForm/useForm.public.js +10 -0
  28. package/dist/index.d.ts +16 -0
  29. package/dist/index.js +11 -0
  30. package/dist/vueTypes.lib.d.ts +6 -0
  31. package/package.json +13 -29
  32. package/src/AppForm/Components.lib.ts +31 -0
  33. package/src/AppForm/VueAppFormApi.public.ts +17 -0
  34. package/src/AppForm/appFormOptions.public.ts +55 -0
  35. package/src/AppForm/componentMap.public.ts +19 -0
  36. package/src/AppForm/contexts.lib.ts +31 -0
  37. package/src/AppForm/createFormHook.public.ts +32 -0
  38. package/src/AppForm/createFormHookTypes.public.ts +28 -0
  39. package/src/AppForm/fieldComponentHelpers.lib.ts +21 -0
  40. package/src/AppForm/getFormHookHelpers.public.ts +109 -0
  41. package/src/AppForm/initializeAppForm.lib.ts +18 -0
  42. package/src/FieldGroup/FieldGroupApi.public.ts +148 -0
  43. package/src/FieldGroup/withFields.lib.ts +103 -0
  44. package/src/FieldGroup/withFields.public.ts +191 -0
  45. package/src/Subscribe.public.ts +46 -0
  46. package/src/VueForm/Components.lib.ts +182 -0
  47. package/src/VueForm/Components.public.ts +451 -0
  48. package/src/VueForm/VueFormApi.lib.ts +35 -0
  49. package/src/VueForm/fieldSubscriptions.lib.ts +47 -0
  50. package/src/VueForm/formApiTypes.public.ts +32 -0
  51. package/src/VueForm/formType.public.ts +46 -0
  52. package/src/VueForm/useField.lib.ts +64 -0
  53. package/src/VueForm/useForm.public.ts +30 -0
  54. package/src/index.ts +15 -4
  55. package/src/vueTypes.lib.ts +31 -0
  56. package/dist/cjs/index.cjs +0 -27
  57. package/dist/cjs/index.cjs.map +0 -1
  58. package/dist/cjs/index.d.cts +0 -5
  59. package/dist/cjs/types.d.cts +0 -9
  60. package/dist/cjs/useField.cjs +0 -106
  61. package/dist/cjs/useField.cjs.map +0 -1
  62. package/dist/cjs/useField.d.cts +0 -54
  63. package/dist/cjs/useForm.cjs +0 -62
  64. package/dist/cjs/useForm.cjs.map +0 -1
  65. package/dist/cjs/useForm.d.cts +0 -23
  66. package/dist/cjs/useFormGroup.cjs +0 -41
  67. package/dist/cjs/useFormGroup.cjs.map +0 -1
  68. package/dist/cjs/useFormGroup.d.cts +0 -37
  69. package/dist/cjs/useFormId.cjs +0 -31
  70. package/dist/cjs/useFormId.cjs.map +0 -1
  71. package/dist/cjs/useFormId.d.cts +0 -7
  72. package/dist/esm/index.d.ts +0 -5
  73. package/dist/esm/index.js +0 -15
  74. package/dist/esm/index.js.map +0 -1
  75. package/dist/esm/types.d.ts +0 -9
  76. package/dist/esm/useField.d.ts +0 -54
  77. package/dist/esm/useField.js +0 -106
  78. package/dist/esm/useField.js.map +0 -1
  79. package/dist/esm/useForm.d.ts +0 -23
  80. package/dist/esm/useForm.js +0 -62
  81. package/dist/esm/useForm.js.map +0 -1
  82. package/dist/esm/useFormGroup.d.ts +0 -37
  83. package/dist/esm/useFormGroup.js +0 -41
  84. package/dist/esm/useFormGroup.js.map +0 -1
  85. package/dist/esm/useFormId.d.ts +0 -7
  86. package/dist/esm/useFormId.js +0 -14
  87. package/dist/esm/useFormId.js.map +0 -1
  88. package/src/types.ts +0 -114
  89. package/src/useField.tsx +0 -550
  90. package/src/useForm.tsx +0 -360
  91. package/src/useFormGroup.tsx +0 -532
  92. package/src/useFormId.ts +0 -24
@@ -0,0 +1,451 @@
1
+ import type {
2
+ DeepKeys,
3
+ DeepKeysWhereValueIncludes,
4
+ DeepValue,
5
+ FieldApi,
6
+ FieldApiOptions,
7
+ FieldValidators,
8
+ FormErrorTypes,
9
+ FormGroupApi,
10
+ FormGroupOptions,
11
+ FormGroupState,
12
+ FormGroupValidators,
13
+ FormState,
14
+ ToFieldError,
15
+ ToFormGroupErrorTypes,
16
+ } from '@tanstack/form-core'
17
+ import type { Component, PublicProps } from 'vue'
18
+ import type { VueComponentInstance } from '../vueTypes.lib'
19
+
20
+ declare const fieldComponentsType: unique symbol
21
+
22
+ type ExactFieldBrand<out TValue> = {
23
+ readonly __tanstackFieldExactType: TValue
24
+ }
25
+
26
+ type AcceptsFieldBrand<out TAcceptedValue> = {
27
+ readonly __tanstackFieldAcceptsType: TAcceptedValue
28
+ }
29
+
30
+ type CompatibleFieldKey<TKey, TComponent, TTargetValue> =
31
+ TComponent extends ExactFieldBrand<infer TExact>
32
+ ? [TExact] extends [TTargetValue]
33
+ ? [TTargetValue] extends [TExact]
34
+ ? TKey
35
+ : never
36
+ : never
37
+ : TComponent extends AcceptsFieldBrand<infer TLoose>
38
+ ? [TTargetValue] extends [TLoose]
39
+ ? TKey
40
+ : never
41
+ : TKey
42
+
43
+ type FilteredFieldComponents<
44
+ TFieldComponents extends Record<string, Component>,
45
+ TTargetValue,
46
+ > = {
47
+ [
48
+ K in keyof TFieldComponents as CompatibleFieldKey<
49
+ K,
50
+ TFieldComponents[K],
51
+ TTargetValue
52
+ >
53
+ ]: TFieldComponents[K]
54
+ }
55
+
56
+ type FieldComponentsMatchingType<
57
+ TFieldComponents extends Record<string, Component>,
58
+ TTargetValue,
59
+ > = unknown extends TTargetValue
60
+ ? TFieldComponents
61
+ : string extends keyof TFieldComponents
62
+ ? TFieldComponents
63
+ : FilteredFieldComponents<TFieldComponents, TTargetValue>
64
+
65
+ export type VueFieldApi<
66
+ TFieldName,
67
+ TFieldValue,
68
+ TFieldError,
69
+ TFormData,
70
+ TFormErrorTypes extends FormErrorTypes,
71
+ TFieldComponents extends Record<string, Component>,
72
+ > = FieldApi<TFieldName, TFieldValue, TFieldError, TFormData, TFormErrorTypes> &
73
+ FieldComponentsMatchingType<TFieldComponents, TFieldValue>
74
+
75
+ interface VueSubscribeProps<in out TSourceData, in out TSelected> {
76
+ selector: (state: TSourceData) => TSelected
77
+ when?: (selected: NoInfer<TSelected>) => boolean
78
+ }
79
+
80
+ export type VueFormSubscribeProps<
81
+ TFormData,
82
+ TFormErrorTypes extends FormErrorTypes,
83
+ TSelected,
84
+ > = VueSubscribeProps<FormState<TFormData, TFormErrorTypes>, TSelected>
85
+
86
+ export type VueFormSubscribeComponent<
87
+ in out TFormData,
88
+ in out TFormErrorTypes extends FormErrorTypes,
89
+ > = new <TSelected>(
90
+ props: VueFormSubscribeProps<TFormData, TFormErrorTypes, TSelected> &
91
+ PublicProps,
92
+ ) => VueComponentInstance<
93
+ VueFormSubscribeProps<TFormData, TFormErrorTypes, TSelected>,
94
+ { default: NoInfer<TSelected> }
95
+ >
96
+
97
+ export interface VueFormFieldProps<
98
+ in out TFieldData,
99
+ in out TFieldName,
100
+ in out TFieldValue,
101
+ in out TFieldValidators extends FieldValidators<
102
+ TFieldData,
103
+ TFieldName,
104
+ TFieldValue
105
+ >,
106
+ in out TGroupFieldError,
107
+ in out TFormData,
108
+ in out TFormErrorTypes extends FormErrorTypes,
109
+ in out TFieldComponents extends Record<string, Component>,
110
+ > extends FieldApiOptions<
111
+ TFieldData,
112
+ TFieldName,
113
+ TFieldValue,
114
+ TFieldValidators,
115
+ TGroupFieldError,
116
+ TFormData,
117
+ TFormErrorTypes
118
+ > {
119
+ readonly [fieldComponentsType]?: TFieldComponents
120
+ }
121
+
122
+ export type VueFormFieldComponent<
123
+ in out TFormData,
124
+ in out TFormErrorTypes extends FormErrorTypes,
125
+ in out TFieldComponents extends Record<string, Component>,
126
+ > = new <
127
+ TFieldName extends DeepKeys<TFormData>,
128
+ const TFieldValidators extends FieldValidators<
129
+ TFormData,
130
+ TFieldName,
131
+ DeepValue<TFormData, TFieldName>
132
+ >,
133
+ >(
134
+ props: VueFormFieldProps<
135
+ TFormData,
136
+ TFieldName,
137
+ DeepValue<TFormData, TFieldName>,
138
+ TFieldValidators,
139
+ never,
140
+ TFormData,
141
+ TFormErrorTypes,
142
+ TFieldComponents
143
+ > &
144
+ PublicProps,
145
+ ) => VueComponentInstance<
146
+ VueFormFieldProps<
147
+ TFormData,
148
+ TFieldName,
149
+ DeepValue<TFormData, TFieldName>,
150
+ TFieldValidators,
151
+ never,
152
+ TFormData,
153
+ TFormErrorTypes,
154
+ TFieldComponents
155
+ >,
156
+ {
157
+ default: {
158
+ field: VueFieldApi<
159
+ TFieldName,
160
+ DeepValue<TFormData, TFieldName>,
161
+ ToFieldError<NoInfer<TFieldValidators>, never, TFormErrorTypes>,
162
+ TFormData,
163
+ TFormErrorTypes,
164
+ TFieldComponents
165
+ >
166
+ }
167
+ }
168
+ >
169
+
170
+ export type VueFormArrayFieldComponent<
171
+ in out TFormData,
172
+ in out TFormErrorTypes extends FormErrorTypes,
173
+ in out TFieldComponents extends Record<string, Component>,
174
+ > = new <
175
+ TFieldName extends DeepKeysWhereValueIncludes<TFormData, Array<any>>,
176
+ const TFieldValidators extends FieldValidators<
177
+ TFormData,
178
+ TFieldName,
179
+ DeepValue<TFormData, TFieldName>
180
+ >,
181
+ >(
182
+ props: VueFormFieldProps<
183
+ TFormData,
184
+ TFieldName,
185
+ DeepValue<TFormData, TFieldName>,
186
+ TFieldValidators,
187
+ never,
188
+ TFormData,
189
+ TFormErrorTypes,
190
+ TFieldComponents
191
+ > &
192
+ PublicProps,
193
+ ) => VueComponentInstance<
194
+ VueFormFieldProps<
195
+ TFormData,
196
+ TFieldName,
197
+ DeepValue<TFormData, TFieldName>,
198
+ TFieldValidators,
199
+ never,
200
+ TFormData,
201
+ TFormErrorTypes,
202
+ TFieldComponents
203
+ >,
204
+ {
205
+ default: {
206
+ field: VueFieldApi<
207
+ TFieldName,
208
+ DeepValue<TFormData, TFieldName>,
209
+ ToFieldError<NoInfer<TFieldValidators>, never, TFormErrorTypes>,
210
+ TFormData,
211
+ TFormErrorTypes,
212
+ TFieldComponents
213
+ >
214
+ }
215
+ }
216
+ >
217
+
218
+ export type VueFormGroupSubscribeProps<
219
+ TGroupValue,
220
+ TGroupErrorTypes extends FormErrorTypes,
221
+ TSelected,
222
+ > = VueSubscribeProps<FormGroupState<TGroupValue, TGroupErrorTypes>, TSelected>
223
+
224
+ export type VueFormGroupSubscribeComponent<
225
+ in out TGroupValue,
226
+ in out TGroupErrorTypes extends FormErrorTypes,
227
+ > = new <TSelected>(
228
+ props: VueFormGroupSubscribeProps<TGroupValue, TGroupErrorTypes, TSelected> &
229
+ PublicProps,
230
+ ) => VueComponentInstance<
231
+ VueFormGroupSubscribeProps<TGroupValue, TGroupErrorTypes, TSelected>,
232
+ { default: NoInfer<TSelected> }
233
+ >
234
+
235
+ export type VueFormGroupFieldComponent<
236
+ in out TFormData,
237
+ in out TGroupValue,
238
+ in out TGroupErrorTypes extends FormErrorTypes,
239
+ in out TFormErrorTypes extends FormErrorTypes,
240
+ in out TFieldComponents extends Record<string, Component>,
241
+ > = new <
242
+ TFieldName extends DeepKeys<TGroupValue>,
243
+ const TFieldValidators extends FieldValidators<
244
+ TGroupValue,
245
+ TFieldName,
246
+ DeepValue<TGroupValue, TFieldName>
247
+ >,
248
+ >(
249
+ props: VueFormFieldProps<
250
+ TGroupValue,
251
+ TFieldName,
252
+ DeepValue<TGroupValue, TFieldName>,
253
+ TFieldValidators,
254
+ TGroupErrorTypes['fieldError'],
255
+ TFormData,
256
+ TFormErrorTypes,
257
+ TFieldComponents
258
+ > &
259
+ PublicProps,
260
+ ) => VueComponentInstance<
261
+ VueFormFieldProps<
262
+ TGroupValue,
263
+ TFieldName,
264
+ DeepValue<TGroupValue, TFieldName>,
265
+ TFieldValidators,
266
+ TGroupErrorTypes['fieldError'],
267
+ TFormData,
268
+ TFormErrorTypes,
269
+ TFieldComponents
270
+ >,
271
+ {
272
+ default: {
273
+ field: VueFieldApi<
274
+ TFieldName,
275
+ DeepValue<TGroupValue, TFieldName>,
276
+ ToFieldError<
277
+ NoInfer<TFieldValidators>,
278
+ TGroupErrorTypes['fieldError'],
279
+ TFormErrorTypes
280
+ >,
281
+ TFormData,
282
+ TFormErrorTypes,
283
+ TFieldComponents
284
+ >
285
+ }
286
+ }
287
+ >
288
+
289
+ export type VueFormGroupArrayFieldComponent<
290
+ in out TFormData,
291
+ in out TGroupValue,
292
+ in out TGroupErrorTypes extends FormErrorTypes,
293
+ in out TFormErrorTypes extends FormErrorTypes,
294
+ in out TFieldComponents extends Record<string, Component>,
295
+ > = new <
296
+ TFieldName extends DeepKeysWhereValueIncludes<TGroupValue, Array<any>>,
297
+ const TFieldValidators extends FieldValidators<
298
+ TGroupValue,
299
+ TFieldName,
300
+ DeepValue<TGroupValue, TFieldName>
301
+ >,
302
+ >(
303
+ props: VueFormFieldProps<
304
+ TGroupValue,
305
+ TFieldName,
306
+ DeepValue<TGroupValue, TFieldName>,
307
+ TFieldValidators,
308
+ TGroupErrorTypes['fieldError'],
309
+ TFormData,
310
+ TFormErrorTypes,
311
+ TFieldComponents
312
+ > &
313
+ PublicProps,
314
+ ) => VueComponentInstance<
315
+ VueFormFieldProps<
316
+ TGroupValue,
317
+ TFieldName,
318
+ DeepValue<TGroupValue, TFieldName>,
319
+ TFieldValidators,
320
+ TGroupErrorTypes['fieldError'],
321
+ TFormData,
322
+ TFormErrorTypes,
323
+ TFieldComponents
324
+ >,
325
+ {
326
+ default: {
327
+ field: VueFieldApi<
328
+ TFieldName,
329
+ DeepValue<TGroupValue, TFieldName>,
330
+ ToFieldError<
331
+ NoInfer<TFieldValidators>,
332
+ TGroupErrorTypes['fieldError'],
333
+ TFormErrorTypes
334
+ >,
335
+ TFormData,
336
+ TFormErrorTypes,
337
+ TFieldComponents
338
+ >
339
+ }
340
+ }
341
+ >
342
+
343
+ export interface VueFormGroupApi<
344
+ in out TFormData,
345
+ in out TGroupName,
346
+ in out TGroupValue,
347
+ in out TGroupErrorTypes extends FormErrorTypes,
348
+ in out TFormErrorTypes extends FormErrorTypes,
349
+ in out TFieldComponents extends Record<string, Component>,
350
+ > extends FormGroupApi<
351
+ TFormData,
352
+ TGroupName,
353
+ TGroupValue,
354
+ TGroupErrorTypes,
355
+ TFormErrorTypes
356
+ > {
357
+ Field: VueFormGroupFieldComponent<
358
+ TFormData,
359
+ TGroupValue,
360
+ TGroupErrorTypes,
361
+ TFormErrorTypes,
362
+ TFieldComponents
363
+ >
364
+ ArrayField: VueFormGroupArrayFieldComponent<
365
+ TFormData,
366
+ TGroupValue,
367
+ TGroupErrorTypes,
368
+ TFormErrorTypes,
369
+ TFieldComponents
370
+ >
371
+ Subscribe: VueFormGroupSubscribeComponent<TGroupValue, TGroupErrorTypes>
372
+ }
373
+
374
+ export interface VueFormGroupProps<
375
+ in out TFormData,
376
+ in out TGroupName,
377
+ in out TGroupValue,
378
+ in out TGroupValidators extends FormGroupValidators<TGroupValue>,
379
+ in out TFormErrorTypes extends FormErrorTypes,
380
+ in out TFieldComponents extends Record<string, Component>,
381
+ > extends Omit<
382
+ FormGroupOptions<
383
+ TFormData,
384
+ TGroupName,
385
+ TGroupValue,
386
+ TGroupValidators,
387
+ TFormErrorTypes
388
+ >,
389
+ 'form'
390
+ > {
391
+ readonly [fieldComponentsType]?: TFieldComponents
392
+ }
393
+
394
+ export type VueFormGroupComponent<
395
+ in out TFormData,
396
+ in out TFormErrorTypes extends FormErrorTypes,
397
+ in out TFieldComponents extends Record<string, Component>,
398
+ > = new <
399
+ TGroupName extends DeepKeys<TFormData>,
400
+ TGroupValue extends DeepValue<TFormData, TGroupName>,
401
+ const TGroupValidators extends FormGroupValidators<TGroupValue>,
402
+ >(
403
+ props: VueFormGroupProps<
404
+ TFormData,
405
+ TGroupName,
406
+ TGroupValue,
407
+ TGroupValidators,
408
+ TFormErrorTypes,
409
+ TFieldComponents
410
+ > &
411
+ PublicProps,
412
+ ) => VueComponentInstance<
413
+ VueFormGroupProps<
414
+ TFormData,
415
+ TGroupName,
416
+ TGroupValue,
417
+ TGroupValidators,
418
+ TFormErrorTypes,
419
+ TFieldComponents
420
+ >,
421
+ {
422
+ default: {
423
+ group: VueFormGroupApi<
424
+ TFormData,
425
+ TGroupName,
426
+ TGroupValue,
427
+ ToFormGroupErrorTypes<NoInfer<TGroupValidators>>,
428
+ TFormErrorTypes,
429
+ TFieldComponents
430
+ >
431
+ }
432
+ }
433
+ >
434
+
435
+ export interface VueTanStackFormComponents<
436
+ in out TFormData,
437
+ in out TFormErrorTypes extends FormErrorTypes,
438
+ in out TFieldComponents extends Record<string, Component> = Record<
439
+ never,
440
+ never
441
+ >,
442
+ > {
443
+ Field: VueFormFieldComponent<TFormData, TFormErrorTypes, TFieldComponents>
444
+ ArrayField: VueFormArrayFieldComponent<
445
+ TFormData,
446
+ TFormErrorTypes,
447
+ TFieldComponents
448
+ >
449
+ Subscribe: VueFormSubscribeComponent<TFormData, TFormErrorTypes>
450
+ FormGroup: VueFormGroupComponent<TFormData, TFormErrorTypes, TFieldComponents>
451
+ }
@@ -0,0 +1,35 @@
1
+ import { InternalFormApi } from '@tanstack/form-core/internals'
2
+ import { onMounted, onUnmounted, useId, watchEffect } from 'vue'
3
+ import { attachVueFormComponents } from './Components.lib'
4
+ import type { AnyInternalFormApi } from '@tanstack/form-core/internals'
5
+ import type { FormOptions } from '@tanstack/form-core'
6
+ import type { VueTanStackFormComponents } from './Components.public'
7
+
8
+ export interface InternalVueFormApi
9
+ extends AnyInternalFormApi, VueTanStackFormComponents<any, any, any> {}
10
+
11
+ export function initializeForm(
12
+ options: FormOptions<any, any, any>,
13
+ ): InternalVueFormApi {
14
+ return attachVueFormComponents(new InternalFormApi(options), null)
15
+ }
16
+
17
+ export function useInternalForm(
18
+ options: FormOptions<any, any, any>,
19
+ initializeFn: (options: FormOptions<any, any, any>) => InternalVueFormApi,
20
+ ) {
21
+ const vueFormId = useId()
22
+ const resolveOptions = () =>
23
+ options.formId === undefined ? { ...options, formId: vueFormId } : options
24
+ const form = initializeFn(resolveOptions())
25
+
26
+ watchEffect(() => form._update(resolveOptions()))
27
+
28
+ let unmount: (() => void) | undefined
29
+ onMounted(() => {
30
+ unmount = form.mount()
31
+ })
32
+ onUnmounted(() => unmount?.())
33
+
34
+ return form
35
+ }
@@ -0,0 +1,47 @@
1
+ import { shallow } from '@tanstack/vue-store'
2
+ import { shallowRef, toRaw, watch } from 'vue'
3
+ import type { ShallowRef } from 'vue'
4
+ import type {
5
+ AnyInternalFieldApi,
6
+ InternalBaseFieldMeta,
7
+ } from '@tanstack/form-core/internals'
8
+
9
+ function createFieldSelection<TSelected>(
10
+ fieldApi: ShallowRef<AnyInternalFieldApi>,
11
+ selector: (field: AnyInternalFieldApi) => TSelected,
12
+ ) {
13
+ const selected = shallowRef(selector(fieldApi.value)) as ShallowRef<TSelected>
14
+
15
+ watch(
16
+ fieldApi,
17
+ (field, _previous, onCleanup) => {
18
+ selected.value = selector(field)
19
+ const subscription = field.atom.subscribe(() => {
20
+ const next = selector(field)
21
+ if (!shallow(toRaw(selected.value), next)) selected.value = next
22
+ })
23
+ onCleanup(() => subscription.unsubscribe())
24
+ },
25
+ { immediate: true, flush: 'sync' },
26
+ )
27
+
28
+ return selected
29
+ }
30
+
31
+ export function createValueFieldSubscription(
32
+ fieldApi: ShallowRef<AnyInternalFieldApi>,
33
+ ) {
34
+ return createFieldSelection(fieldApi, (field) => ({
35
+ value: field.value,
36
+ meta: field.meta,
37
+ }))
38
+ }
39
+
40
+ export function createArrayFieldSubscription(
41
+ fieldApi: ShallowRef<AnyInternalFieldApi>,
42
+ ) {
43
+ return createFieldSelection(fieldApi, (field) => ({
44
+ length: field.value.length,
45
+ version: (field.meta as InternalBaseFieldMeta)._arrayVersion,
46
+ }))
47
+ }
@@ -0,0 +1,32 @@
1
+ import type { AnyFormApi, FormApi, FormErrorTypes } from '@tanstack/form-core'
2
+ import type { Component } from 'vue'
3
+ import type { VueTanStackFormComponents } from './Components.public'
4
+ import type {
5
+ AnyVueFormComponentMap,
6
+ DefaultVueFormComponentMap,
7
+ } from '../AppForm/componentMap.public'
8
+
9
+ type ExtendedFormApi<
10
+ TFormData,
11
+ TFormErrorTypes extends FormErrorTypes,
12
+ TFieldComponents extends Record<string, Component>,
13
+ > = FormApi<TFormData, TFormErrorTypes> &
14
+ VueTanStackFormComponents<TFormData, TFormErrorTypes, TFieldComponents>
15
+
16
+ export type VueFormApi<
17
+ TFormData,
18
+ TFormErrorTypes extends FormErrorTypes,
19
+ TComponents extends AnyVueFormComponentMap = DefaultVueFormComponentMap,
20
+ > = unknown extends TComponents['formComponents']
21
+ ? ExtendedFormApi<TFormData, TFormErrorTypes, TComponents['fieldComponents']>
22
+ : ExtendedFormApi<
23
+ TFormData,
24
+ TFormErrorTypes,
25
+ TComponents['fieldComponents']
26
+ > &
27
+ TComponents['formComponents']
28
+
29
+ export type AnyVueFormApi = AnyFormApi &
30
+ VueTanStackFormComponents<any, any, any>
31
+
32
+ export type { VueFormComponentMap } from '../AppForm/componentMap.public'
@@ -0,0 +1,46 @@
1
+ import type {
2
+ AnyFormOptions,
3
+ FormOptions,
4
+ FormValidators,
5
+ ToFormErrorTypes,
6
+ } from '@tanstack/form-core'
7
+ import type { AppFormOptions } from '../AppForm/appFormOptions.public'
8
+ import type {
9
+ AnyVueFormComponentMap,
10
+ DefaultVueFormComponentMap,
11
+ } from '../AppForm/componentMap.public'
12
+ import type { VueFormApi } from './formApiTypes.public'
13
+
14
+ type VueFormTypeErrorTypes<
15
+ TFormValidators extends FormValidators<any>,
16
+ TSubmitReturn,
17
+ > = unknown extends TSubmitReturn
18
+ ? any
19
+ : ToFormErrorTypes<TFormValidators, TSubmitReturn>
20
+
21
+ export type VueFormType<
22
+ TOptions extends
23
+ AnyFormOptions | AppFormOptions<any, any, any, AnyVueFormComponentMap>,
24
+ > =
25
+ TOptions extends AppFormOptions<
26
+ infer TFormData,
27
+ infer TFormValidators,
28
+ infer TSubmitReturn,
29
+ infer TComponents
30
+ >
31
+ ? VueFormApi<
32
+ TFormData,
33
+ VueFormTypeErrorTypes<TFormValidators, TSubmitReturn>,
34
+ TComponents
35
+ >
36
+ : TOptions extends FormOptions<
37
+ infer TFormData,
38
+ infer TFormValidators,
39
+ infer TSubmitReturn
40
+ >
41
+ ? VueFormApi<
42
+ TFormData,
43
+ VueFormTypeErrorTypes<TFormValidators, TSubmitReturn>,
44
+ DefaultVueFormComponentMap
45
+ >
46
+ : never
@@ -0,0 +1,64 @@
1
+ import { useSelector } from '@tanstack/vue-store'
2
+ import { onMounted, onUnmounted, shallowRef, watch, watchEffect } from 'vue'
3
+ import type { Component, ShallowRef } from 'vue'
4
+ import type {
5
+ AnyInternalFieldApi,
6
+ AnyInternalFormApi,
7
+ } from '@tanstack/form-core/internals'
8
+
9
+ export interface InternalFieldProps {
10
+ form: AnyInternalFormApi
11
+ name: string
12
+ [key: string]: unknown
13
+ }
14
+
15
+ export function useField(
16
+ options: () => InternalFieldProps,
17
+ fieldComponents: Record<string, Component> | null,
18
+ ): ShallowRef<AnyInternalFieldApi> {
19
+ const initialOptions = options()
20
+ const resetVersion = useSelector(initialOptions.form._atoms.resetVersion)
21
+
22
+ const createField = () => {
23
+ const current = options()
24
+ const field = current.form._getOrCreateFieldApi({
25
+ ...current,
26
+ name: current.name,
27
+ } as never)
28
+ if (fieldComponents !== null) Object.assign(field, fieldComponents)
29
+ return field
30
+ }
31
+
32
+ const fieldApi = shallowRef(createField())
33
+
34
+ watch(
35
+ [() => options().form, () => options().name, resetVersion],
36
+ () => {
37
+ fieldApi.value = createField()
38
+ },
39
+ { flush: 'sync' },
40
+ )
41
+
42
+ watchEffect(() => {
43
+ fieldApi.value._update(options() as never)
44
+ })
45
+
46
+ let mounted = false
47
+ let unregister: (() => void) | undefined
48
+ watch(
49
+ fieldApi,
50
+ (field) => {
51
+ if (!mounted) return
52
+ unregister?.()
53
+ unregister = field._register()
54
+ },
55
+ { flush: 'sync' },
56
+ )
57
+ onMounted(() => {
58
+ mounted = true
59
+ unregister = fieldApi.value._register()
60
+ })
61
+ onUnmounted(() => unregister?.())
62
+
63
+ return fieldApi
64
+ }
@@ -0,0 +1,30 @@
1
+ import { initializeForm, useInternalForm } from './VueFormApi.lib'
2
+ import type {
3
+ FormOptions,
4
+ FormValidators,
5
+ ToFormErrorTypes,
6
+ } from '@tanstack/form-core'
7
+ import type {
8
+ AnyVueFormComponentMap,
9
+ DefaultVueFormComponentMap,
10
+ } from '../AppForm/componentMap.public'
11
+ import type { VueFormApi } from './formApiTypes.public'
12
+
13
+ export type UseFormHook<in out TComponents extends AnyVueFormComponentMap> = <
14
+ TFormData,
15
+ const TFormValidators extends FormValidators<TFormData>,
16
+ TSubmitReturn,
17
+ >(
18
+ options: FormOptions<TFormData, TFormValidators, TSubmitReturn>,
19
+ ) => VueFormApi<
20
+ TFormData,
21
+ ToFormErrorTypes<TFormValidators, TSubmitReturn>,
22
+ TComponents
23
+ >
24
+
25
+ function useFormHook(options: FormOptions<any, any, any>) {
26
+ return useInternalForm(options, initializeForm)
27
+ }
28
+
29
+ export const useForm =
30
+ useFormHook as never as UseFormHook<DefaultVueFormComponentMap>