@tanstack/vue-form 2.0.0-alpha.0 → 2.0.0-alpha.2
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/dist/AppForm/createFormHook.public.d.ts +6 -3
- package/dist/AppForm/createFormHook.public.js +2 -4
- package/dist/AppForm/createFormHookTypes.public.d.ts +82 -6
- package/dist/AppForm/initializeAppForm.lib.js +6 -1
- package/dist/FieldGroup/FieldGroupApi.public.d.ts +1 -1
- package/dist/VueForm/Components.public.d.ts +2 -2
- package/dist/VueForm/formApiTypes.public.d.ts +26 -0
- package/dist/VueForm/formType.public.d.ts +24 -2
- package/dist/VueForm/useField.lib.js +2 -2
- package/dist/VueForm/useForm.public.d.ts +23 -1
- package/dist/VueForm/useForm.public.js +22 -0
- package/dist/index.d.ts +2 -3
- package/package.json +3 -4
- package/dist/AppForm/appFormOptions.public.d.ts +0 -14
- package/src/AppForm/Components.lib.ts +0 -31
- package/src/AppForm/VueAppFormApi.public.ts +0 -17
- package/src/AppForm/appFormOptions.public.ts +0 -55
- package/src/AppForm/componentMap.public.ts +0 -19
- package/src/AppForm/contexts.lib.ts +0 -31
- package/src/AppForm/createFormHook.public.ts +0 -32
- package/src/AppForm/createFormHookTypes.public.ts +0 -28
- package/src/AppForm/fieldComponentHelpers.lib.ts +0 -21
- package/src/AppForm/getFormHookHelpers.public.ts +0 -109
- package/src/AppForm/initializeAppForm.lib.ts +0 -18
- package/src/FieldGroup/FieldGroupApi.public.ts +0 -148
- package/src/FieldGroup/withFields.lib.ts +0 -103
- package/src/FieldGroup/withFields.public.ts +0 -191
- package/src/Subscribe.public.ts +0 -46
- package/src/VueForm/Components.lib.ts +0 -182
- package/src/VueForm/Components.public.ts +0 -451
- package/src/VueForm/VueFormApi.lib.ts +0 -35
- package/src/VueForm/fieldSubscriptions.lib.ts +0 -47
- package/src/VueForm/formApiTypes.public.ts +0 -32
- package/src/VueForm/formType.public.ts +0 -46
- package/src/VueForm/useField.lib.ts +0 -64
- package/src/VueForm/useForm.public.ts +0 -30
- package/src/index.ts +0 -16
- package/src/vueTypes.lib.ts +0 -31
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { AppFormHookResult, CreateFormHookOptions } from "./createFormHookTypes.public.js";
|
|
2
|
+
import { Component } from "vue";
|
|
3
3
|
//#region src/AppForm/createFormHook.public.d.ts
|
|
4
|
-
declare function createFormHook<const
|
|
4
|
+
declare function createFormHook<const TFormComponents extends Record<string, Component>, const TFieldComponents extends Record<string, Component>>(createOptions: CreateFormHookOptions<TFormComponents, TFieldComponents>): AppFormHookResult<{
|
|
5
|
+
formComponents: TFormComponents;
|
|
6
|
+
fieldComponents: TFieldComponents;
|
|
7
|
+
}>;
|
|
5
8
|
//#endregion
|
|
6
9
|
export { createFormHook };
|
|
@@ -2,11 +2,9 @@ import { useInternalForm } from "../VueForm/VueFormApi.lib.js";
|
|
|
2
2
|
import { defineFieldGroup } from "../FieldGroup/withFields.public.js";
|
|
3
3
|
import { useFormContext } from "./contexts.lib.js";
|
|
4
4
|
import { createAppFormInitializer } from "./initializeAppForm.lib.js";
|
|
5
|
+
import { formOptions } from "@tanstack/form-core";
|
|
5
6
|
|
|
6
7
|
//#region src/AppForm/createFormHook.public.ts
|
|
7
|
-
const appFormOptions = ((opts) => opts);
|
|
8
|
-
appFormOptions.strictSchema = (opts) => opts;
|
|
9
|
-
appFormOptions.looseSchema = (opts) => opts;
|
|
10
8
|
function createFormHook(createOptions) {
|
|
11
9
|
const initializeAppForm = createAppFormInitializer(createOptions);
|
|
12
10
|
function useExtendedForm(options) {
|
|
@@ -14,7 +12,7 @@ function createFormHook(createOptions) {
|
|
|
14
12
|
}
|
|
15
13
|
return {
|
|
16
14
|
useFormContext,
|
|
17
|
-
appFormOptions,
|
|
15
|
+
appFormOptions: formOptions,
|
|
18
16
|
defineAppFieldGroup: defineFieldGroup,
|
|
19
17
|
useAppForm: useExtendedForm
|
|
20
18
|
};
|
|
@@ -1,15 +1,91 @@
|
|
|
1
|
-
import { AnyVueFormComponentMap } from "./componentMap.public.js";
|
|
2
|
-
import { AppFormOptionsApi } from "./appFormOptions.public.js";
|
|
1
|
+
import { AnyVueFormComponentMap, VueFormComponentMap } from "./componentMap.public.js";
|
|
3
2
|
import { DefineFieldGroupFn } from "../FieldGroup/withFields.public.js";
|
|
4
3
|
import { VueAppFormApi } from "./VueAppFormApi.public.js";
|
|
5
|
-
import { FormOptions, FormValidators, ToFormErrorTypes } from "@tanstack/form-core";
|
|
4
|
+
import { DefaultFieldOptions, DefaultFormGroupOptions, DefaultFormOptions, FormOptions, FormOptionsApi, FormValidators, ToFormErrorTypes } from "@tanstack/form-core";
|
|
5
|
+
import { Component } from "vue";
|
|
6
6
|
//#region src/AppForm/createFormHookTypes.public.d.ts
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Configures the components and reusable defaults returned by
|
|
9
|
+
* `createFormHook`.
|
|
10
|
+
*
|
|
11
|
+
* Form core resolves each default object before the corresponding usage-site
|
|
12
|
+
* options. Non-listener properties passed at the usage site take precedence,
|
|
13
|
+
* including when explicitly set to `undefined`. Listener arrays follow the
|
|
14
|
+
* configured `listenersMerge` strategy.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* const { useAppForm } = createFormHook({
|
|
19
|
+
* formComponents: {},
|
|
20
|
+
* fieldComponents: {
|
|
21
|
+
* TextField,
|
|
22
|
+
* },
|
|
23
|
+
* defaultFormOptions: {
|
|
24
|
+
* errorVisibility: ({ fieldState }) => fieldState.meta.isBlurred,
|
|
25
|
+
* },
|
|
26
|
+
* defaultFieldOptions: {
|
|
27
|
+
* errorBoundary: true,
|
|
28
|
+
* },
|
|
29
|
+
* })
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @typeParam TFormComponents - Library-managed. Do not specify explicitly.
|
|
33
|
+
* @typeParam TFieldComponents - Library-managed. Do not specify explicitly.
|
|
34
|
+
*/
|
|
35
|
+
interface CreateFormHookOptions<TFormComponents extends Record<string, Component>, TFieldComponents extends Record<string, Component>> extends VueFormComponentMap<TFormComponents, TFieldComponents> {
|
|
36
|
+
/**
|
|
37
|
+
* Defaults for every form created by `useAppForm`.
|
|
38
|
+
*
|
|
39
|
+
* Non-listener options passed to `useAppForm` override these defaults,
|
|
40
|
+
* including when explicitly set to `undefined`. Listener arrays follow
|
|
41
|
+
* `listenersMerge`.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* defaultFormOptions: {
|
|
46
|
+
* errorVisibility: ({ state }) => state.submissionAttempts > 0,
|
|
47
|
+
* },
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
defaultFormOptions?: DefaultFormOptions;
|
|
51
|
+
/**
|
|
52
|
+
* Defaults for every field and array-field component owned by the form.
|
|
53
|
+
*
|
|
54
|
+
* Non-listener options passed to the component override these defaults,
|
|
55
|
+
* including when explicitly set to `undefined`. Listener arrays follow
|
|
56
|
+
* `listenersMerge`. This includes `group.Field` and `group.ArrayField`.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* defaultFieldOptions: {
|
|
61
|
+
* errorVisibility: ({ fieldState }) => fieldState.meta.isBlurred,
|
|
62
|
+
* },
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
defaultFieldOptions?: DefaultFieldOptions;
|
|
66
|
+
/**
|
|
67
|
+
* Defaults for every `form.FormGroup` component.
|
|
68
|
+
*
|
|
69
|
+
* Options passed to the component override these defaults, including when
|
|
70
|
+
* an option is explicitly `undefined`.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```ts
|
|
74
|
+
* defaultFormGroupOptions: {
|
|
75
|
+
* onSubmitInvalid: ({ groupApi }) => {
|
|
76
|
+
* console.error('Invalid group', groupApi.name)
|
|
77
|
+
* },
|
|
78
|
+
* },
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
defaultFormGroupOptions?: DefaultFormGroupOptions;
|
|
82
|
+
}
|
|
83
|
+
type UseAppFormHook<TComponents extends AnyVueFormComponentMap> = <TFormData, const TFormValidators extends FormValidators<TFormData>, TSubmitReturn>(options: FormOptions<TFormData, TFormValidators, TSubmitReturn, unknown>) => VueAppFormApi<TFormData, ToFormErrorTypes<TFormValidators, TSubmitReturn>, TComponents>;
|
|
8
84
|
interface AppFormHookResult<TComponents extends AnyVueFormComponentMap> {
|
|
9
|
-
appFormOptions:
|
|
85
|
+
appFormOptions: FormOptionsApi<TComponents>;
|
|
10
86
|
defineAppFieldGroup: DefineFieldGroupFn<TComponents['fieldComponents']>;
|
|
11
87
|
useAppForm: UseAppFormHook<TComponents>;
|
|
12
88
|
useFormContext: () => VueAppFormApi<any, any, TComponents>;
|
|
13
89
|
}
|
|
14
90
|
//#endregion
|
|
15
|
-
export { AppFormHookResult, UseAppFormHook };
|
|
91
|
+
export { AppFormHookResult, CreateFormHookOptions, UseAppFormHook };
|
|
@@ -3,7 +3,12 @@ import { InternalFormApi } from "@tanstack/form-core/internals";
|
|
|
3
3
|
|
|
4
4
|
//#region src/AppForm/initializeAppForm.lib.ts
|
|
5
5
|
function createAppFormInitializer(createOptions) {
|
|
6
|
-
|
|
6
|
+
const defaultOptions = createOptions.defaultFormOptions || createOptions.defaultFieldOptions || createOptions.defaultFormGroupOptions ? {
|
|
7
|
+
form: createOptions.defaultFormOptions,
|
|
8
|
+
field: createOptions.defaultFieldOptions,
|
|
9
|
+
formGroup: createOptions.defaultFormGroupOptions
|
|
10
|
+
} : void 0;
|
|
11
|
+
return (options) => attachVueAppFormComponents(new InternalFormApi(options, defaultOptions), createOptions.formComponents, createOptions.fieldComponents);
|
|
7
12
|
}
|
|
8
13
|
|
|
9
14
|
//#endregion
|
|
@@ -15,7 +15,7 @@ type FieldGroupArrayFieldComponent<in out TFieldData, in out TFieldComponents ex
|
|
|
15
15
|
};
|
|
16
16
|
}>;
|
|
17
17
|
type FieldGroupSubscribeProps<TSelected> = VueFormSubscribeProps<unknown, FormErrorTypes, TSelected>;
|
|
18
|
-
type FieldGroupSubscribeComponent = new <TSelected>(props: FieldGroupSubscribeProps<TSelected> & PublicProps) => VueComponentInstance<FieldGroupSubscribeProps<TSelected>, {
|
|
18
|
+
type FieldGroupSubscribeComponent = new <const TSelected>(props: FieldGroupSubscribeProps<TSelected> & PublicProps) => VueComponentInstance<FieldGroupSubscribeProps<TSelected>, {
|
|
19
19
|
default: NoInfer<TSelected>;
|
|
20
20
|
}>;
|
|
21
21
|
interface FieldGroupApi<in out TFieldData, in out TFieldComponents extends Record<string, Component> = Record<never, never>> extends FormApiFieldMethods<TFieldData>, FormApiArrayMethods<TFieldData> {
|
|
@@ -18,7 +18,7 @@ interface VueSubscribeProps<in out TSourceData, in out TSelected> {
|
|
|
18
18
|
when?: (selected: NoInfer<TSelected>) => boolean;
|
|
19
19
|
}
|
|
20
20
|
type VueFormSubscribeProps<TFormData, TFormErrorTypes extends FormErrorTypes, TSelected> = VueSubscribeProps<FormState<TFormData, TFormErrorTypes>, TSelected>;
|
|
21
|
-
type VueFormSubscribeComponent<in out TFormData, in out TFormErrorTypes extends FormErrorTypes> = new <TSelected>(props: VueFormSubscribeProps<TFormData, TFormErrorTypes, TSelected> & PublicProps) => VueComponentInstance<VueFormSubscribeProps<TFormData, TFormErrorTypes, TSelected>, {
|
|
21
|
+
type VueFormSubscribeComponent<in out TFormData, in out TFormErrorTypes extends FormErrorTypes> = new <const TSelected>(props: VueFormSubscribeProps<TFormData, TFormErrorTypes, TSelected> & PublicProps) => VueComponentInstance<VueFormSubscribeProps<TFormData, TFormErrorTypes, TSelected>, {
|
|
22
22
|
default: NoInfer<TSelected>;
|
|
23
23
|
}>;
|
|
24
24
|
interface VueFormFieldProps<in out TFieldData, in out TFieldName, in out TFieldValue, in out TFieldValidators extends FieldValidators<TFieldData, TFieldName, TFieldValue>, in out TGroupFieldError, in out TFormData, in out TFormErrorTypes extends FormErrorTypes, in out TFieldComponents extends Record<string, Component>> extends FieldApiOptions<TFieldData, TFieldName, TFieldValue, TFieldValidators, TGroupFieldError, TFormData, TFormErrorTypes> {
|
|
@@ -35,7 +35,7 @@ type VueFormArrayFieldComponent<in out TFormData, in out TFormErrorTypes extends
|
|
|
35
35
|
};
|
|
36
36
|
}>;
|
|
37
37
|
type VueFormGroupSubscribeProps<TGroupValue, TGroupErrorTypes extends FormErrorTypes, TSelected> = VueSubscribeProps<FormGroupState<TGroupValue, TGroupErrorTypes>, TSelected>;
|
|
38
|
-
type VueFormGroupSubscribeComponent<in out TGroupValue, in out TGroupErrorTypes extends FormErrorTypes> = new <TSelected>(props: VueFormGroupSubscribeProps<TGroupValue, TGroupErrorTypes, TSelected> & PublicProps) => VueComponentInstance<VueFormGroupSubscribeProps<TGroupValue, TGroupErrorTypes, TSelected>, {
|
|
38
|
+
type VueFormGroupSubscribeComponent<in out TGroupValue, in out TGroupErrorTypes extends FormErrorTypes> = new <const TSelected>(props: VueFormGroupSubscribeProps<TGroupValue, TGroupErrorTypes, TSelected> & PublicProps) => VueComponentInstance<VueFormGroupSubscribeProps<TGroupValue, TGroupErrorTypes, TSelected>, {
|
|
39
39
|
default: NoInfer<TSelected>;
|
|
40
40
|
}>;
|
|
41
41
|
type VueFormGroupFieldComponent<in out TFormData, in out TGroupValue, in out TGroupErrorTypes extends FormErrorTypes, in out TFormErrorTypes extends FormErrorTypes, in out TFieldComponents extends Record<string, Component>> = new <TFieldName extends DeepKeys<TGroupValue>, const TFieldValidators extends FieldValidators<TGroupValue, TFieldName, DeepValue<TGroupValue, TFieldName>>>(props: VueFormFieldProps<TGroupValue, TFieldName, DeepValue<TGroupValue, TFieldName>, TFieldValidators, TGroupErrorTypes['fieldError'], TFormData, TFormErrorTypes, TFieldComponents> & PublicProps) => VueComponentInstance<VueFormFieldProps<TGroupValue, TFieldName, DeepValue<TGroupValue, TFieldName>, TFieldValidators, TGroupErrorTypes['fieldError'], TFormData, TFormErrorTypes, TFieldComponents>, {
|
|
@@ -5,6 +5,32 @@ import { Component } from "vue";
|
|
|
5
5
|
//#region src/VueForm/formApiTypes.public.d.ts
|
|
6
6
|
type ExtendedFormApi<TFormData, TFormErrorTypes extends FormErrorTypes, TFieldComponents extends Record<string, Component>> = FormApi<TFormData, TFormErrorTypes> & VueTanStackFormComponents<TFormData, TFormErrorTypes, TFieldComponents>;
|
|
7
7
|
type VueFormApi<TFormData, TFormErrorTypes extends FormErrorTypes, TComponents extends AnyVueFormComponentMap = DefaultVueFormComponentMap> = unknown extends TComponents['formComponents'] ? ExtendedFormApi<TFormData, TFormErrorTypes, TComponents['fieldComponents']> : ExtendedFormApi<TFormData, TFormErrorTypes, TComponents['fieldComponents']> & TComponents['formComponents'];
|
|
8
|
+
/**
|
|
9
|
+
* A Vue form API whose form data and error types are erased.
|
|
10
|
+
*
|
|
11
|
+
* Use it for reusable Vue components that only need core form operations and
|
|
12
|
+
* the `Field`, `ArrayField`, `Subscribe`, or `FormGroup` components common to
|
|
13
|
+
* every Vue form. Field paths and values are not checked against a particular
|
|
14
|
+
* form shape; use `VueFormType` when a component depends on one known form.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```vue
|
|
18
|
+
* <script setup lang="ts">
|
|
19
|
+
* defineProps<{ form: AnyVueFormApi }>()
|
|
20
|
+
* </script>
|
|
21
|
+
*
|
|
22
|
+
* <template>
|
|
23
|
+
* <form.Subscribe
|
|
24
|
+
* :selector="(state) => state.isSubmitting"
|
|
25
|
+
* v-slot="isSubmitting"
|
|
26
|
+
* >
|
|
27
|
+
* <button type="submit" :disabled="isSubmitting">
|
|
28
|
+
* {{ isSubmitting ? 'Saving...' : 'Save' }}
|
|
29
|
+
* </button>
|
|
30
|
+
* </form.Subscribe>
|
|
31
|
+
* </template>
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
8
34
|
type AnyVueFormApi = AnyFormApi & VueTanStackFormComponents<any, any, any>;
|
|
9
35
|
//#endregion
|
|
10
36
|
export { AnyVueFormApi, VueFormApi, type VueFormComponentMap };
|
|
@@ -1,9 +1,31 @@
|
|
|
1
1
|
import { AnyVueFormComponentMap, DefaultVueFormComponentMap } from "../AppForm/componentMap.public.js";
|
|
2
2
|
import { VueFormApi } from "./formApiTypes.public.js";
|
|
3
|
-
import { AppFormOptions } from "../AppForm/appFormOptions.public.js";
|
|
4
3
|
import { AnyFormOptions, FormOptions, FormValidators, ToFormErrorTypes } from "@tanstack/form-core";
|
|
5
4
|
//#region src/VueForm/formType.public.d.ts
|
|
6
5
|
type VueFormTypeErrorTypes<TFormValidators extends FormValidators<any>, TSubmitReturn> = unknown extends TSubmitReturn ? any : ToFormErrorTypes<TFormValidators, TSubmitReturn>;
|
|
7
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Derives the Vue form API type represented by a reusable options object.
|
|
8
|
+
*
|
|
9
|
+
* Use it to type props for components that belong to one known form shape. It
|
|
10
|
+
* preserves the inferred form data and any components registered through
|
|
11
|
+
* `appFormOptions`. Options such as `onSubmit` can be defined either in the
|
|
12
|
+
* shared options or when the form is created in the component.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* const profileOptions = formOptions({
|
|
17
|
+
* defaultValues: { name: '' },
|
|
18
|
+
* })
|
|
19
|
+
*
|
|
20
|
+
* type ProfileForm = VueFormType<typeof profileOptions>
|
|
21
|
+
*
|
|
22
|
+
* const props = defineProps<{
|
|
23
|
+
* form: ProfileForm
|
|
24
|
+
* }>()
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @typeParam TOptions - The reusable form or app-form options from which the API derives its form data, error, and registered-component types.
|
|
28
|
+
*/
|
|
29
|
+
type VueFormType<TOptions extends AnyFormOptions> = TOptions extends FormOptions<infer TFormData, infer TFormValidators, infer TSubmitReturn, infer TComponents> ? VueFormApi<TFormData, VueFormTypeErrorTypes<TFormValidators, TSubmitReturn>, TComponents extends AnyVueFormComponentMap ? TComponents : DefaultVueFormComponentMap> : never;
|
|
8
30
|
//#endregion
|
|
9
31
|
export { VueFormType };
|
|
@@ -10,7 +10,7 @@ function useField(options, fieldComponents) {
|
|
|
10
10
|
const field = current.form._getOrCreateFieldApi({
|
|
11
11
|
...current,
|
|
12
12
|
name: current.name
|
|
13
|
-
});
|
|
13
|
+
}, "field");
|
|
14
14
|
if (fieldComponents !== null) Object.assign(field, fieldComponents);
|
|
15
15
|
return field;
|
|
16
16
|
};
|
|
@@ -23,7 +23,7 @@ function useField(options, fieldComponents) {
|
|
|
23
23
|
fieldApi.value = createField();
|
|
24
24
|
}, { flush: "sync" });
|
|
25
25
|
watchEffect(() => {
|
|
26
|
-
fieldApi.value._update(options());
|
|
26
|
+
fieldApi.value._update(options(), "field");
|
|
27
27
|
});
|
|
28
28
|
let mounted = false;
|
|
29
29
|
let unregister;
|
|
@@ -2,7 +2,29 @@ import { AnyVueFormComponentMap, DefaultVueFormComponentMap } from "../AppForm/c
|
|
|
2
2
|
import { VueFormApi } from "./formApiTypes.public.js";
|
|
3
3
|
import { FormOptions, FormValidators, ToFormErrorTypes } from "@tanstack/form-core";
|
|
4
4
|
//#region src/VueForm/useForm.public.d.ts
|
|
5
|
-
type UseFormHook<in out TComponents extends AnyVueFormComponentMap> = <TFormData, const TFormValidators extends FormValidators<TFormData>, TSubmitReturn>(options: FormOptions<TFormData, TFormValidators, TSubmitReturn>) => VueFormApi<TFormData, ToFormErrorTypes<TFormValidators, TSubmitReturn>, TComponents>;
|
|
5
|
+
type UseFormHook<in out TComponents extends AnyVueFormComponentMap> = <TFormData, const TFormValidators extends FormValidators<TFormData>, TSubmitReturn>(options: FormOptions<TFormData, TFormValidators, TSubmitReturn, unknown>) => VueFormApi<TFormData, ToFormErrorTypes<TFormValidators, TSubmitReturn>, TComponents>;
|
|
6
|
+
/**
|
|
7
|
+
* Creates a Vue form whose instance and lifecycle are owned by the current
|
|
8
|
+
* component.
|
|
9
|
+
*
|
|
10
|
+
* `defaultValues` establish the initial state and inferred form value type. To
|
|
11
|
+
* update the existing form after creation, pass a reactive options object;
|
|
12
|
+
* tracked changes are applied without replacing the form instance.
|
|
13
|
+
*
|
|
14
|
+
* Call this during the component's setup phase. The form mounts with the
|
|
15
|
+
* component and is cleaned up when the component unmounts.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* const form = useForm({
|
|
20
|
+
* defaultValues: { name: '' },
|
|
21
|
+
* onSubmit: ({ value }) => saveProfile(value),
|
|
22
|
+
* })
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @returns The Vue form API with typed field, subscription, and form-group
|
|
26
|
+
* components attached.
|
|
27
|
+
*/
|
|
6
28
|
declare const useForm: UseFormHook<DefaultVueFormComponentMap>;
|
|
7
29
|
//#endregion
|
|
8
30
|
export { UseFormHook, useForm };
|
|
@@ -4,6 +4,28 @@ import { initializeForm, useInternalForm } from "./VueFormApi.lib.js";
|
|
|
4
4
|
function useFormHook(options) {
|
|
5
5
|
return useInternalForm(options, initializeForm);
|
|
6
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* Creates a Vue form whose instance and lifecycle are owned by the current
|
|
9
|
+
* component.
|
|
10
|
+
*
|
|
11
|
+
* `defaultValues` establish the initial state and inferred form value type. To
|
|
12
|
+
* update the existing form after creation, pass a reactive options object;
|
|
13
|
+
* tracked changes are applied without replacing the form instance.
|
|
14
|
+
*
|
|
15
|
+
* Call this during the component's setup phase. The form mounts with the
|
|
16
|
+
* component and is cleaned up when the component unmounts.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const form = useForm({
|
|
21
|
+
* defaultValues: { name: '' },
|
|
22
|
+
* onSubmit: ({ value }) => saveProfile(value),
|
|
23
|
+
* })
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @returns The Vue form API with typed field, subscription, and form-group
|
|
27
|
+
* components attached.
|
|
28
|
+
*/
|
|
7
29
|
const useForm = useFormHook;
|
|
8
30
|
|
|
9
31
|
//#endregion
|
package/dist/index.d.ts
CHANGED
|
@@ -2,15 +2,14 @@ import { AnyVueFormComponentMap, DefaultVueFormComponentMap, VueFormComponentMap
|
|
|
2
2
|
import { VueFieldApi, VueFormArrayFieldComponent, VueFormFieldComponent, VueFormFieldProps, VueFormGroupApi, VueFormGroupArrayFieldComponent, VueFormGroupComponent, VueFormGroupFieldComponent, VueFormGroupProps, VueFormGroupSubscribeComponent, VueFormGroupSubscribeProps, VueFormSubscribeComponent, VueFormSubscribeProps, VueTanStackFormComponents } from "./VueForm/Components.public.js";
|
|
3
3
|
import { AnyVueFormApi, VueFormApi } from "./VueForm/formApiTypes.public.js";
|
|
4
4
|
import { UseFormHook, useForm } from "./VueForm/useForm.public.js";
|
|
5
|
-
import { AppFormOptions, AppFormOptionsApi } from "./AppForm/appFormOptions.public.js";
|
|
6
5
|
import { VueFormType } from "./VueForm/formType.public.js";
|
|
7
6
|
import { Subscribe, SubscribeComponent, SubscribeProps, SubscribeSource } from "./Subscribe.public.js";
|
|
8
7
|
import { AnyFieldGroupApi, FieldGroupApi, FieldGroupArrayFieldComponent, FieldGroupFieldComponent, FieldGroupFormState, FieldGroupSubscribeComponent, FieldGroupSubscribeProps } from "./FieldGroup/FieldGroupApi.public.js";
|
|
9
8
|
import { AnyFieldGroupFieldSlot, DefineFieldGroupFn, FieldGroupDefinition, FieldGroupFieldBindingForSlot, FieldGroupFieldBindings, FieldGroupFieldBindingsOf, FieldGroupFieldComponentsOf, FieldGroupFieldData, FieldGroupFieldNameForSlot, FieldGroupFieldNames, FieldGroupFieldSlot, FieldGroupFieldSlotAllows, FieldGroupFieldSlotMode, FieldGroupFieldSlotModeOf, FieldGroupFieldSlotValue, FieldGroupFields, FieldGroupFieldsOf, FieldGroupFieldsPropName, FieldGroupForm, FieldGroupHelper, FieldGroupWithFieldsFn, LooseFieldGroupFieldSlot, StrictFieldGroupFieldSlot, VueFieldGroup, defineFieldGroup } from "./FieldGroup/withFields.public.js";
|
|
10
9
|
import { AppFormComponent, VueAppFormApi } from "./AppForm/VueAppFormApi.public.js";
|
|
11
|
-
import { AppFormHookResult, UseAppFormHook } from "./AppForm/createFormHookTypes.public.js";
|
|
10
|
+
import { AppFormHookResult, CreateFormHookOptions, UseAppFormHook } from "./AppForm/createFormHookTypes.public.js";
|
|
12
11
|
import { createFormHook } from "./AppForm/createFormHook.public.js";
|
|
13
12
|
import { FormHookHelpers, getFormHookHelpers } from "./AppForm/getFormHookHelpers.public.js";
|
|
14
13
|
export * from "@tanstack/form-core";
|
|
15
14
|
export * from "@tanstack/vue-store";
|
|
16
|
-
export { AnyFieldGroupApi, AnyFieldGroupFieldSlot, AnyVueFormApi, AnyVueFormComponentMap, AppFormComponent, AppFormHookResult,
|
|
15
|
+
export { AnyFieldGroupApi, AnyFieldGroupFieldSlot, AnyVueFormApi, AnyVueFormComponentMap, AppFormComponent, AppFormHookResult, CreateFormHookOptions, DefaultVueFormComponentMap, DefineFieldGroupFn, FieldGroupApi, FieldGroupArrayFieldComponent, FieldGroupDefinition, FieldGroupFieldBindingForSlot, FieldGroupFieldBindings, FieldGroupFieldBindingsOf, FieldGroupFieldComponent, FieldGroupFieldComponentsOf, FieldGroupFieldData, FieldGroupFieldNameForSlot, FieldGroupFieldNames, FieldGroupFieldSlot, FieldGroupFieldSlotAllows, FieldGroupFieldSlotMode, FieldGroupFieldSlotModeOf, FieldGroupFieldSlotValue, FieldGroupFields, FieldGroupFieldsOf, FieldGroupFieldsPropName, FieldGroupForm, FieldGroupFormState, FieldGroupHelper, FieldGroupSubscribeComponent, FieldGroupSubscribeProps, FieldGroupWithFieldsFn, FormHookHelpers, LooseFieldGroupFieldSlot, StrictFieldGroupFieldSlot, Subscribe, SubscribeComponent, SubscribeProps, SubscribeSource, UseAppFormHook, UseFormHook, VueAppFormApi, VueFieldApi, VueFieldGroup, VueFormApi, VueFormArrayFieldComponent, VueFormComponentMap, VueFormFieldComponent, VueFormFieldProps, VueFormGroupApi, VueFormGroupArrayFieldComponent, VueFormGroupComponent, VueFormGroupFieldComponent, VueFormGroupProps, VueFormGroupSubscribeComponent, VueFormGroupSubscribeProps, VueFormSubscribeComponent, VueFormSubscribeProps, VueFormType, VueTanStackFormComponents, createFormHook, defineFieldGroup, getFormHookHelpers, useForm };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/vue-form",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.2",
|
|
4
4
|
"description": "Powerful, type-safe forms for Vue.",
|
|
5
5
|
"author": "tannerlinsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -22,12 +22,11 @@
|
|
|
22
22
|
},
|
|
23
23
|
"sideEffects": false,
|
|
24
24
|
"files": [
|
|
25
|
-
"dist"
|
|
26
|
-
"src"
|
|
25
|
+
"dist"
|
|
27
26
|
],
|
|
28
27
|
"dependencies": {
|
|
29
28
|
"@tanstack/vue-store": "^0.11.1",
|
|
30
|
-
"@tanstack/form-core": "2.0.0-alpha.
|
|
29
|
+
"@tanstack/form-core": "2.0.0-alpha.2"
|
|
31
30
|
},
|
|
32
31
|
"devDependencies": {
|
|
33
32
|
"@testing-library/vue": "^8.1.0",
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { AnyVueFormComponentMap } from "./componentMap.public.js";
|
|
2
|
-
import { FormOptions, FormValidatorData, FormValidators, InferUnion, NullableSchemaData } from "@tanstack/form-core";
|
|
3
|
-
//#region src/AppForm/appFormOptions.public.d.ts
|
|
4
|
-
declare const componentsSymbol: unique symbol;
|
|
5
|
-
interface AppFormOptions<TFormData, TFormValidators extends FormValidators<TFormData>, TSubmitReturn, TComponents extends AnyVueFormComponentMap> extends FormOptions<TFormData, TFormValidators, TSubmitReturn> {
|
|
6
|
-
[componentsSymbol]: TComponents;
|
|
7
|
-
}
|
|
8
|
-
interface AppFormOptionsApi<TComponents extends AnyVueFormComponentMap> {
|
|
9
|
-
<TFormData, const TFormValidators extends FormValidators<TFormData>, TSubmitReturn>(options: FormOptions<TFormData, TFormValidators, TSubmitReturn>): AppFormOptions<TFormData, TFormValidators, TSubmitReturn, TComponents>;
|
|
10
|
-
strictSchema: <const TFormValidators extends FormValidators<any>, TFormData extends FormValidatorData<TFormValidators>, TSubmitReturn>(options: FormOptions<TFormData, TFormValidators, TSubmitReturn>) => AppFormOptions<FormValidatorData<TFormValidators>, TFormValidators, TSubmitReturn, TComponents>;
|
|
11
|
-
looseSchema: <const TFormValidators extends FormValidators<any>, const TFormData extends NullableSchemaData<TFormValidators>, TSubmitReturn>(options: FormOptions<TFormData, TFormValidators, TSubmitReturn>) => AppFormOptions<InferUnion<TFormData, FormValidatorData<TFormValidators>>, TFormValidators, TSubmitReturn, TComponents>;
|
|
12
|
-
}
|
|
13
|
-
//#endregion
|
|
14
|
-
export { AppFormOptions, AppFormOptionsApi };
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { defineComponent, provide } from 'vue'
|
|
2
|
-
import { attachVueFormComponents } from '../VueForm/Components.lib'
|
|
3
|
-
import { FieldContext, FormContext } from './contexts.lib'
|
|
4
|
-
import type { Component } from 'vue'
|
|
5
|
-
import type { AnyInternalFormApi } from '@tanstack/form-core/internals'
|
|
6
|
-
import type { AnyVueFormComponentMap } from './componentMap.public'
|
|
7
|
-
import type { VueAppFormApi } from './VueAppFormApi.public'
|
|
8
|
-
|
|
9
|
-
type AnyVueAppFormApi = VueAppFormApi<any, any, AnyVueFormComponentMap>
|
|
10
|
-
|
|
11
|
-
export function attachVueAppFormComponents(
|
|
12
|
-
form: AnyInternalFormApi,
|
|
13
|
-
formComponents: Record<string, Component>,
|
|
14
|
-
fieldComponents: Record<string, Component>,
|
|
15
|
-
): AnyVueAppFormApi {
|
|
16
|
-
const resultForm = attachVueFormComponents(
|
|
17
|
-
form,
|
|
18
|
-
fieldComponents,
|
|
19
|
-
FieldContext,
|
|
20
|
-
) as never as AnyVueAppFormApi
|
|
21
|
-
|
|
22
|
-
resultForm.AppForm = defineComponent(
|
|
23
|
-
(_props, { slots }) => {
|
|
24
|
-
provide(FormContext, resultForm as never)
|
|
25
|
-
return () => slots.default?.()
|
|
26
|
-
},
|
|
27
|
-
{ name: 'TanStackForm.AppForm' },
|
|
28
|
-
) as never
|
|
29
|
-
|
|
30
|
-
return Object.assign(resultForm, formComponents)
|
|
31
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { FormErrorTypes } from '@tanstack/form-core'
|
|
2
|
-
import type { PublicProps } from 'vue'
|
|
3
|
-
import type { VueComponentInstance } from '../vueTypes.lib'
|
|
4
|
-
import type { VueFormApi } from '../VueForm/formApiTypes.public'
|
|
5
|
-
import type { AnyVueFormComponentMap } from './componentMap.public'
|
|
6
|
-
|
|
7
|
-
export type AppFormComponent = new (
|
|
8
|
-
props: PublicProps,
|
|
9
|
-
) => VueComponentInstance<{}, { default: {} }>
|
|
10
|
-
|
|
11
|
-
export type VueAppFormApi<
|
|
12
|
-
TFormData,
|
|
13
|
-
TFormErrorTypes extends FormErrorTypes,
|
|
14
|
-
TComponents extends AnyVueFormComponentMap,
|
|
15
|
-
> = VueFormApi<TFormData, TFormErrorTypes, TComponents> & {
|
|
16
|
-
AppForm: AppFormComponent
|
|
17
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
FormOptions,
|
|
3
|
-
FormValidatorData,
|
|
4
|
-
FormValidators,
|
|
5
|
-
InferUnion,
|
|
6
|
-
NullableSchemaData,
|
|
7
|
-
} from '@tanstack/form-core'
|
|
8
|
-
import type { AnyVueFormComponentMap } from './componentMap.public'
|
|
9
|
-
|
|
10
|
-
declare const componentsSymbol: unique symbol
|
|
11
|
-
|
|
12
|
-
export interface AppFormOptions<
|
|
13
|
-
TFormData,
|
|
14
|
-
TFormValidators extends FormValidators<TFormData>,
|
|
15
|
-
TSubmitReturn,
|
|
16
|
-
TComponents extends AnyVueFormComponentMap,
|
|
17
|
-
> extends FormOptions<TFormData, TFormValidators, TSubmitReturn> {
|
|
18
|
-
[componentsSymbol]: TComponents
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface AppFormOptionsApi<TComponents extends AnyVueFormComponentMap> {
|
|
22
|
-
<
|
|
23
|
-
TFormData,
|
|
24
|
-
const TFormValidators extends FormValidators<TFormData>,
|
|
25
|
-
TSubmitReturn,
|
|
26
|
-
>(
|
|
27
|
-
options: FormOptions<TFormData, TFormValidators, TSubmitReturn>,
|
|
28
|
-
): AppFormOptions<TFormData, TFormValidators, TSubmitReturn, TComponents>
|
|
29
|
-
|
|
30
|
-
strictSchema: <
|
|
31
|
-
const TFormValidators extends FormValidators<any>,
|
|
32
|
-
TFormData extends FormValidatorData<TFormValidators>,
|
|
33
|
-
TSubmitReturn,
|
|
34
|
-
>(
|
|
35
|
-
options: FormOptions<TFormData, TFormValidators, TSubmitReturn>,
|
|
36
|
-
) => AppFormOptions<
|
|
37
|
-
FormValidatorData<TFormValidators>,
|
|
38
|
-
TFormValidators,
|
|
39
|
-
TSubmitReturn,
|
|
40
|
-
TComponents
|
|
41
|
-
>
|
|
42
|
-
|
|
43
|
-
looseSchema: <
|
|
44
|
-
const TFormValidators extends FormValidators<any>,
|
|
45
|
-
const TFormData extends NullableSchemaData<TFormValidators>,
|
|
46
|
-
TSubmitReturn,
|
|
47
|
-
>(
|
|
48
|
-
options: FormOptions<TFormData, TFormValidators, TSubmitReturn>,
|
|
49
|
-
) => AppFormOptions<
|
|
50
|
-
InferUnion<TFormData, FormValidatorData<TFormValidators>>,
|
|
51
|
-
TFormValidators,
|
|
52
|
-
TSubmitReturn,
|
|
53
|
-
TComponents
|
|
54
|
-
>
|
|
55
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { Component } from 'vue'
|
|
2
|
-
|
|
3
|
-
export interface VueFormComponentMap<
|
|
4
|
-
TFormComponents extends Record<string, Component>,
|
|
5
|
-
TFieldComponents extends Record<string, Component>,
|
|
6
|
-
> {
|
|
7
|
-
formComponents: TFormComponents
|
|
8
|
-
fieldComponents: TFieldComponents
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export type AnyVueFormComponentMap = VueFormComponentMap<
|
|
12
|
-
Record<string, Component>,
|
|
13
|
-
Record<string, Component>
|
|
14
|
-
>
|
|
15
|
-
|
|
16
|
-
export type DefaultVueFormComponentMap = VueFormComponentMap<
|
|
17
|
-
Record<never, never>,
|
|
18
|
-
Record<never, never>
|
|
19
|
-
>
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { inject } from 'vue'
|
|
2
|
-
import type { InjectionKey } from 'vue'
|
|
3
|
-
import type { AnyInternalFieldApi } from '@tanstack/form-core/internals'
|
|
4
|
-
import type { InternalVueFormApi } from '../VueForm/VueFormApi.lib'
|
|
5
|
-
|
|
6
|
-
export const FormContext = Symbol(
|
|
7
|
-
'TanStackForm.FormContext',
|
|
8
|
-
) as InjectionKey<InternalVueFormApi>
|
|
9
|
-
export const FieldContext = Symbol(
|
|
10
|
-
'TanStackForm.FieldContext',
|
|
11
|
-
) as InjectionKey<AnyInternalFieldApi>
|
|
12
|
-
|
|
13
|
-
export function useFieldContext(): AnyInternalFieldApi {
|
|
14
|
-
const field = inject(FieldContext)
|
|
15
|
-
if (field === undefined) {
|
|
16
|
-
throw new Error(
|
|
17
|
-
'TanStack Form: Field components must be used within a `form.Field` component.',
|
|
18
|
-
)
|
|
19
|
-
}
|
|
20
|
-
return field
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function useFormContext(): InternalVueFormApi {
|
|
24
|
-
const form = inject(FormContext)
|
|
25
|
-
if (form === undefined) {
|
|
26
|
-
throw new Error(
|
|
27
|
-
'TanStack Form: Form components must be used within a `form.AppForm` component.',
|
|
28
|
-
)
|
|
29
|
-
}
|
|
30
|
-
return form
|
|
31
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { useInternalForm } from '../VueForm/VueFormApi.lib'
|
|
2
|
-
import { defineFieldGroup } from '../FieldGroup/withFields.public'
|
|
3
|
-
import { createAppFormInitializer } from './initializeAppForm.lib'
|
|
4
|
-
import { useFormContext } from './contexts.lib'
|
|
5
|
-
import type { AppFormOptionsApi } from './appFormOptions.public'
|
|
6
|
-
import type { AnyVueFormComponentMap } from './componentMap.public'
|
|
7
|
-
import type {
|
|
8
|
-
AppFormHookResult,
|
|
9
|
-
UseAppFormHook,
|
|
10
|
-
} from './createFormHookTypes.public'
|
|
11
|
-
import type { FormOptions } from '@tanstack/form-core'
|
|
12
|
-
|
|
13
|
-
const appFormOptions = ((opts: unknown) => opts) as AppFormOptionsApi<any>
|
|
14
|
-
appFormOptions.strictSchema = (opts) => opts as never
|
|
15
|
-
appFormOptions.looseSchema = (opts) => opts as never
|
|
16
|
-
|
|
17
|
-
export function createFormHook<
|
|
18
|
-
const TComponents extends AnyVueFormComponentMap,
|
|
19
|
-
>(createOptions: TComponents): AppFormHookResult<TComponents> {
|
|
20
|
-
const initializeAppForm = createAppFormInitializer(createOptions)
|
|
21
|
-
|
|
22
|
-
function useExtendedForm(options: FormOptions<any, any, any>) {
|
|
23
|
-
return useInternalForm(options, initializeAppForm)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return {
|
|
27
|
-
useFormContext: useFormContext as never,
|
|
28
|
-
appFormOptions,
|
|
29
|
-
defineAppFieldGroup: defineFieldGroup,
|
|
30
|
-
useAppForm: useExtendedForm as never as UseAppFormHook<TComponents>,
|
|
31
|
-
}
|
|
32
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { AppFormOptionsApi } from './appFormOptions.public'
|
|
2
|
-
import type { AnyVueFormComponentMap } from './componentMap.public'
|
|
3
|
-
import type { VueAppFormApi } from './VueAppFormApi.public'
|
|
4
|
-
import type { DefineFieldGroupFn } from '../FieldGroup/withFields.public'
|
|
5
|
-
import type {
|
|
6
|
-
FormOptions,
|
|
7
|
-
FormValidators,
|
|
8
|
-
ToFormErrorTypes,
|
|
9
|
-
} from '@tanstack/form-core'
|
|
10
|
-
|
|
11
|
-
export type UseAppFormHook<TComponents extends AnyVueFormComponentMap> = <
|
|
12
|
-
TFormData,
|
|
13
|
-
const TFormValidators extends FormValidators<TFormData>,
|
|
14
|
-
TSubmitReturn,
|
|
15
|
-
>(
|
|
16
|
-
options: FormOptions<TFormData, TFormValidators, TSubmitReturn>,
|
|
17
|
-
) => VueAppFormApi<
|
|
18
|
-
TFormData,
|
|
19
|
-
ToFormErrorTypes<TFormValidators, TSubmitReturn>,
|
|
20
|
-
TComponents
|
|
21
|
-
>
|
|
22
|
-
|
|
23
|
-
export interface AppFormHookResult<TComponents extends AnyVueFormComponentMap> {
|
|
24
|
-
appFormOptions: AppFormOptionsApi<TComponents>
|
|
25
|
-
defineAppFieldGroup: DefineFieldGroupFn<TComponents['fieldComponents']>
|
|
26
|
-
useAppForm: UseAppFormHook<TComponents>
|
|
27
|
-
useFormContext: () => VueAppFormApi<any, any, TComponents>
|
|
28
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { defineComponent, h } from 'vue'
|
|
2
|
-
import { useFieldContext } from './contexts.lib'
|
|
3
|
-
import type { Component } from 'vue'
|
|
4
|
-
|
|
5
|
-
export function wrapField(
|
|
6
|
-
component: Component,
|
|
7
|
-
fieldPropKey: string,
|
|
8
|
-
): Component {
|
|
9
|
-
return defineComponent(
|
|
10
|
-
(_props, context) => {
|
|
11
|
-
const field = useFieldContext()
|
|
12
|
-
return () =>
|
|
13
|
-
h(component, { ...context.attrs, [fieldPropKey]: field }, context.slots)
|
|
14
|
-
},
|
|
15
|
-
{ name: 'TanStackForm.FieldComponent', inheritAttrs: false },
|
|
16
|
-
)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function brandComponentFactory(): (component: Component) => Component {
|
|
20
|
-
return (component) => component
|
|
21
|
-
}
|