@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.
- package/dist/AppForm/Components.lib.js +16 -0
- package/dist/AppForm/VueAppFormApi.public.d.ts +14 -0
- package/dist/AppForm/appFormOptions.public.d.ts +14 -0
- package/dist/AppForm/componentMap.public.d.ts +10 -0
- package/dist/AppForm/contexts.lib.js +18 -0
- package/dist/AppForm/createFormHook.public.d.ts +6 -0
- package/dist/AppForm/createFormHook.public.js +24 -0
- package/dist/AppForm/createFormHookTypes.public.d.ts +15 -0
- package/dist/AppForm/fieldComponentHelpers.lib.js +22 -0
- package/dist/AppForm/getFormHookHelpers.public.d.ts +37 -0
- package/dist/AppForm/getFormHookHelpers.public.js +18 -0
- package/dist/AppForm/initializeAppForm.lib.js +10 -0
- package/dist/FieldGroup/FieldGroupApi.public.d.ts +30 -0
- package/dist/FieldGroup/withFields.lib.js +62 -0
- package/dist/FieldGroup/withFields.public.d.ts +57 -0
- package/dist/FieldGroup/withFields.public.js +8 -0
- package/dist/Subscribe.public.d.ts +15 -0
- package/dist/Subscribe.public.js +22 -0
- package/dist/VueForm/Components.lib.js +94 -0
- package/dist/VueForm/Components.public.d.ts +71 -0
- package/dist/VueForm/VueFormApi.lib.js +26 -0
- package/dist/VueForm/fieldSubscriptions.lib.js +34 -0
- package/dist/VueForm/formApiTypes.public.d.ts +10 -0
- package/dist/VueForm/formType.public.d.ts +9 -0
- package/dist/VueForm/useField.lib.js +44 -0
- package/dist/VueForm/useForm.public.d.ts +8 -0
- package/dist/VueForm/useForm.public.js +10 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +11 -0
- package/dist/vueTypes.lib.d.ts +6 -0
- package/package.json +13 -29
- package/src/AppForm/Components.lib.ts +31 -0
- package/src/AppForm/VueAppFormApi.public.ts +17 -0
- package/src/AppForm/appFormOptions.public.ts +55 -0
- package/src/AppForm/componentMap.public.ts +19 -0
- package/src/AppForm/contexts.lib.ts +31 -0
- package/src/AppForm/createFormHook.public.ts +32 -0
- package/src/AppForm/createFormHookTypes.public.ts +28 -0
- package/src/AppForm/fieldComponentHelpers.lib.ts +21 -0
- package/src/AppForm/getFormHookHelpers.public.ts +109 -0
- package/src/AppForm/initializeAppForm.lib.ts +18 -0
- package/src/FieldGroup/FieldGroupApi.public.ts +148 -0
- package/src/FieldGroup/withFields.lib.ts +103 -0
- package/src/FieldGroup/withFields.public.ts +191 -0
- package/src/Subscribe.public.ts +46 -0
- package/src/VueForm/Components.lib.ts +182 -0
- package/src/VueForm/Components.public.ts +451 -0
- package/src/VueForm/VueFormApi.lib.ts +35 -0
- package/src/VueForm/fieldSubscriptions.lib.ts +47 -0
- package/src/VueForm/formApiTypes.public.ts +32 -0
- package/src/VueForm/formType.public.ts +46 -0
- package/src/VueForm/useField.lib.ts +64 -0
- package/src/VueForm/useForm.public.ts +30 -0
- package/src/index.ts +15 -4
- package/src/vueTypes.lib.ts +31 -0
- package/dist/cjs/index.cjs +0 -27
- package/dist/cjs/index.cjs.map +0 -1
- package/dist/cjs/index.d.cts +0 -5
- package/dist/cjs/types.d.cts +0 -9
- package/dist/cjs/useField.cjs +0 -106
- package/dist/cjs/useField.cjs.map +0 -1
- package/dist/cjs/useField.d.cts +0 -54
- package/dist/cjs/useForm.cjs +0 -62
- package/dist/cjs/useForm.cjs.map +0 -1
- package/dist/cjs/useForm.d.cts +0 -23
- package/dist/cjs/useFormGroup.cjs +0 -41
- package/dist/cjs/useFormGroup.cjs.map +0 -1
- package/dist/cjs/useFormGroup.d.cts +0 -37
- package/dist/cjs/useFormId.cjs +0 -31
- package/dist/cjs/useFormId.cjs.map +0 -1
- package/dist/cjs/useFormId.d.cts +0 -7
- package/dist/esm/index.d.ts +0 -5
- package/dist/esm/index.js +0 -15
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/types.d.ts +0 -9
- package/dist/esm/useField.d.ts +0 -54
- package/dist/esm/useField.js +0 -106
- package/dist/esm/useField.js.map +0 -1
- package/dist/esm/useForm.d.ts +0 -23
- package/dist/esm/useForm.js +0 -62
- package/dist/esm/useForm.js.map +0 -1
- package/dist/esm/useFormGroup.d.ts +0 -37
- package/dist/esm/useFormGroup.js +0 -41
- package/dist/esm/useFormGroup.js.map +0 -1
- package/dist/esm/useFormId.d.ts +0 -7
- package/dist/esm/useFormId.js +0 -14
- package/dist/esm/useFormId.js.map +0 -1
- package/src/types.ts +0 -114
- package/src/useField.tsx +0 -550
- package/src/useForm.tsx +0 -360
- package/src/useFormGroup.tsx +0 -532
- package/src/useFormId.ts +0 -24
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { shallow } from "@tanstack/vue-store";
|
|
2
|
+
import { shallowRef, toRaw, watch } from "vue";
|
|
3
|
+
|
|
4
|
+
//#region src/VueForm/fieldSubscriptions.lib.ts
|
|
5
|
+
function createFieldSelection(fieldApi, selector) {
|
|
6
|
+
const selected = shallowRef(selector(fieldApi.value));
|
|
7
|
+
watch(fieldApi, (field, _previous, onCleanup) => {
|
|
8
|
+
selected.value = selector(field);
|
|
9
|
+
const subscription = field.atom.subscribe(() => {
|
|
10
|
+
const next = selector(field);
|
|
11
|
+
if (!shallow(toRaw(selected.value), next)) selected.value = next;
|
|
12
|
+
});
|
|
13
|
+
onCleanup(() => subscription.unsubscribe());
|
|
14
|
+
}, {
|
|
15
|
+
immediate: true,
|
|
16
|
+
flush: "sync"
|
|
17
|
+
});
|
|
18
|
+
return selected;
|
|
19
|
+
}
|
|
20
|
+
function createValueFieldSubscription(fieldApi) {
|
|
21
|
+
return createFieldSelection(fieldApi, (field) => ({
|
|
22
|
+
value: field.value,
|
|
23
|
+
meta: field.meta
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
function createArrayFieldSubscription(fieldApi) {
|
|
27
|
+
return createFieldSelection(fieldApi, (field) => ({
|
|
28
|
+
length: field.value.length,
|
|
29
|
+
version: field.meta._arrayVersion
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
//#endregion
|
|
34
|
+
export { createArrayFieldSubscription, createValueFieldSubscription };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AnyVueFormComponentMap, DefaultVueFormComponentMap, VueFormComponentMap } from "../AppForm/componentMap.public.js";
|
|
2
|
+
import { VueTanStackFormComponents } from "./Components.public.js";
|
|
3
|
+
import { AnyFormApi, FormApi, FormErrorTypes } from "@tanstack/form-core";
|
|
4
|
+
import { Component } from "vue";
|
|
5
|
+
//#region src/VueForm/formApiTypes.public.d.ts
|
|
6
|
+
type ExtendedFormApi<TFormData, TFormErrorTypes extends FormErrorTypes, TFieldComponents extends Record<string, Component>> = FormApi<TFormData, TFormErrorTypes> & VueTanStackFormComponents<TFormData, TFormErrorTypes, TFieldComponents>;
|
|
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
|
+
type AnyVueFormApi = AnyFormApi & VueTanStackFormComponents<any, any, any>;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { AnyVueFormApi, VueFormApi, type VueFormComponentMap };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AnyVueFormComponentMap, DefaultVueFormComponentMap } from "../AppForm/componentMap.public.js";
|
|
2
|
+
import { VueFormApi } from "./formApiTypes.public.js";
|
|
3
|
+
import { AppFormOptions } from "../AppForm/appFormOptions.public.js";
|
|
4
|
+
import { AnyFormOptions, FormOptions, FormValidators, ToFormErrorTypes } from "@tanstack/form-core";
|
|
5
|
+
//#region src/VueForm/formType.public.d.ts
|
|
6
|
+
type VueFormTypeErrorTypes<TFormValidators extends FormValidators<any>, TSubmitReturn> = unknown extends TSubmitReturn ? any : ToFormErrorTypes<TFormValidators, TSubmitReturn>;
|
|
7
|
+
type VueFormType<TOptions extends AnyFormOptions | AppFormOptions<any, any, any, AnyVueFormComponentMap>> = TOptions extends AppFormOptions<infer TFormData, infer TFormValidators, infer TSubmitReturn, infer TComponents> ? VueFormApi<TFormData, VueFormTypeErrorTypes<TFormValidators, TSubmitReturn>, TComponents> : TOptions extends FormOptions<infer TFormData, infer TFormValidators, infer TSubmitReturn> ? VueFormApi<TFormData, VueFormTypeErrorTypes<TFormValidators, TSubmitReturn>, DefaultVueFormComponentMap> : never;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { VueFormType };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useSelector } from "@tanstack/vue-store";
|
|
2
|
+
import { onMounted, onUnmounted, shallowRef, watch, watchEffect } from "vue";
|
|
3
|
+
|
|
4
|
+
//#region src/VueForm/useField.lib.ts
|
|
5
|
+
function useField(options, fieldComponents) {
|
|
6
|
+
const initialOptions = options();
|
|
7
|
+
const resetVersion = useSelector(initialOptions.form._atoms.resetVersion);
|
|
8
|
+
const createField = () => {
|
|
9
|
+
const current = options();
|
|
10
|
+
const field = current.form._getOrCreateFieldApi({
|
|
11
|
+
...current,
|
|
12
|
+
name: current.name
|
|
13
|
+
});
|
|
14
|
+
if (fieldComponents !== null) Object.assign(field, fieldComponents);
|
|
15
|
+
return field;
|
|
16
|
+
};
|
|
17
|
+
const fieldApi = shallowRef(createField());
|
|
18
|
+
watch([
|
|
19
|
+
() => options().form,
|
|
20
|
+
() => options().name,
|
|
21
|
+
resetVersion
|
|
22
|
+
], () => {
|
|
23
|
+
fieldApi.value = createField();
|
|
24
|
+
}, { flush: "sync" });
|
|
25
|
+
watchEffect(() => {
|
|
26
|
+
fieldApi.value._update(options());
|
|
27
|
+
});
|
|
28
|
+
let mounted = false;
|
|
29
|
+
let unregister;
|
|
30
|
+
watch(fieldApi, (field) => {
|
|
31
|
+
if (!mounted) return;
|
|
32
|
+
unregister?.();
|
|
33
|
+
unregister = field._register();
|
|
34
|
+
}, { flush: "sync" });
|
|
35
|
+
onMounted(() => {
|
|
36
|
+
mounted = true;
|
|
37
|
+
unregister = fieldApi.value._register();
|
|
38
|
+
});
|
|
39
|
+
onUnmounted(() => unregister?.());
|
|
40
|
+
return fieldApi;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
44
|
+
export { useField };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AnyVueFormComponentMap, DefaultVueFormComponentMap } from "../AppForm/componentMap.public.js";
|
|
2
|
+
import { VueFormApi } from "./formApiTypes.public.js";
|
|
3
|
+
import { FormOptions, FormValidators, ToFormErrorTypes } from "@tanstack/form-core";
|
|
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>;
|
|
6
|
+
declare const useForm: UseFormHook<DefaultVueFormComponentMap>;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { UseFormHook, useForm };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { initializeForm, useInternalForm } from "./VueFormApi.lib.js";
|
|
2
|
+
|
|
3
|
+
//#region src/VueForm/useForm.public.ts
|
|
4
|
+
function useFormHook(options) {
|
|
5
|
+
return useInternalForm(options, initializeForm);
|
|
6
|
+
}
|
|
7
|
+
const useForm = useFormHook;
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
export { useForm };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { AnyVueFormComponentMap, DefaultVueFormComponentMap, VueFormComponentMap } from "./AppForm/componentMap.public.js";
|
|
2
|
+
import { VueFieldApi, VueFormArrayFieldComponent, VueFormFieldComponent, VueFormFieldProps, VueFormGroupApi, VueFormGroupArrayFieldComponent, VueFormGroupComponent, VueFormGroupFieldComponent, VueFormGroupProps, VueFormGroupSubscribeComponent, VueFormGroupSubscribeProps, VueFormSubscribeComponent, VueFormSubscribeProps, VueTanStackFormComponents } from "./VueForm/Components.public.js";
|
|
3
|
+
import { AnyVueFormApi, VueFormApi } from "./VueForm/formApiTypes.public.js";
|
|
4
|
+
import { UseFormHook, useForm } from "./VueForm/useForm.public.js";
|
|
5
|
+
import { AppFormOptions, AppFormOptionsApi } from "./AppForm/appFormOptions.public.js";
|
|
6
|
+
import { VueFormType } from "./VueForm/formType.public.js";
|
|
7
|
+
import { Subscribe, SubscribeComponent, SubscribeProps, SubscribeSource } from "./Subscribe.public.js";
|
|
8
|
+
import { AnyFieldGroupApi, FieldGroupApi, FieldGroupArrayFieldComponent, FieldGroupFieldComponent, FieldGroupFormState, FieldGroupSubscribeComponent, FieldGroupSubscribeProps } from "./FieldGroup/FieldGroupApi.public.js";
|
|
9
|
+
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
|
+
import { AppFormComponent, VueAppFormApi } from "./AppForm/VueAppFormApi.public.js";
|
|
11
|
+
import { AppFormHookResult, UseAppFormHook } from "./AppForm/createFormHookTypes.public.js";
|
|
12
|
+
import { createFormHook } from "./AppForm/createFormHook.public.js";
|
|
13
|
+
import { FormHookHelpers, getFormHookHelpers } from "./AppForm/getFormHookHelpers.public.js";
|
|
14
|
+
export * from "@tanstack/form-core";
|
|
15
|
+
export * from "@tanstack/vue-store";
|
|
16
|
+
export { AnyFieldGroupApi, AnyFieldGroupFieldSlot, AnyVueFormApi, AnyVueFormComponentMap, AppFormComponent, AppFormHookResult, AppFormOptions, AppFormOptionsApi, 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/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Subscribe } from "./Subscribe.public.js";
|
|
2
|
+
import { useForm } from "./VueForm/useForm.public.js";
|
|
3
|
+
import { defineFieldGroup } from "./FieldGroup/withFields.public.js";
|
|
4
|
+
import { createFormHook } from "./AppForm/createFormHook.public.js";
|
|
5
|
+
import { getFormHookHelpers } from "./AppForm/getFormHookHelpers.public.js";
|
|
6
|
+
|
|
7
|
+
export * from "@tanstack/form-core"
|
|
8
|
+
|
|
9
|
+
export * from "@tanstack/vue-store"
|
|
10
|
+
|
|
11
|
+
export { Subscribe, createFormHook, defineFieldGroup, getFormHookHelpers, useForm };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ComponentOptionsMixin, CreateComponentPublicInstanceWithMixins, EmitsOptions, PublicProps, SlotsType } from "vue";
|
|
2
|
+
//#region src/vueTypes.lib.d.ts
|
|
3
|
+
type VueComponentInstance<TProps extends Record<string, any>, TSlots extends Record<string, any>> = CreateComponentPublicInstanceWithMixins<TProps, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, PublicProps, {}, false, {}, SlotsType<TSlots>>;
|
|
4
|
+
type VueComponentWithSlots<TProps extends Record<string, any>, TSlots extends Record<string, any>> = new (props: TProps & PublicProps) => VueComponentInstance<TProps, TSlots>;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { VueComponentInstance, VueComponentWithSlots };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/vue-form",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-alpha.0",
|
|
4
4
|
"description": "Powerful, type-safe forms for Vue.",
|
|
5
5
|
"author": "tannerlinsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -15,20 +15,9 @@
|
|
|
15
15
|
"url": "https://github.com/sponsors/tannerlinsley"
|
|
16
16
|
},
|
|
17
17
|
"type": "module",
|
|
18
|
-
"types": "dist/
|
|
19
|
-
"main": "dist/cjs/index.cjs",
|
|
20
|
-
"module": "dist/esm/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
21
19
|
"exports": {
|
|
22
|
-
".":
|
|
23
|
-
"import": {
|
|
24
|
-
"types": "./dist/esm/index.d.ts",
|
|
25
|
-
"default": "./dist/esm/index.js"
|
|
26
|
-
},
|
|
27
|
-
"require": {
|
|
28
|
-
"types": "./dist/cjs/index.d.cts",
|
|
29
|
-
"default": "./dist/cjs/index.cjs"
|
|
30
|
-
}
|
|
31
|
-
},
|
|
20
|
+
".": "./dist/index.js",
|
|
32
21
|
"./package.json": "./package.json"
|
|
33
22
|
},
|
|
34
23
|
"sideEffects": false,
|
|
@@ -37,31 +26,26 @@
|
|
|
37
26
|
"src"
|
|
38
27
|
],
|
|
39
28
|
"dependencies": {
|
|
40
|
-
"@tanstack/vue-store": "^0.11.
|
|
41
|
-
"@tanstack/form-core": "
|
|
29
|
+
"@tanstack/vue-store": "^0.11.1",
|
|
30
|
+
"@tanstack/form-core": "2.0.0-alpha.0"
|
|
42
31
|
},
|
|
43
32
|
"devDependencies": {
|
|
44
|
-
"@
|
|
45
|
-
"
|
|
46
|
-
"vue": "^
|
|
33
|
+
"@testing-library/vue": "^8.1.0",
|
|
34
|
+
"@vitejs/plugin-vue": "^6.0.8",
|
|
35
|
+
"unplugin-vue": "^7.2.0",
|
|
36
|
+
"vue": "^3.6.0-rc.2",
|
|
37
|
+
"vue-tsc": "^3.3.9"
|
|
47
38
|
},
|
|
48
39
|
"peerDependencies": {
|
|
49
|
-
"vue": "^3.
|
|
40
|
+
"vue": "^3.6.0-rc.2"
|
|
50
41
|
},
|
|
51
42
|
"scripts": {
|
|
52
43
|
"clean": "premove ./dist ./coverage",
|
|
53
44
|
"test:eslint": "eslint ./src ./tests",
|
|
54
|
-
"test:types": "
|
|
55
|
-
"test:types:ts54": "node ../../node_modules/typescript54/lib/tsc.js",
|
|
56
|
-
"test:types:ts55": "node ../../node_modules/typescript55/lib/tsc.js",
|
|
57
|
-
"test:types:ts56": "node ../../node_modules/typescript56/lib/tsc.js",
|
|
58
|
-
"test:types:ts57": "node ../../node_modules/typescript57/lib/tsc.js",
|
|
59
|
-
"test:types:ts58": "node ../../node_modules/typescript58/lib/tsc.js",
|
|
60
|
-
"test:types:ts59": "tsc",
|
|
61
|
-
"fixme:test:lib": "pnpm run test:2 && pnpm run test:2.7 && pnpm run test:3",
|
|
45
|
+
"test:types": "vue-tsc --noEmit",
|
|
62
46
|
"test:lib": "vitest",
|
|
63
47
|
"test:lib:dev": "pnpm run test:lib --watch",
|
|
64
48
|
"test:build": "publint --strict",
|
|
65
|
-
"build": "
|
|
49
|
+
"build": "tsdown"
|
|
66
50
|
}
|
|
67
51
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
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
|
+
>
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { brandComponentFactory, wrapField } from './fieldComponentHelpers.lib'
|
|
2
|
+
import type { FieldWithValue } from '@tanstack/form-core'
|
|
3
|
+
import type { Component, PublicProps } from 'vue'
|
|
4
|
+
import type { VueComponentInstance } from '../vueTypes.lib'
|
|
5
|
+
|
|
6
|
+
type ExactFieldBrand<out TValue> = {
|
|
7
|
+
readonly __tanstackFieldExactType: TValue
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
type AcceptsFieldBrand<out TAcceptedValue> = {
|
|
11
|
+
readonly __tanstackFieldAcceptsType: TAcceptedValue
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type AnyFieldComponent = Component
|
|
15
|
+
type PropsOf<TComponent> = TComponent extends new (...args: any[]) => {
|
|
16
|
+
$props: infer TProps
|
|
17
|
+
}
|
|
18
|
+
? Omit<TProps, keyof PublicProps>
|
|
19
|
+
: never
|
|
20
|
+
type FieldValuePropKeys<TProps> = {
|
|
21
|
+
[K in keyof TProps]-?: TProps[K] extends FieldWithValue<any> ? K : never
|
|
22
|
+
}[keyof TProps]
|
|
23
|
+
type FieldValueFromProp<TProp> =
|
|
24
|
+
TProp extends FieldWithValue<infer TValue> ? TValue : never
|
|
25
|
+
type FieldValueFromComponentProp<
|
|
26
|
+
TProps,
|
|
27
|
+
TFieldPropKey extends keyof TProps,
|
|
28
|
+
> = FieldValueFromProp<TProps[TFieldPropKey]>
|
|
29
|
+
type PublicPropsReplacingField<
|
|
30
|
+
TProps,
|
|
31
|
+
TFieldPropKey extends keyof TProps,
|
|
32
|
+
> = Omit<TProps, TFieldPropKey>
|
|
33
|
+
|
|
34
|
+
type StrictInjectedFieldComponent<
|
|
35
|
+
TComponent extends AnyFieldComponent,
|
|
36
|
+
TProps = PropsOf<TComponent>,
|
|
37
|
+
TFieldPropKey extends FieldValuePropKeys<TProps> = FieldValuePropKeys<TProps>,
|
|
38
|
+
> = (new (
|
|
39
|
+
props: PublicPropsReplacingField<TProps, TFieldPropKey> & PublicProps,
|
|
40
|
+
) => VueComponentInstance<
|
|
41
|
+
PublicPropsReplacingField<TProps, TFieldPropKey> & Record<string, any>,
|
|
42
|
+
{}
|
|
43
|
+
>) &
|
|
44
|
+
ExactFieldBrand<FieldValueFromComponentProp<TProps, TFieldPropKey>>
|
|
45
|
+
|
|
46
|
+
type LooseInjectedFieldComponent<
|
|
47
|
+
TComponent extends AnyFieldComponent,
|
|
48
|
+
TProps = PropsOf<TComponent>,
|
|
49
|
+
TFieldPropKey extends FieldValuePropKeys<TProps> = FieldValuePropKeys<TProps>,
|
|
50
|
+
> = (new (
|
|
51
|
+
props: PublicPropsReplacingField<TProps, TFieldPropKey> & PublicProps,
|
|
52
|
+
) => VueComponentInstance<
|
|
53
|
+
PublicPropsReplacingField<TProps, TFieldPropKey> & Record<string, any>,
|
|
54
|
+
{}
|
|
55
|
+
>) &
|
|
56
|
+
AcceptsFieldBrand<FieldValueFromComponentProp<TProps, TFieldPropKey>>
|
|
57
|
+
|
|
58
|
+
type StrictBrandedFieldComponent<TComponent, TValue> = TComponent &
|
|
59
|
+
ExactFieldBrand<TValue>
|
|
60
|
+
type LooseBrandedFieldComponent<TComponent, TValue> = TComponent &
|
|
61
|
+
AcceptsFieldBrand<TValue>
|
|
62
|
+
|
|
63
|
+
interface FieldComponentHelper {
|
|
64
|
+
strict: <
|
|
65
|
+
TComponent extends AnyFieldComponent,
|
|
66
|
+
TProps = PropsOf<TComponent>,
|
|
67
|
+
TFieldPropKey extends FieldValuePropKeys<TProps> =
|
|
68
|
+
FieldValuePropKeys<TProps>,
|
|
69
|
+
>(
|
|
70
|
+
component: TComponent,
|
|
71
|
+
fieldPropKey: TFieldPropKey,
|
|
72
|
+
) => StrictInjectedFieldComponent<TComponent, TProps, TFieldPropKey>
|
|
73
|
+
loose: <
|
|
74
|
+
TComponent extends AnyFieldComponent,
|
|
75
|
+
TProps = PropsOf<TComponent>,
|
|
76
|
+
TFieldPropKey extends FieldValuePropKeys<TProps> =
|
|
77
|
+
FieldValuePropKeys<TProps>,
|
|
78
|
+
>(
|
|
79
|
+
component: TComponent,
|
|
80
|
+
fieldPropKey: TFieldPropKey,
|
|
81
|
+
) => LooseInjectedFieldComponent<TComponent, TProps, TFieldPropKey>
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
interface FieldBrandHelper {
|
|
85
|
+
strict: <TValue>() => <TComponent extends AnyFieldComponent>(
|
|
86
|
+
component: TComponent,
|
|
87
|
+
) => StrictBrandedFieldComponent<TComponent, TValue>
|
|
88
|
+
loose: <TValue>() => <TComponent extends AnyFieldComponent>(
|
|
89
|
+
component: TComponent,
|
|
90
|
+
) => LooseBrandedFieldComponent<TComponent, TValue>
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface FormHookHelpers {
|
|
94
|
+
fieldBrand: FieldBrandHelper
|
|
95
|
+
fieldComponent: FieldComponentHelper
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function getFormHookHelpers(): FormHookHelpers {
|
|
99
|
+
return {
|
|
100
|
+
fieldComponent: {
|
|
101
|
+
loose: wrapField as FieldComponentHelper['loose'],
|
|
102
|
+
strict: wrapField as FieldComponentHelper['strict'],
|
|
103
|
+
},
|
|
104
|
+
fieldBrand: {
|
|
105
|
+
loose: brandComponentFactory as FieldBrandHelper['loose'],
|
|
106
|
+
strict: brandComponentFactory as FieldBrandHelper['strict'],
|
|
107
|
+
},
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { InternalFormApi } from '@tanstack/form-core/internals'
|
|
2
|
+
import { attachVueAppFormComponents } from './Components.lib'
|
|
3
|
+
import type { FormOptions } from '@tanstack/form-core'
|
|
4
|
+
import type { InternalVueFormApi } from '../VueForm/VueFormApi.lib'
|
|
5
|
+
import type { AnyVueFormComponentMap } from './componentMap.public'
|
|
6
|
+
|
|
7
|
+
export function createAppFormInitializer<
|
|
8
|
+
TComponents extends AnyVueFormComponentMap,
|
|
9
|
+
>(
|
|
10
|
+
createOptions: TComponents,
|
|
11
|
+
): (options: FormOptions<any, any, any>) => InternalVueFormApi {
|
|
12
|
+
return (options) =>
|
|
13
|
+
attachVueAppFormComponents(
|
|
14
|
+
new InternalFormApi(options),
|
|
15
|
+
createOptions.formComponents,
|
|
16
|
+
createOptions.fieldComponents,
|
|
17
|
+
) as never
|
|
18
|
+
}
|