@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,16 @@
|
|
|
1
|
+
import { attachVueFormComponents } from "../VueForm/Components.lib.js";
|
|
2
|
+
import { FieldContext, FormContext } from "./contexts.lib.js";
|
|
3
|
+
import { defineComponent, provide } from "vue";
|
|
4
|
+
|
|
5
|
+
//#region src/AppForm/Components.lib.ts
|
|
6
|
+
function attachVueAppFormComponents(form, formComponents, fieldComponents) {
|
|
7
|
+
const resultForm = attachVueFormComponents(form, fieldComponents, FieldContext);
|
|
8
|
+
resultForm.AppForm = defineComponent((_props, { slots }) => {
|
|
9
|
+
provide(FormContext, resultForm);
|
|
10
|
+
return () => slots.default?.();
|
|
11
|
+
}, { name: "TanStackForm.AppForm" });
|
|
12
|
+
return Object.assign(resultForm, formComponents);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
export { attachVueAppFormComponents };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AnyVueFormComponentMap } from "./componentMap.public.js";
|
|
2
|
+
import { VueComponentInstance } from "../vueTypes.lib.js";
|
|
3
|
+
import { VueFormApi } from "../VueForm/formApiTypes.public.js";
|
|
4
|
+
import { FormErrorTypes } from "@tanstack/form-core";
|
|
5
|
+
import { PublicProps } from "vue";
|
|
6
|
+
//#region src/AppForm/VueAppFormApi.public.d.ts
|
|
7
|
+
type AppFormComponent = new (props: PublicProps) => VueComponentInstance<{}, {
|
|
8
|
+
default: {};
|
|
9
|
+
}>;
|
|
10
|
+
type VueAppFormApi<TFormData, TFormErrorTypes extends FormErrorTypes, TComponents extends AnyVueFormComponentMap> = VueFormApi<TFormData, TFormErrorTypes, TComponents> & {
|
|
11
|
+
AppForm: AppFormComponent;
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { AppFormComponent, VueAppFormApi };
|
|
@@ -0,0 +1,14 @@
|
|
|
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 };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Component } from "vue";
|
|
2
|
+
//#region src/AppForm/componentMap.public.d.ts
|
|
3
|
+
interface VueFormComponentMap<TFormComponents extends Record<string, Component>, TFieldComponents extends Record<string, Component>> {
|
|
4
|
+
formComponents: TFormComponents;
|
|
5
|
+
fieldComponents: TFieldComponents;
|
|
6
|
+
}
|
|
7
|
+
type AnyVueFormComponentMap = VueFormComponentMap<Record<string, Component>, Record<string, Component>>;
|
|
8
|
+
type DefaultVueFormComponentMap = VueFormComponentMap<Record<never, never>, Record<never, never>>;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { AnyVueFormComponentMap, DefaultVueFormComponentMap, VueFormComponentMap };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { inject } from "vue";
|
|
2
|
+
|
|
3
|
+
//#region src/AppForm/contexts.lib.ts
|
|
4
|
+
const FormContext = Symbol("TanStackForm.FormContext");
|
|
5
|
+
const FieldContext = Symbol("TanStackForm.FieldContext");
|
|
6
|
+
function useFieldContext() {
|
|
7
|
+
const field = inject(FieldContext);
|
|
8
|
+
if (field === void 0) throw new Error("TanStack Form: Field components must be used within a `form.Field` component.");
|
|
9
|
+
return field;
|
|
10
|
+
}
|
|
11
|
+
function useFormContext() {
|
|
12
|
+
const form = inject(FormContext);
|
|
13
|
+
if (form === void 0) throw new Error("TanStack Form: Form components must be used within a `form.AppForm` component.");
|
|
14
|
+
return form;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { FieldContext, FormContext, useFieldContext, useFormContext };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { AnyVueFormComponentMap } from "./componentMap.public.js";
|
|
2
|
+
import { AppFormHookResult } from "./createFormHookTypes.public.js";
|
|
3
|
+
//#region src/AppForm/createFormHook.public.d.ts
|
|
4
|
+
declare function createFormHook<const TComponents extends AnyVueFormComponentMap>(createOptions: TComponents): AppFormHookResult<TComponents>;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { createFormHook };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useInternalForm } from "../VueForm/VueFormApi.lib.js";
|
|
2
|
+
import { defineFieldGroup } from "../FieldGroup/withFields.public.js";
|
|
3
|
+
import { useFormContext } from "./contexts.lib.js";
|
|
4
|
+
import { createAppFormInitializer } from "./initializeAppForm.lib.js";
|
|
5
|
+
|
|
6
|
+
//#region src/AppForm/createFormHook.public.ts
|
|
7
|
+
const appFormOptions = ((opts) => opts);
|
|
8
|
+
appFormOptions.strictSchema = (opts) => opts;
|
|
9
|
+
appFormOptions.looseSchema = (opts) => opts;
|
|
10
|
+
function createFormHook(createOptions) {
|
|
11
|
+
const initializeAppForm = createAppFormInitializer(createOptions);
|
|
12
|
+
function useExtendedForm(options) {
|
|
13
|
+
return useInternalForm(options, initializeAppForm);
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
useFormContext,
|
|
17
|
+
appFormOptions,
|
|
18
|
+
defineAppFieldGroup: defineFieldGroup,
|
|
19
|
+
useAppForm: useExtendedForm
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
export { createFormHook };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { AnyVueFormComponentMap } from "./componentMap.public.js";
|
|
2
|
+
import { AppFormOptionsApi } from "./appFormOptions.public.js";
|
|
3
|
+
import { DefineFieldGroupFn } from "../FieldGroup/withFields.public.js";
|
|
4
|
+
import { VueAppFormApi } from "./VueAppFormApi.public.js";
|
|
5
|
+
import { FormOptions, FormValidators, ToFormErrorTypes } from "@tanstack/form-core";
|
|
6
|
+
//#region src/AppForm/createFormHookTypes.public.d.ts
|
|
7
|
+
type UseAppFormHook<TComponents extends AnyVueFormComponentMap> = <TFormData, const TFormValidators extends FormValidators<TFormData>, TSubmitReturn>(options: FormOptions<TFormData, TFormValidators, TSubmitReturn>) => VueAppFormApi<TFormData, ToFormErrorTypes<TFormValidators, TSubmitReturn>, TComponents>;
|
|
8
|
+
interface AppFormHookResult<TComponents extends AnyVueFormComponentMap> {
|
|
9
|
+
appFormOptions: AppFormOptionsApi<TComponents>;
|
|
10
|
+
defineAppFieldGroup: DefineFieldGroupFn<TComponents['fieldComponents']>;
|
|
11
|
+
useAppForm: UseAppFormHook<TComponents>;
|
|
12
|
+
useFormContext: () => VueAppFormApi<any, any, TComponents>;
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { AppFormHookResult, UseAppFormHook };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useFieldContext } from "./contexts.lib.js";
|
|
2
|
+
import { defineComponent, h } from "vue";
|
|
3
|
+
|
|
4
|
+
//#region src/AppForm/fieldComponentHelpers.lib.ts
|
|
5
|
+
function wrapField(component, fieldPropKey) {
|
|
6
|
+
return defineComponent((_props, context) => {
|
|
7
|
+
const field = useFieldContext();
|
|
8
|
+
return () => h(component, {
|
|
9
|
+
...context.attrs,
|
|
10
|
+
[fieldPropKey]: field
|
|
11
|
+
}, context.slots);
|
|
12
|
+
}, {
|
|
13
|
+
name: "TanStackForm.FieldComponent",
|
|
14
|
+
inheritAttrs: false
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function brandComponentFactory() {
|
|
18
|
+
return (component) => component;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
export { brandComponentFactory, wrapField };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { VueComponentInstance } from "../vueTypes.lib.js";
|
|
2
|
+
import { FieldWithValue } from "@tanstack/form-core";
|
|
3
|
+
import { Component, PublicProps } from "vue";
|
|
4
|
+
//#region src/AppForm/getFormHookHelpers.public.d.ts
|
|
5
|
+
type ExactFieldBrand<out TValue> = {
|
|
6
|
+
readonly __tanstackFieldExactType: TValue;
|
|
7
|
+
};
|
|
8
|
+
type AcceptsFieldBrand<out TAcceptedValue> = {
|
|
9
|
+
readonly __tanstackFieldAcceptsType: TAcceptedValue;
|
|
10
|
+
};
|
|
11
|
+
type AnyFieldComponent = Component;
|
|
12
|
+
type PropsOf<TComponent> = TComponent extends (new (...args: any[]) => {
|
|
13
|
+
$props: infer TProps;
|
|
14
|
+
}) ? Omit<TProps, keyof PublicProps> : never;
|
|
15
|
+
type FieldValuePropKeys<TProps> = { [K in keyof TProps]-?: TProps[K] extends FieldWithValue<any> ? K : never; }[keyof TProps];
|
|
16
|
+
type FieldValueFromProp<TProp> = TProp extends FieldWithValue<infer TValue> ? TValue : never;
|
|
17
|
+
type FieldValueFromComponentProp<TProps, TFieldPropKey extends keyof TProps> = FieldValueFromProp<TProps[TFieldPropKey]>;
|
|
18
|
+
type PublicPropsReplacingField<TProps, TFieldPropKey extends keyof TProps> = Omit<TProps, TFieldPropKey>;
|
|
19
|
+
type StrictInjectedFieldComponent<TComponent extends AnyFieldComponent, TProps = PropsOf<TComponent>, TFieldPropKey extends FieldValuePropKeys<TProps> = FieldValuePropKeys<TProps>> = (new (props: PublicPropsReplacingField<TProps, TFieldPropKey> & PublicProps) => VueComponentInstance<PublicPropsReplacingField<TProps, TFieldPropKey> & Record<string, any>, {}>) & ExactFieldBrand<FieldValueFromComponentProp<TProps, TFieldPropKey>>;
|
|
20
|
+
type LooseInjectedFieldComponent<TComponent extends AnyFieldComponent, TProps = PropsOf<TComponent>, TFieldPropKey extends FieldValuePropKeys<TProps> = FieldValuePropKeys<TProps>> = (new (props: PublicPropsReplacingField<TProps, TFieldPropKey> & PublicProps) => VueComponentInstance<PublicPropsReplacingField<TProps, TFieldPropKey> & Record<string, any>, {}>) & AcceptsFieldBrand<FieldValueFromComponentProp<TProps, TFieldPropKey>>;
|
|
21
|
+
type StrictBrandedFieldComponent<TComponent, TValue> = TComponent & ExactFieldBrand<TValue>;
|
|
22
|
+
type LooseBrandedFieldComponent<TComponent, TValue> = TComponent & AcceptsFieldBrand<TValue>;
|
|
23
|
+
interface FieldComponentHelper {
|
|
24
|
+
strict: <TComponent extends AnyFieldComponent, TProps = PropsOf<TComponent>, TFieldPropKey extends FieldValuePropKeys<TProps> = FieldValuePropKeys<TProps>>(component: TComponent, fieldPropKey: TFieldPropKey) => StrictInjectedFieldComponent<TComponent, TProps, TFieldPropKey>;
|
|
25
|
+
loose: <TComponent extends AnyFieldComponent, TProps = PropsOf<TComponent>, TFieldPropKey extends FieldValuePropKeys<TProps> = FieldValuePropKeys<TProps>>(component: TComponent, fieldPropKey: TFieldPropKey) => LooseInjectedFieldComponent<TComponent, TProps, TFieldPropKey>;
|
|
26
|
+
}
|
|
27
|
+
interface FieldBrandHelper {
|
|
28
|
+
strict: <TValue>() => <TComponent extends AnyFieldComponent>(component: TComponent) => StrictBrandedFieldComponent<TComponent, TValue>;
|
|
29
|
+
loose: <TValue>() => <TComponent extends AnyFieldComponent>(component: TComponent) => LooseBrandedFieldComponent<TComponent, TValue>;
|
|
30
|
+
}
|
|
31
|
+
interface FormHookHelpers {
|
|
32
|
+
fieldBrand: FieldBrandHelper;
|
|
33
|
+
fieldComponent: FieldComponentHelper;
|
|
34
|
+
}
|
|
35
|
+
declare function getFormHookHelpers(): FormHookHelpers;
|
|
36
|
+
//#endregion
|
|
37
|
+
export { FormHookHelpers, getFormHookHelpers };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { brandComponentFactory, wrapField } from "./fieldComponentHelpers.lib.js";
|
|
2
|
+
|
|
3
|
+
//#region src/AppForm/getFormHookHelpers.public.ts
|
|
4
|
+
function getFormHookHelpers() {
|
|
5
|
+
return {
|
|
6
|
+
fieldComponent: {
|
|
7
|
+
loose: wrapField,
|
|
8
|
+
strict: wrapField
|
|
9
|
+
},
|
|
10
|
+
fieldBrand: {
|
|
11
|
+
loose: brandComponentFactory,
|
|
12
|
+
strict: brandComponentFactory
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { getFormHookHelpers };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { attachVueAppFormComponents } from "./Components.lib.js";
|
|
2
|
+
import { InternalFormApi } from "@tanstack/form-core/internals";
|
|
3
|
+
|
|
4
|
+
//#region src/AppForm/initializeAppForm.lib.ts
|
|
5
|
+
function createAppFormInitializer(createOptions) {
|
|
6
|
+
return (options) => attachVueAppFormComponents(new InternalFormApi(options), createOptions.formComponents, createOptions.fieldComponents);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
export { createAppFormInitializer };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { VueComponentInstance } from "../vueTypes.lib.js";
|
|
2
|
+
import { VueFieldApi, VueFormFieldProps, VueFormSubscribeProps } from "../VueForm/Components.public.js";
|
|
3
|
+
import { DeepKeys, DeepKeysWhereValueIncludes, DeepValue, FieldValidators, FormApiArrayMethods, FormApiFieldMethods, FormErrorTypes, FormState, ToFieldError, ValidationIssue } from "@tanstack/form-core";
|
|
4
|
+
import { ReadonlyAtom } from "@tanstack/vue-store";
|
|
5
|
+
import { Component, PublicProps } from "vue";
|
|
6
|
+
//#region src/FieldGroup/FieldGroupApi.public.d.ts
|
|
7
|
+
type FieldGroupFieldComponent<in out TFieldData, in out TFieldComponents extends Record<string, Component>> = new <const TFieldName extends DeepKeys<TFieldData>>(props: VueFormFieldProps<TFieldData, TFieldName, DeepValue<TFieldData, TFieldName>, FieldValidators<TFieldData, TFieldName, DeepValue<TFieldData, TFieldName>>, ValidationIssue, unknown, FormErrorTypes, TFieldComponents> & PublicProps) => VueComponentInstance<VueFormFieldProps<TFieldData, TFieldName, DeepValue<TFieldData, TFieldName>, FieldValidators<TFieldData, TFieldName, DeepValue<TFieldData, TFieldName>>, ValidationIssue, unknown, FormErrorTypes, TFieldComponents>, {
|
|
8
|
+
default: {
|
|
9
|
+
field: VueFieldApi<TFieldName, DeepValue<TFieldData, TFieldName>, ToFieldError<FieldValidators<TFieldData, TFieldName, DeepValue<TFieldData, TFieldName>>, ValidationIssue, FormErrorTypes>, unknown, FormErrorTypes, TFieldComponents>;
|
|
10
|
+
};
|
|
11
|
+
}>;
|
|
12
|
+
type FieldGroupArrayFieldComponent<in out TFieldData, in out TFieldComponents extends Record<string, Component>> = new <const TFieldName extends DeepKeysWhereValueIncludes<TFieldData, Array<any>>>(props: VueFormFieldProps<TFieldData, TFieldName, DeepValue<TFieldData, TFieldName>, FieldValidators<TFieldData, TFieldName, DeepValue<TFieldData, TFieldName>>, ValidationIssue, unknown, FormErrorTypes, TFieldComponents> & PublicProps) => VueComponentInstance<VueFormFieldProps<TFieldData, TFieldName, DeepValue<TFieldData, TFieldName>, FieldValidators<TFieldData, TFieldName, DeepValue<TFieldData, TFieldName>>, ValidationIssue, unknown, FormErrorTypes, TFieldComponents>, {
|
|
13
|
+
default: {
|
|
14
|
+
field: VueFieldApi<TFieldName, DeepValue<TFieldData, TFieldName>, ToFieldError<FieldValidators<TFieldData, TFieldName, DeepValue<TFieldData, TFieldName>>, ValidationIssue, FormErrorTypes>, unknown, FormErrorTypes, TFieldComponents>;
|
|
15
|
+
};
|
|
16
|
+
}>;
|
|
17
|
+
type FieldGroupSubscribeProps<TSelected> = VueFormSubscribeProps<unknown, FormErrorTypes, TSelected>;
|
|
18
|
+
type FieldGroupSubscribeComponent = new <TSelected>(props: FieldGroupSubscribeProps<TSelected> & PublicProps) => VueComponentInstance<FieldGroupSubscribeProps<TSelected>, {
|
|
19
|
+
default: NoInfer<TSelected>;
|
|
20
|
+
}>;
|
|
21
|
+
interface FieldGroupApi<in out TFieldData, in out TFieldComponents extends Record<string, Component> = Record<never, never>> extends FormApiFieldMethods<TFieldData>, FormApiArrayMethods<TFieldData> {
|
|
22
|
+
atom: ReadonlyAtom<TFieldData>;
|
|
23
|
+
Field: FieldGroupFieldComponent<TFieldData, TFieldComponents>;
|
|
24
|
+
ArrayField: FieldGroupArrayFieldComponent<TFieldData, TFieldComponents>;
|
|
25
|
+
Subscribe: FieldGroupSubscribeComponent;
|
|
26
|
+
}
|
|
27
|
+
type AnyFieldGroupApi = FieldGroupApi<any, Record<string, Component>>;
|
|
28
|
+
type FieldGroupFormState = FormState<unknown, FormErrorTypes>;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { AnyFieldGroupApi, FieldGroupApi, FieldGroupArrayFieldComponent, FieldGroupFieldComponent, FieldGroupFormState, FieldGroupSubscribeComponent, FieldGroupSubscribeProps };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { InternalFieldGroupApi, defineFieldGroupFieldsRuntime, fieldGroupHelperRuntime } from "@tanstack/form-core/internals";
|
|
2
|
+
import { computed, defineComponent, h } from "vue";
|
|
3
|
+
|
|
4
|
+
//#region src/FieldGroup/withFields.lib.ts
|
|
5
|
+
function attachVueFieldGroupComponents(group, form) {
|
|
6
|
+
const forwardField = (component, name) => defineComponent((_props, context) => {
|
|
7
|
+
const resolved = computed(() => {
|
|
8
|
+
const options = { ...context.attrs };
|
|
9
|
+
return group._getFormFieldOptions(options, (base, overrides) => ({
|
|
10
|
+
...base,
|
|
11
|
+
...overrides
|
|
12
|
+
}));
|
|
13
|
+
});
|
|
14
|
+
return () => h(component, resolved.value, context.slots);
|
|
15
|
+
}, {
|
|
16
|
+
name,
|
|
17
|
+
inheritAttrs: false
|
|
18
|
+
});
|
|
19
|
+
const Field = forwardField(form.Field, "TanStackForm.FieldGroup.Field");
|
|
20
|
+
const ArrayField = forwardField(form.ArrayField, "TanStackForm.FieldGroup.ArrayField");
|
|
21
|
+
const Subscribe = defineComponent((_props, context) => () => h(form.Subscribe, { ...context.attrs }, context.slots), {
|
|
22
|
+
name: "TanStackForm.FieldGroup.Subscribe",
|
|
23
|
+
inheritAttrs: false
|
|
24
|
+
});
|
|
25
|
+
return Object.assign(group, {
|
|
26
|
+
Field,
|
|
27
|
+
ArrayField,
|
|
28
|
+
Subscribe
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function defineFieldGroupRuntime(defineFieldGroupFn) {
|
|
32
|
+
const fields = defineFieldGroupFieldsRuntime(defineFieldGroupFn(fieldGroupHelperRuntime));
|
|
33
|
+
return {
|
|
34
|
+
fields,
|
|
35
|
+
bindComponent: (component, fieldsPropName) => withFieldsRuntime(fields, component, fieldsPropName)
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function withFieldsRuntime(fields, component, fieldsPropName) {
|
|
39
|
+
const fieldNames = Object.keys(fields);
|
|
40
|
+
return defineComponent((_props, context) => {
|
|
41
|
+
const form = context.attrs.form;
|
|
42
|
+
if (!form) throw new Error("TanStack Form: Field groups must receive a `form` prop.");
|
|
43
|
+
const fieldGroupApi = attachVueFieldGroupComponents(new InternalFieldGroupApi({
|
|
44
|
+
form,
|
|
45
|
+
fieldNames,
|
|
46
|
+
getBindings: () => context.attrs[fieldsPropName]
|
|
47
|
+
}), form);
|
|
48
|
+
return () => {
|
|
49
|
+
const componentProps = { ...context.attrs };
|
|
50
|
+
delete componentProps.form;
|
|
51
|
+
delete componentProps[fieldsPropName];
|
|
52
|
+
componentProps[fieldsPropName] = fieldGroupApi;
|
|
53
|
+
return h(component, componentProps, context.slots);
|
|
54
|
+
};
|
|
55
|
+
}, {
|
|
56
|
+
name: "TanStackForm.FieldGroup",
|
|
57
|
+
inheritAttrs: false
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
//#endregion
|
|
62
|
+
export { defineFieldGroupRuntime };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { VueComponentInstance } from "../vueTypes.lib.js";
|
|
2
|
+
import { VueTanStackFormComponents } from "../VueForm/Components.public.js";
|
|
3
|
+
import { FieldGroupApi } from "./FieldGroupApi.public.js";
|
|
4
|
+
import { DeepKeys, DeepKeysWhereValueIncludes, DeepValue, FormApi } from "@tanstack/form-core";
|
|
5
|
+
import { Component, PublicProps } from "vue";
|
|
6
|
+
//#region src/FieldGroup/withFields.public.d.ts
|
|
7
|
+
declare const fieldGroupFieldSlotValueSymbol: unique symbol;
|
|
8
|
+
declare const fieldGroupFieldsSymbol: unique symbol;
|
|
9
|
+
type FieldGroupFieldSlotMode = 'strict' | 'loose';
|
|
10
|
+
interface FieldGroupFieldSlot<out TValue, out TMode extends FieldGroupFieldSlotMode = FieldGroupFieldSlotMode> {
|
|
11
|
+
readonly mode: TMode;
|
|
12
|
+
readonly [fieldGroupFieldSlotValueSymbol]: TValue;
|
|
13
|
+
}
|
|
14
|
+
type AnyFieldGroupFieldSlot = FieldGroupFieldSlot<any>;
|
|
15
|
+
type StrictFieldGroupFieldSlot<TValue> = FieldGroupFieldSlot<TValue, 'strict'>;
|
|
16
|
+
type LooseFieldGroupFieldSlot<TValue> = FieldGroupFieldSlot<TValue, 'loose'>;
|
|
17
|
+
type FieldGroupFieldSlotValue<TSlot> = TSlot extends FieldGroupFieldSlot<infer TValue> ? TValue : never;
|
|
18
|
+
type FieldGroupFieldSlotModeOf<TSlot> = TSlot extends FieldGroupFieldSlot<any, infer TMode> ? TMode : never;
|
|
19
|
+
type IsSame<TTypeA, TTypeB> = [TTypeA] extends [TTypeB] ? [TTypeB] extends [TTypeA] ? true : false : false;
|
|
20
|
+
type FieldGroupFieldSlotAllows<TSlot, TValue> = TSlot extends FieldGroupFieldSlot<infer TAcceptedValue, infer TMode> ? TMode extends 'strict' ? IsSame<TValue, TAcceptedValue> : [TValue] extends [TAcceptedValue] ? true : false : false;
|
|
21
|
+
type FieldGroupFieldNameForSlot<TFieldData, TSlot extends AnyFieldGroupFieldSlot> = { [TFieldName in DeepKeys<TFieldData>]: FieldGroupFieldSlotAllows<TSlot, DeepValue<TFieldData, TFieldName>> extends true ? TFieldName : never; }[DeepKeys<TFieldData>];
|
|
22
|
+
type FieldGroupFields = Record<string, AnyFieldGroupFieldSlot>;
|
|
23
|
+
type FieldGroupFieldNames<TFieldData, TFields extends FieldGroupFields> = { [TFieldName in keyof TFields]: FieldGroupFieldNameForSlot<TFieldData, TFields[TFieldName]>; };
|
|
24
|
+
type FieldGroupFieldData<TFields extends FieldGroupFields> = { [TFieldName in keyof TFields]: TFields[TFieldName] extends FieldGroupFieldSlot<infer TValue, any> ? TValue : never; };
|
|
25
|
+
type FieldGroupFieldsOf<TFieldGroup> = TFieldGroup extends {
|
|
26
|
+
readonly [fieldGroupFieldsSymbol]: infer TFields;
|
|
27
|
+
} ? TFields : never;
|
|
28
|
+
type VueFieldGroup<TFields extends FieldGroupFields, TFieldComponents extends Record<string, Component> = Record<never, never>> = FieldGroupApi<FieldGroupFieldData<TFields>, TFieldComponents> & {
|
|
29
|
+
readonly [fieldGroupFieldsSymbol]: TFields;
|
|
30
|
+
};
|
|
31
|
+
type FieldGroupFieldComponentsOf<TFieldGroup> = TFieldGroup extends VueFieldGroup<any, infer TFieldComponents> ? TFieldComponents : never;
|
|
32
|
+
type FieldGroupForm<TFieldComponents extends Record<string, Component> = Record<never, never>, TFormData = any> = FormApi<TFormData, any> & VueTanStackFormComponents<TFormData, any, TFieldComponents>;
|
|
33
|
+
type FieldGroupFieldBindingForSlot<TFormData, TSlot extends AnyFieldGroupFieldSlot> = TSlot extends FieldGroupFieldSlot<infer TValue, infer TMode> ? TMode extends 'strict' ? FieldGroupFieldNameForSlot<TFormData, TSlot> : DeepKeysWhereValueIncludes<TFormData, TValue> : never;
|
|
34
|
+
type FieldGroupFieldBindings<TFields extends FieldGroupFields, TFormData = any> = { [TFieldName in keyof TFields]: FieldGroupFieldBindingForSlot<TFormData, TFields[TFieldName]>; };
|
|
35
|
+
type FieldGroupFieldBindingsOf<TFieldGroup, TFormData> = FieldGroupFieldsOf<TFieldGroup> extends FieldGroupFields ? FieldGroupFieldBindings<FieldGroupFieldsOf<TFieldGroup>, TFormData> : never;
|
|
36
|
+
type FieldGroupFieldsPropName<TProps, TFieldGroup extends VueFieldGroup<any, any>> = { [TPropName in keyof TProps]-?: IsSame<TProps[TPropName], TFieldGroup> extends true ? TPropName : never; }[keyof TProps];
|
|
37
|
+
type FieldGroupWithFieldsFn<TFieldGroup extends VueFieldGroup<any, any>> = <TProps extends object, const TFieldsPropName extends PropertyKey>(component: Component & (new (props: TProps & PublicProps) => any), fieldsPropName: TFieldsPropName & FieldGroupFieldsPropName<TProps, TFieldGroup>) => new <TFormData>(props: Omit<TProps, TFieldsPropName | 'form'> & {
|
|
38
|
+
form: FieldGroupForm<FieldGroupFieldComponentsOf<TFieldGroup>, TFormData>;
|
|
39
|
+
} & { [TPropName in TFieldsPropName]: FieldGroupFieldBindingsOf<TFieldGroup, TFormData>; } & PublicProps) => VueComponentInstance<Omit<TProps, TFieldsPropName | 'form'> & {
|
|
40
|
+
form: FieldGroupForm<FieldGroupFieldComponentsOf<TFieldGroup>, TFormData>;
|
|
41
|
+
} & { [TPropName in TFieldsPropName]: FieldGroupFieldBindingsOf<TFieldGroup, TFormData>; } & Record<string, any>, {}>;
|
|
42
|
+
interface FieldGroupHelper {
|
|
43
|
+
strict: <TValue>() => StrictFieldGroupFieldSlot<TValue>;
|
|
44
|
+
loose: <TValue>() => LooseFieldGroupFieldSlot<TValue>;
|
|
45
|
+
}
|
|
46
|
+
interface FieldGroupDefinition<TFields extends FieldGroupFields, TFieldComponents extends Record<string, Component>> {
|
|
47
|
+
/** The virtual field-group API injected into the bound component. */
|
|
48
|
+
fields: VueFieldGroup<TFields, TFieldComponents>;
|
|
49
|
+
/** Binds a component's virtual field API to concrete paths in a form. */
|
|
50
|
+
bindComponent: FieldGroupWithFieldsFn<VueFieldGroup<TFields, TFieldComponents>>;
|
|
51
|
+
}
|
|
52
|
+
/** Signature shared by `defineFieldGroup` and app-form field-group definers. */
|
|
53
|
+
type DefineFieldGroupFn<TFieldComponents extends Record<string, Component>> = <const TFields extends FieldGroupFields>(defineFn: (helper: FieldGroupHelper) => TFields) => FieldGroupDefinition<TFields, TFieldComponents>;
|
|
54
|
+
/** Defines a reusable group of virtual fields. */
|
|
55
|
+
declare const defineFieldGroup: DefineFieldGroupFn<Record<never, never>>;
|
|
56
|
+
//#endregion
|
|
57
|
+
export { 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 };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { VueComponentWithSlots } from "./vueTypes.lib.js";
|
|
2
|
+
import { Atom, ReadonlyAtom, ReadonlyStore, Store } from "@tanstack/vue-store";
|
|
3
|
+
//#region src/Subscribe.public.d.ts
|
|
4
|
+
type SubscribeSource<TValue> = Atom<TValue> | ReadonlyAtom<TValue> | Store<TValue> | ReadonlyStore<TValue>;
|
|
5
|
+
interface SubscribeProps<in out TSourceData, in out TSelected> {
|
|
6
|
+
source: SubscribeSource<TSourceData>;
|
|
7
|
+
selector: (state: TSourceData) => TSelected;
|
|
8
|
+
when?: (selected: NoInfer<TSelected>) => boolean;
|
|
9
|
+
}
|
|
10
|
+
type SubscribeComponent = new <TSourceData, const TSelected>(props: SubscribeProps<TSourceData, TSelected>) => InstanceType<VueComponentWithSlots<SubscribeProps<TSourceData, TSelected>, {
|
|
11
|
+
default: NoInfer<TSelected>;
|
|
12
|
+
}>>;
|
|
13
|
+
declare const Subscribe: SubscribeComponent;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { Subscribe, SubscribeComponent, SubscribeProps, SubscribeSource };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { shallow, useSelector } from "@tanstack/vue-store";
|
|
2
|
+
import { defineComponent } from "vue";
|
|
3
|
+
|
|
4
|
+
//#region src/Subscribe.public.ts
|
|
5
|
+
const SubscribeImpl = defineComponent((props, { slots }) => {
|
|
6
|
+
const selected = useSelector(props.source, props.selector, { compare: shallow });
|
|
7
|
+
return () => {
|
|
8
|
+
if (props.when?.(selected.value) === false) return null;
|
|
9
|
+
return slots.default?.(selected.value);
|
|
10
|
+
};
|
|
11
|
+
}, {
|
|
12
|
+
name: "TanStackForm.Subscribe",
|
|
13
|
+
props: [
|
|
14
|
+
"source",
|
|
15
|
+
"selector",
|
|
16
|
+
"when"
|
|
17
|
+
]
|
|
18
|
+
});
|
|
19
|
+
const Subscribe = SubscribeImpl;
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
export { Subscribe };
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Subscribe } from "../Subscribe.public.js";
|
|
2
|
+
import { createArrayFieldSubscription, createValueFieldSubscription } from "./fieldSubscriptions.lib.js";
|
|
3
|
+
import { useField } from "./useField.lib.js";
|
|
4
|
+
import { shallow, useSelector } from "@tanstack/vue-store";
|
|
5
|
+
import { InternalFormGroupApi } from "@tanstack/form-core/internals";
|
|
6
|
+
import { defineComponent, h, onMounted, onUnmounted, provide, watchEffect } from "vue";
|
|
7
|
+
|
|
8
|
+
//#region src/VueForm/Components.lib.ts
|
|
9
|
+
function attachVueFormComponents(form, fieldComponents, fieldContext) {
|
|
10
|
+
const resultForm = form;
|
|
11
|
+
resultForm.Field = createFieldComponent(form, fieldComponents, false, fieldContext);
|
|
12
|
+
resultForm.ArrayField = createFieldComponent(form, fieldComponents, true, fieldContext);
|
|
13
|
+
resultForm.Subscribe = createSubscribeComponent(form);
|
|
14
|
+
resultForm.FormGroup = createFormGroupComponent(resultForm);
|
|
15
|
+
return resultForm;
|
|
16
|
+
}
|
|
17
|
+
function createFieldComponent(form, fieldComponents, array, fieldContext) {
|
|
18
|
+
return defineComponent((_props, context) => {
|
|
19
|
+
const options = () => ({
|
|
20
|
+
...context.attrs,
|
|
21
|
+
form
|
|
22
|
+
});
|
|
23
|
+
const fieldApi = useField(options, fieldComponents);
|
|
24
|
+
const selection = array ? createArrayFieldSubscription(fieldApi) : createValueFieldSubscription(fieldApi);
|
|
25
|
+
if (fieldContext) provide(fieldContext, fieldApi.value);
|
|
26
|
+
return () => {
|
|
27
|
+
selection.value;
|
|
28
|
+
return context.slots.default?.({ field: fieldApi.value });
|
|
29
|
+
};
|
|
30
|
+
}, {
|
|
31
|
+
name: array ? "TanStackForm.ArrayField" : "TanStackForm.Field",
|
|
32
|
+
inheritAttrs: false
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function createSubscribeComponent(form) {
|
|
36
|
+
return defineComponent((_props, context) => () => h(Subscribe, {
|
|
37
|
+
...context.attrs,
|
|
38
|
+
source: form.atom
|
|
39
|
+
}, context.slots), {
|
|
40
|
+
name: "TanStackForm.Subscribe",
|
|
41
|
+
inheritAttrs: false
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function createFormGroupComponent(form) {
|
|
45
|
+
return defineComponent((_props, context) => {
|
|
46
|
+
const options = () => ({
|
|
47
|
+
...context.attrs,
|
|
48
|
+
form
|
|
49
|
+
});
|
|
50
|
+
const group = attachVueFormGroupComponents(new InternalFormGroupApi(options()), form);
|
|
51
|
+
watchEffect(() => group.update(options()));
|
|
52
|
+
let mounted = false;
|
|
53
|
+
onMounted(() => {
|
|
54
|
+
mounted = true;
|
|
55
|
+
group.mount();
|
|
56
|
+
});
|
|
57
|
+
onUnmounted(() => {
|
|
58
|
+
if (mounted) group._cleanup();
|
|
59
|
+
});
|
|
60
|
+
const state = useSelector(group.atom, (value) => value, { compare: shallow });
|
|
61
|
+
return () => {
|
|
62
|
+
state.value;
|
|
63
|
+
return context.slots.default?.({ group });
|
|
64
|
+
};
|
|
65
|
+
}, {
|
|
66
|
+
name: "TanStackForm.FormGroup",
|
|
67
|
+
inheritAttrs: false
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function forwardToField(component, group) {
|
|
71
|
+
return defineComponent((_props, context) => () => {
|
|
72
|
+
const options = { ...context.attrs };
|
|
73
|
+
return h(component, group._getFormFieldOptions(options, (base, overrides) => ({
|
|
74
|
+
...base,
|
|
75
|
+
...overrides
|
|
76
|
+
})), context.slots);
|
|
77
|
+
}, { inheritAttrs: false });
|
|
78
|
+
}
|
|
79
|
+
function attachVueFormGroupComponents(group, form) {
|
|
80
|
+
const resultGroup = group;
|
|
81
|
+
resultGroup.Field = forwardToField(form.Field, group);
|
|
82
|
+
resultGroup.ArrayField = forwardToField(form.ArrayField, group);
|
|
83
|
+
resultGroup.Subscribe = defineComponent((_props, context) => () => h(Subscribe, {
|
|
84
|
+
...context.attrs,
|
|
85
|
+
source: group.atom
|
|
86
|
+
}, context.slots), {
|
|
87
|
+
name: "TanStackForm.FormGroup.Subscribe",
|
|
88
|
+
inheritAttrs: false
|
|
89
|
+
});
|
|
90
|
+
return resultGroup;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
//#endregion
|
|
94
|
+
export { attachVueFormComponents };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { VueComponentInstance } from "../vueTypes.lib.js";
|
|
2
|
+
import { DeepKeys, DeepKeysWhereValueIncludes, DeepValue, FieldApi, FieldApiOptions, FieldValidators, FormErrorTypes, FormGroupApi, FormGroupOptions, FormGroupState, FormGroupValidators, FormState, ToFieldError, ToFormGroupErrorTypes } from "@tanstack/form-core";
|
|
3
|
+
import { Component, PublicProps } from "vue";
|
|
4
|
+
//#region src/VueForm/Components.public.d.ts
|
|
5
|
+
declare const fieldComponentsType: unique symbol;
|
|
6
|
+
type ExactFieldBrand<out TValue> = {
|
|
7
|
+
readonly __tanstackFieldExactType: TValue;
|
|
8
|
+
};
|
|
9
|
+
type AcceptsFieldBrand<out TAcceptedValue> = {
|
|
10
|
+
readonly __tanstackFieldAcceptsType: TAcceptedValue;
|
|
11
|
+
};
|
|
12
|
+
type CompatibleFieldKey<TKey, TComponent, TTargetValue> = TComponent extends ExactFieldBrand<infer TExact> ? [TExact] extends [TTargetValue] ? [TTargetValue] extends [TExact] ? TKey : never : never : TComponent extends AcceptsFieldBrand<infer TLoose> ? [TTargetValue] extends [TLoose] ? TKey : never : TKey;
|
|
13
|
+
type FilteredFieldComponents<TFieldComponents extends Record<string, Component>, TTargetValue> = { [K in keyof TFieldComponents as CompatibleFieldKey<K, TFieldComponents[K], TTargetValue>]: TFieldComponents[K]; };
|
|
14
|
+
type FieldComponentsMatchingType<TFieldComponents extends Record<string, Component>, TTargetValue> = unknown extends TTargetValue ? TFieldComponents : string extends keyof TFieldComponents ? TFieldComponents : FilteredFieldComponents<TFieldComponents, TTargetValue>;
|
|
15
|
+
type VueFieldApi<TFieldName, TFieldValue, TFieldError, TFormData, TFormErrorTypes extends FormErrorTypes, TFieldComponents extends Record<string, Component>> = FieldApi<TFieldName, TFieldValue, TFieldError, TFormData, TFormErrorTypes> & FieldComponentsMatchingType<TFieldComponents, TFieldValue>;
|
|
16
|
+
interface VueSubscribeProps<in out TSourceData, in out TSelected> {
|
|
17
|
+
selector: (state: TSourceData) => TSelected;
|
|
18
|
+
when?: (selected: NoInfer<TSelected>) => boolean;
|
|
19
|
+
}
|
|
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>, {
|
|
22
|
+
default: NoInfer<TSelected>;
|
|
23
|
+
}>;
|
|
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> {
|
|
25
|
+
readonly [fieldComponentsType]?: TFieldComponents;
|
|
26
|
+
}
|
|
27
|
+
type VueFormFieldComponent<in out TFormData, in out TFormErrorTypes extends FormErrorTypes, in out TFieldComponents extends Record<string, Component>> = new <TFieldName extends DeepKeys<TFormData>, const TFieldValidators extends FieldValidators<TFormData, TFieldName, DeepValue<TFormData, TFieldName>>>(props: VueFormFieldProps<TFormData, TFieldName, DeepValue<TFormData, TFieldName>, TFieldValidators, never, TFormData, TFormErrorTypes, TFieldComponents> & PublicProps) => VueComponentInstance<VueFormFieldProps<TFormData, TFieldName, DeepValue<TFormData, TFieldName>, TFieldValidators, never, TFormData, TFormErrorTypes, TFieldComponents>, {
|
|
28
|
+
default: {
|
|
29
|
+
field: VueFieldApi<TFieldName, DeepValue<TFormData, TFieldName>, ToFieldError<NoInfer<TFieldValidators>, never, TFormErrorTypes>, TFormData, TFormErrorTypes, TFieldComponents>;
|
|
30
|
+
};
|
|
31
|
+
}>;
|
|
32
|
+
type VueFormArrayFieldComponent<in out TFormData, in out TFormErrorTypes extends FormErrorTypes, in out TFieldComponents extends Record<string, Component>> = new <TFieldName extends DeepKeysWhereValueIncludes<TFormData, Array<any>>, const TFieldValidators extends FieldValidators<TFormData, TFieldName, DeepValue<TFormData, TFieldName>>>(props: VueFormFieldProps<TFormData, TFieldName, DeepValue<TFormData, TFieldName>, TFieldValidators, never, TFormData, TFormErrorTypes, TFieldComponents> & PublicProps) => VueComponentInstance<VueFormFieldProps<TFormData, TFieldName, DeepValue<TFormData, TFieldName>, TFieldValidators, never, TFormData, TFormErrorTypes, TFieldComponents>, {
|
|
33
|
+
default: {
|
|
34
|
+
field: VueFieldApi<TFieldName, DeepValue<TFormData, TFieldName>, ToFieldError<NoInfer<TFieldValidators>, never, TFormErrorTypes>, TFormData, TFormErrorTypes, TFieldComponents>;
|
|
35
|
+
};
|
|
36
|
+
}>;
|
|
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>, {
|
|
39
|
+
default: NoInfer<TSelected>;
|
|
40
|
+
}>;
|
|
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>, {
|
|
42
|
+
default: {
|
|
43
|
+
field: VueFieldApi<TFieldName, DeepValue<TGroupValue, TFieldName>, ToFieldError<NoInfer<TFieldValidators>, TGroupErrorTypes['fieldError'], TFormErrorTypes>, TFormData, TFormErrorTypes, TFieldComponents>;
|
|
44
|
+
};
|
|
45
|
+
}>;
|
|
46
|
+
type VueFormGroupArrayFieldComponent<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 DeepKeysWhereValueIncludes<TGroupValue, Array<any>>, 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>, {
|
|
47
|
+
default: {
|
|
48
|
+
field: VueFieldApi<TFieldName, DeepValue<TGroupValue, TFieldName>, ToFieldError<NoInfer<TFieldValidators>, TGroupErrorTypes['fieldError'], TFormErrorTypes>, TFormData, TFormErrorTypes, TFieldComponents>;
|
|
49
|
+
};
|
|
50
|
+
}>;
|
|
51
|
+
interface VueFormGroupApi<in out TFormData, in out TGroupName, in out TGroupValue, in out TGroupErrorTypes extends FormErrorTypes, in out TFormErrorTypes extends FormErrorTypes, in out TFieldComponents extends Record<string, Component>> extends FormGroupApi<TFormData, TGroupName, TGroupValue, TGroupErrorTypes, TFormErrorTypes> {
|
|
52
|
+
Field: VueFormGroupFieldComponent<TFormData, TGroupValue, TGroupErrorTypes, TFormErrorTypes, TFieldComponents>;
|
|
53
|
+
ArrayField: VueFormGroupArrayFieldComponent<TFormData, TGroupValue, TGroupErrorTypes, TFormErrorTypes, TFieldComponents>;
|
|
54
|
+
Subscribe: VueFormGroupSubscribeComponent<TGroupValue, TGroupErrorTypes>;
|
|
55
|
+
}
|
|
56
|
+
interface VueFormGroupProps<in out TFormData, in out TGroupName, in out TGroupValue, in out TGroupValidators extends FormGroupValidators<TGroupValue>, in out TFormErrorTypes extends FormErrorTypes, in out TFieldComponents extends Record<string, Component>> extends Omit<FormGroupOptions<TFormData, TGroupName, TGroupValue, TGroupValidators, TFormErrorTypes>, 'form'> {
|
|
57
|
+
readonly [fieldComponentsType]?: TFieldComponents;
|
|
58
|
+
}
|
|
59
|
+
type VueFormGroupComponent<in out TFormData, in out TFormErrorTypes extends FormErrorTypes, in out TFieldComponents extends Record<string, Component>> = new <TGroupName extends DeepKeys<TFormData>, TGroupValue extends DeepValue<TFormData, TGroupName>, const TGroupValidators extends FormGroupValidators<TGroupValue>>(props: VueFormGroupProps<TFormData, TGroupName, TGroupValue, TGroupValidators, TFormErrorTypes, TFieldComponents> & PublicProps) => VueComponentInstance<VueFormGroupProps<TFormData, TGroupName, TGroupValue, TGroupValidators, TFormErrorTypes, TFieldComponents>, {
|
|
60
|
+
default: {
|
|
61
|
+
group: VueFormGroupApi<TFormData, TGroupName, TGroupValue, ToFormGroupErrorTypes<NoInfer<TGroupValidators>>, TFormErrorTypes, TFieldComponents>;
|
|
62
|
+
};
|
|
63
|
+
}>;
|
|
64
|
+
interface VueTanStackFormComponents<in out TFormData, in out TFormErrorTypes extends FormErrorTypes, in out TFieldComponents extends Record<string, Component> = Record<never, never>> {
|
|
65
|
+
Field: VueFormFieldComponent<TFormData, TFormErrorTypes, TFieldComponents>;
|
|
66
|
+
ArrayField: VueFormArrayFieldComponent<TFormData, TFormErrorTypes, TFieldComponents>;
|
|
67
|
+
Subscribe: VueFormSubscribeComponent<TFormData, TFormErrorTypes>;
|
|
68
|
+
FormGroup: VueFormGroupComponent<TFormData, TFormErrorTypes, TFieldComponents>;
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
export { VueFieldApi, VueFormArrayFieldComponent, VueFormFieldComponent, VueFormFieldProps, VueFormGroupApi, VueFormGroupArrayFieldComponent, VueFormGroupComponent, VueFormGroupFieldComponent, VueFormGroupProps, VueFormGroupSubscribeComponent, VueFormGroupSubscribeProps, VueFormSubscribeComponent, VueFormSubscribeProps, VueTanStackFormComponents };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { attachVueFormComponents } from "./Components.lib.js";
|
|
2
|
+
import { InternalFormApi } from "@tanstack/form-core/internals";
|
|
3
|
+
import { onMounted, onUnmounted, useId, watchEffect } from "vue";
|
|
4
|
+
|
|
5
|
+
//#region src/VueForm/VueFormApi.lib.ts
|
|
6
|
+
function initializeForm(options) {
|
|
7
|
+
return attachVueFormComponents(new InternalFormApi(options), null);
|
|
8
|
+
}
|
|
9
|
+
function useInternalForm(options, initializeFn) {
|
|
10
|
+
const vueFormId = useId();
|
|
11
|
+
const resolveOptions = () => options.formId === void 0 ? {
|
|
12
|
+
...options,
|
|
13
|
+
formId: vueFormId
|
|
14
|
+
} : options;
|
|
15
|
+
const form = initializeFn(resolveOptions());
|
|
16
|
+
watchEffect(() => form._update(resolveOptions()));
|
|
17
|
+
let unmount;
|
|
18
|
+
onMounted(() => {
|
|
19
|
+
unmount = form.mount();
|
|
20
|
+
});
|
|
21
|
+
onUnmounted(() => unmount?.());
|
|
22
|
+
return form;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
export { initializeForm, useInternalForm };
|