@tanstack/vue-form 0.3.5 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/legacy/types.cjs.map +1 -1
- package/build/legacy/types.d.cts +2 -2
- package/build/legacy/types.d.ts +2 -2
- package/build/legacy/useField.cjs.map +1 -1
- package/build/legacy/useField.d.cts +13 -13
- package/build/legacy/useField.d.ts +13 -13
- package/build/legacy/useField.js.map +1 -1
- package/build/modern/types.cjs.map +1 -1
- package/build/modern/types.d.cts +2 -2
- package/build/modern/types.d.ts +2 -2
- package/build/modern/useField.cjs.map +1 -1
- package/build/modern/useField.d.cts +13 -13
- package/build/modern/useField.d.ts +13 -13
- package/build/modern/useField.js.map +1 -1
- package/package.json +2 -2
- package/src/tests/useField.test.tsx +5 -5
- package/src/tests/useForm.test.tsx +35 -4
- package/src/types.ts +3 -3
- package/src/useField.tsx +17 -34
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../src/types.ts"],"sourcesContent":["import type { FieldOptions, DeepKeys } from '@tanstack/form-core'\n\nexport type UseFieldOptions<\n
|
1
|
+
{"version":3,"sources":["../../src/types.ts"],"sourcesContent":["import type { FieldOptions, DeepKeys, DeepValue } from '@tanstack/form-core'\n\nexport type UseFieldOptions<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TData = DeepValue<TParentData, TName>,\n> = FieldOptions<TParentData, TName, TData> & {\n mode?: 'value' | 'array'\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
package/build/legacy/types.d.cts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
import { DeepKeys, FieldOptions } from '@tanstack/form-core';
|
1
|
+
import { DeepKeys, DeepValue, FieldOptions } from '@tanstack/form-core';
|
2
2
|
|
3
|
-
type UseFieldOptions<
|
3
|
+
type UseFieldOptions<TParentData, TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>> = FieldOptions<TParentData, TName, TData> & {
|
4
4
|
mode?: 'value' | 'array';
|
5
5
|
};
|
6
6
|
|
package/build/legacy/types.d.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
import { DeepKeys, FieldOptions } from '@tanstack/form-core';
|
1
|
+
import { DeepKeys, DeepValue, FieldOptions } from '@tanstack/form-core';
|
2
2
|
|
3
|
-
type UseFieldOptions<
|
3
|
+
type UseFieldOptions<TParentData, TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>> = FieldOptions<TParentData, TName, TData> & {
|
4
4
|
mode?: 'value' | 'array';
|
5
5
|
};
|
6
6
|
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../src/useField.tsx"],"sourcesContent":["import { FieldApi } from '@tanstack/form-core'\nimport type {
|
1
|
+
{"version":3,"sources":["../../src/useField.tsx"],"sourcesContent":["import { FieldApi } from '@tanstack/form-core'\nimport type { DeepKeys, DeepValue, Narrow } from '@tanstack/form-core'\nimport { useStore } from '@tanstack/vue-store'\nimport { defineComponent, onMounted, onUnmounted, watch } from 'vue-demi'\nimport type { SlotsType, SetupContext, Ref } from 'vue-demi'\nimport { provideFormContext, useFormContext } from './formContext'\nimport type { UseFieldOptions } from './types'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FieldApi<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TData = DeepValue<TParentData, TName>,\n > {\n Field: FieldComponent<TData>\n }\n}\n\nexport type UseField<TParentData> = <TName extends DeepKeys<TParentData>>(\n opts?: { name: Narrow<TName> } & UseFieldOptions<\n TParentData,\n TName,\n DeepValue<TParentData, TName>\n >,\n) => FieldApi<TParentData, TName, DeepValue<TParentData, TName>>\n\nexport function useField<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TData = DeepValue<TParentData, TName>,\n>(\n opts: UseFieldOptions<TParentData, TName>,\n): {\n api: FieldApi<\n TParentData,\n TName\n // Omit<typeof opts, 'onMount'> & {\n // form: FormApi<TParentData>\n // }\n >\n state: Readonly<\n Ref<\n FieldApi<\n TParentData,\n TName,\n TData\n // Omit<typeof opts, 'onMount'> & {\n // form: FormApi<TParentData>\n // }\n >['state']\n >\n >\n} {\n // Get the form API either manually or from context\n const { formApi, parentFieldName } = useFormContext()\n\n const fieldApi = (() => {\n const api = new FieldApi({\n ...opts,\n form: formApi,\n name: opts.name,\n } as never)\n\n api.Field = Field as never\n\n return api\n })()\n\n const fieldState = useStore(fieldApi.store, (state) => state)\n\n let cleanup!: () => void\n onMounted(() => {\n cleanup = fieldApi.mount()\n })\n\n onUnmounted(() => {\n cleanup()\n })\n\n watch(\n () => opts,\n () => {\n // Keep options up to date as they are rendered\n fieldApi.update({ ...opts, form: formApi } as never)\n },\n )\n\n return { api: fieldApi, state: fieldState } as never\n}\n\nexport type FieldValue<TParentData, TName> = TParentData extends any[]\n ? unknown extends TName\n ? TParentData[number]\n : DeepValue<TParentData[number], TName>\n : DeepValue<TParentData, TName>\n\ntype FieldComponentProps<\n TParentData,\n TName extends DeepKeys<TParentData>,\n> = (TParentData extends any[]\n ? {\n name?: TName\n index: number\n }\n : {\n name: TName\n index?: never\n }) &\n Omit<UseFieldOptions<TParentData, TName>, 'name' | 'index'>\n\nexport type FieldComponent<TParentData> = <\n TName extends DeepKeys<TParentData>,\n TData = DeepValue<TParentData, TName>,\n>(\n fieldOptions: FieldComponentProps<TParentData, TName>,\n context: SetupContext<\n {},\n SlotsType<{\n default: {\n field: FieldApi<TParentData, TName, TData>\n state: FieldApi<TParentData, TName, TData>['state']\n }\n }>\n >,\n) => any\n\nexport const Field = defineComponent(\n <TParentData, TName extends DeepKeys<TParentData>>(\n fieldOptions: UseFieldOptions<TParentData, TName>,\n context: SetupContext,\n ) => {\n const fieldApi = useField({ ...fieldOptions, ...context.attrs } as any)\n\n provideFormContext({\n formApi: fieldApi.api.form,\n parentFieldName: fieldApi.api.name,\n } as never)\n\n return () =>\n context.slots.default!({\n field: fieldApi.api,\n state: fieldApi.state.value,\n })\n },\n { name: 'Field', inheritAttrs: false },\n)\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAAyB;AAEzB,uBAAyB;AACzB,sBAA+D;AAE/D,yBAAmD;AAsB5C,SAAS,SAKd,MAqBA;AAEA,QAAM,EAAE,SAAS,gBAAgB,QAAI,mCAAe;AAEpD,QAAM,YAAY,MAAM;AACtB,UAAM,MAAM,IAAI,0BAAS;AAAA,MACvB,GAAG;AAAA,MACH,MAAM;AAAA,MACN,MAAM,KAAK;AAAA,IACb,CAAU;AAEV,QAAI,QAAQ;AAEZ,WAAO;AAAA,EACT,GAAG;AAEH,QAAM,iBAAa,2BAAS,SAAS,OAAO,CAAC,UAAU,KAAK;AAE5D,MAAI;AACJ,iCAAU,MAAM;AACd,cAAU,SAAS,MAAM;AAAA,EAC3B,CAAC;AAED,mCAAY,MAAM;AAChB,YAAQ;AAAA,EACV,CAAC;AAED;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAEJ,eAAS,OAAO,EAAE,GAAG,MAAM,MAAM,QAAQ,CAAU;AAAA,IACrD;AAAA,EACF;AAEA,SAAO,EAAE,KAAK,UAAU,OAAO,WAAW;AAC5C;AAsCO,IAAM,YAAQ;AAAA,EACnB,CACE,cACA,YACG;AACH,UAAM,WAAW,SAAS,EAAE,GAAG,cAAc,GAAG,QAAQ,MAAM,CAAQ;AAEtE,+CAAmB;AAAA,MACjB,SAAS,SAAS,IAAI;AAAA,MACtB,iBAAiB,SAAS,IAAI;AAAA,IAChC,CAAU;AAEV,WAAO,MACL,QAAQ,MAAM,QAAS;AAAA,MACrB,OAAO,SAAS;AAAA,MAChB,OAAO,SAAS,MAAM;AAAA,IACxB,CAAC;AAAA,EACL;AAAA,EACA,EAAE,MAAM,SAAS,cAAc,MAAM;AACvC;","names":[]}
|
@@ -1,35 +1,35 @@
|
|
1
1
|
import * as _tanstack_form_core from '@tanstack/form-core';
|
2
|
-
import { DeepKeys,
|
2
|
+
import { DeepKeys, DeepValue, FieldApi, Narrow } from '@tanstack/form-core';
|
3
3
|
import { SetupContext, SlotsType, Ref } from 'vue-demi';
|
4
4
|
import { UseFieldOptions } from './types.cjs';
|
5
5
|
|
6
6
|
declare module '@tanstack/form-core' {
|
7
|
-
interface FieldApi<
|
8
|
-
Field: FieldComponent<
|
7
|
+
interface FieldApi<TParentData, TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>> {
|
8
|
+
Field: FieldComponent<TData>;
|
9
9
|
}
|
10
10
|
}
|
11
11
|
type UseField<TParentData> = <TName extends DeepKeys<TParentData>>(opts?: {
|
12
12
|
name: Narrow<TName>;
|
13
|
-
} & UseFieldOptions<
|
14
|
-
declare function useField<
|
15
|
-
api: FieldApi<
|
16
|
-
state: Readonly<Ref<FieldApi<
|
13
|
+
} & UseFieldOptions<TParentData, TName, DeepValue<TParentData, TName>>) => FieldApi<TParentData, TName, DeepValue<TParentData, TName>>;
|
14
|
+
declare function useField<TParentData, TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>>(opts: UseFieldOptions<TParentData, TName>): {
|
15
|
+
api: FieldApi<TParentData, TName>;
|
16
|
+
state: Readonly<Ref<FieldApi<TParentData, TName, TData>['state']>>;
|
17
17
|
};
|
18
18
|
type FieldValue<TParentData, TName> = TParentData extends any[] ? unknown extends TName ? TParentData[number] : DeepValue<TParentData[number], TName> : DeepValue<TParentData, TName>;
|
19
|
-
type FieldComponentProps<
|
19
|
+
type FieldComponentProps<TParentData, TName extends DeepKeys<TParentData>> = (TParentData extends any[] ? {
|
20
20
|
name?: TName;
|
21
21
|
index: number;
|
22
22
|
} : {
|
23
23
|
name: TName;
|
24
24
|
index?: never;
|
25
|
-
}) & Omit<UseFieldOptions<
|
26
|
-
type FieldComponent<TParentData> = <
|
25
|
+
}) & Omit<UseFieldOptions<TParentData, TName>, 'name' | 'index'>;
|
26
|
+
type FieldComponent<TParentData> = <TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>>(fieldOptions: FieldComponentProps<TParentData, TName>, context: SetupContext<{}, SlotsType<{
|
27
27
|
default: {
|
28
|
-
field: FieldApi<
|
29
|
-
state: FieldApi<
|
28
|
+
field: FieldApi<TParentData, TName, TData>;
|
29
|
+
state: FieldApi<TParentData, TName, TData>['state'];
|
30
30
|
};
|
31
31
|
}>>) => any;
|
32
|
-
declare const Field: <
|
32
|
+
declare const Field: <TParentData, TName extends DeepKeys<TParentData>>(props: _tanstack_form_core.FieldOptions<TParentData, TName, DeepValue<TParentData, TName>> & {
|
33
33
|
mode?: "value" | "array" | undefined;
|
34
34
|
} & ({
|
35
35
|
[x: `on${Capitalize<string>}`]: ((...args: never) => any) | undefined;
|
@@ -1,35 +1,35 @@
|
|
1
1
|
import * as _tanstack_form_core from '@tanstack/form-core';
|
2
|
-
import { DeepKeys,
|
2
|
+
import { DeepKeys, DeepValue, FieldApi, Narrow } from '@tanstack/form-core';
|
3
3
|
import { SetupContext, SlotsType, Ref } from 'vue-demi';
|
4
4
|
import { UseFieldOptions } from './types.js';
|
5
5
|
|
6
6
|
declare module '@tanstack/form-core' {
|
7
|
-
interface FieldApi<
|
8
|
-
Field: FieldComponent<
|
7
|
+
interface FieldApi<TParentData, TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>> {
|
8
|
+
Field: FieldComponent<TData>;
|
9
9
|
}
|
10
10
|
}
|
11
11
|
type UseField<TParentData> = <TName extends DeepKeys<TParentData>>(opts?: {
|
12
12
|
name: Narrow<TName>;
|
13
|
-
} & UseFieldOptions<
|
14
|
-
declare function useField<
|
15
|
-
api: FieldApi<
|
16
|
-
state: Readonly<Ref<FieldApi<
|
13
|
+
} & UseFieldOptions<TParentData, TName, DeepValue<TParentData, TName>>) => FieldApi<TParentData, TName, DeepValue<TParentData, TName>>;
|
14
|
+
declare function useField<TParentData, TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>>(opts: UseFieldOptions<TParentData, TName>): {
|
15
|
+
api: FieldApi<TParentData, TName>;
|
16
|
+
state: Readonly<Ref<FieldApi<TParentData, TName, TData>['state']>>;
|
17
17
|
};
|
18
18
|
type FieldValue<TParentData, TName> = TParentData extends any[] ? unknown extends TName ? TParentData[number] : DeepValue<TParentData[number], TName> : DeepValue<TParentData, TName>;
|
19
|
-
type FieldComponentProps<
|
19
|
+
type FieldComponentProps<TParentData, TName extends DeepKeys<TParentData>> = (TParentData extends any[] ? {
|
20
20
|
name?: TName;
|
21
21
|
index: number;
|
22
22
|
} : {
|
23
23
|
name: TName;
|
24
24
|
index?: never;
|
25
|
-
}) & Omit<UseFieldOptions<
|
26
|
-
type FieldComponent<TParentData> = <
|
25
|
+
}) & Omit<UseFieldOptions<TParentData, TName>, 'name' | 'index'>;
|
26
|
+
type FieldComponent<TParentData> = <TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>>(fieldOptions: FieldComponentProps<TParentData, TName>, context: SetupContext<{}, SlotsType<{
|
27
27
|
default: {
|
28
|
-
field: FieldApi<
|
29
|
-
state: FieldApi<
|
28
|
+
field: FieldApi<TParentData, TName, TData>;
|
29
|
+
state: FieldApi<TParentData, TName, TData>['state'];
|
30
30
|
};
|
31
31
|
}>>) => any;
|
32
|
-
declare const Field: <
|
32
|
+
declare const Field: <TParentData, TName extends DeepKeys<TParentData>>(props: _tanstack_form_core.FieldOptions<TParentData, TName, DeepValue<TParentData, TName>> & {
|
33
33
|
mode?: "value" | "array" | undefined;
|
34
34
|
} & ({
|
35
35
|
[x: `on${Capitalize<string>}`]: ((...args: never) => any) | undefined;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../src/useField.tsx"],"sourcesContent":["import { FieldApi } from '@tanstack/form-core'\nimport type {
|
1
|
+
{"version":3,"sources":["../../src/useField.tsx"],"sourcesContent":["import { FieldApi } from '@tanstack/form-core'\nimport type { DeepKeys, DeepValue, Narrow } from '@tanstack/form-core'\nimport { useStore } from '@tanstack/vue-store'\nimport { defineComponent, onMounted, onUnmounted, watch } from 'vue-demi'\nimport type { SlotsType, SetupContext, Ref } from 'vue-demi'\nimport { provideFormContext, useFormContext } from './formContext'\nimport type { UseFieldOptions } from './types'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FieldApi<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TData = DeepValue<TParentData, TName>,\n > {\n Field: FieldComponent<TData>\n }\n}\n\nexport type UseField<TParentData> = <TName extends DeepKeys<TParentData>>(\n opts?: { name: Narrow<TName> } & UseFieldOptions<\n TParentData,\n TName,\n DeepValue<TParentData, TName>\n >,\n) => FieldApi<TParentData, TName, DeepValue<TParentData, TName>>\n\nexport function useField<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TData = DeepValue<TParentData, TName>,\n>(\n opts: UseFieldOptions<TParentData, TName>,\n): {\n api: FieldApi<\n TParentData,\n TName\n // Omit<typeof opts, 'onMount'> & {\n // form: FormApi<TParentData>\n // }\n >\n state: Readonly<\n Ref<\n FieldApi<\n TParentData,\n TName,\n TData\n // Omit<typeof opts, 'onMount'> & {\n // form: FormApi<TParentData>\n // }\n >['state']\n >\n >\n} {\n // Get the form API either manually or from context\n const { formApi, parentFieldName } = useFormContext()\n\n const fieldApi = (() => {\n const api = new FieldApi({\n ...opts,\n form: formApi,\n name: opts.name,\n } as never)\n\n api.Field = Field as never\n\n return api\n })()\n\n const fieldState = useStore(fieldApi.store, (state) => state)\n\n let cleanup!: () => void\n onMounted(() => {\n cleanup = fieldApi.mount()\n })\n\n onUnmounted(() => {\n cleanup()\n })\n\n watch(\n () => opts,\n () => {\n // Keep options up to date as they are rendered\n fieldApi.update({ ...opts, form: formApi } as never)\n },\n )\n\n return { api: fieldApi, state: fieldState } as never\n}\n\nexport type FieldValue<TParentData, TName> = TParentData extends any[]\n ? unknown extends TName\n ? TParentData[number]\n : DeepValue<TParentData[number], TName>\n : DeepValue<TParentData, TName>\n\ntype FieldComponentProps<\n TParentData,\n TName extends DeepKeys<TParentData>,\n> = (TParentData extends any[]\n ? {\n name?: TName\n index: number\n }\n : {\n name: TName\n index?: never\n }) &\n Omit<UseFieldOptions<TParentData, TName>, 'name' | 'index'>\n\nexport type FieldComponent<TParentData> = <\n TName extends DeepKeys<TParentData>,\n TData = DeepValue<TParentData, TName>,\n>(\n fieldOptions: FieldComponentProps<TParentData, TName>,\n context: SetupContext<\n {},\n SlotsType<{\n default: {\n field: FieldApi<TParentData, TName, TData>\n state: FieldApi<TParentData, TName, TData>['state']\n }\n }>\n >,\n) => any\n\nexport const Field = defineComponent(\n <TParentData, TName extends DeepKeys<TParentData>>(\n fieldOptions: UseFieldOptions<TParentData, TName>,\n context: SetupContext,\n ) => {\n const fieldApi = useField({ ...fieldOptions, ...context.attrs } as any)\n\n provideFormContext({\n formApi: fieldApi.api.form,\n parentFieldName: fieldApi.api.name,\n } as never)\n\n return () =>\n context.slots.default!({\n field: fieldApi.api,\n state: fieldApi.state.value,\n })\n },\n { name: 'Field', inheritAttrs: false },\n)\n"],"mappings":";AAAA,SAAS,gBAAgB;AAEzB,SAAS,gBAAgB;AACzB,SAAS,iBAAiB,WAAW,aAAa,aAAa;AAE/D,SAAS,oBAAoB,sBAAsB;AAsB5C,SAAS,SAKd,MAqBA;AAEA,QAAM,EAAE,SAAS,gBAAgB,IAAI,eAAe;AAEpD,QAAM,YAAY,MAAM;AACtB,UAAM,MAAM,IAAI,SAAS;AAAA,MACvB,GAAG;AAAA,MACH,MAAM;AAAA,MACN,MAAM,KAAK;AAAA,IACb,CAAU;AAEV,QAAI,QAAQ;AAEZ,WAAO;AAAA,EACT,GAAG;AAEH,QAAM,aAAa,SAAS,SAAS,OAAO,CAAC,UAAU,KAAK;AAE5D,MAAI;AACJ,YAAU,MAAM;AACd,cAAU,SAAS,MAAM;AAAA,EAC3B,CAAC;AAED,cAAY,MAAM;AAChB,YAAQ;AAAA,EACV,CAAC;AAED;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAEJ,eAAS,OAAO,EAAE,GAAG,MAAM,MAAM,QAAQ,CAAU;AAAA,IACrD;AAAA,EACF;AAEA,SAAO,EAAE,KAAK,UAAU,OAAO,WAAW;AAC5C;AAsCO,IAAM,QAAQ;AAAA,EACnB,CACE,cACA,YACG;AACH,UAAM,WAAW,SAAS,EAAE,GAAG,cAAc,GAAG,QAAQ,MAAM,CAAQ;AAEtE,uBAAmB;AAAA,MACjB,SAAS,SAAS,IAAI;AAAA,MACtB,iBAAiB,SAAS,IAAI;AAAA,IAChC,CAAU;AAEV,WAAO,MACL,QAAQ,MAAM,QAAS;AAAA,MACrB,OAAO,SAAS;AAAA,MAChB,OAAO,SAAS,MAAM;AAAA,IACxB,CAAC;AAAA,EACL;AAAA,EACA,EAAE,MAAM,SAAS,cAAc,MAAM;AACvC;","names":[]}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../src/types.ts"],"sourcesContent":["import type { FieldOptions, DeepKeys } from '@tanstack/form-core'\n\nexport type UseFieldOptions<\n
|
1
|
+
{"version":3,"sources":["../../src/types.ts"],"sourcesContent":["import type { FieldOptions, DeepKeys, DeepValue } from '@tanstack/form-core'\n\nexport type UseFieldOptions<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TData = DeepValue<TParentData, TName>,\n> = FieldOptions<TParentData, TName, TData> & {\n mode?: 'value' | 'array'\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
package/build/modern/types.d.cts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
import { DeepKeys, FieldOptions } from '@tanstack/form-core';
|
1
|
+
import { DeepKeys, DeepValue, FieldOptions } from '@tanstack/form-core';
|
2
2
|
|
3
|
-
type UseFieldOptions<
|
3
|
+
type UseFieldOptions<TParentData, TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>> = FieldOptions<TParentData, TName, TData> & {
|
4
4
|
mode?: 'value' | 'array';
|
5
5
|
};
|
6
6
|
|
package/build/modern/types.d.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
import { DeepKeys, FieldOptions } from '@tanstack/form-core';
|
1
|
+
import { DeepKeys, DeepValue, FieldOptions } from '@tanstack/form-core';
|
2
2
|
|
3
|
-
type UseFieldOptions<
|
3
|
+
type UseFieldOptions<TParentData, TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>> = FieldOptions<TParentData, TName, TData> & {
|
4
4
|
mode?: 'value' | 'array';
|
5
5
|
};
|
6
6
|
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../src/useField.tsx"],"sourcesContent":["import { FieldApi } from '@tanstack/form-core'\nimport type {
|
1
|
+
{"version":3,"sources":["../../src/useField.tsx"],"sourcesContent":["import { FieldApi } from '@tanstack/form-core'\nimport type { DeepKeys, DeepValue, Narrow } from '@tanstack/form-core'\nimport { useStore } from '@tanstack/vue-store'\nimport { defineComponent, onMounted, onUnmounted, watch } from 'vue-demi'\nimport type { SlotsType, SetupContext, Ref } from 'vue-demi'\nimport { provideFormContext, useFormContext } from './formContext'\nimport type { UseFieldOptions } from './types'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FieldApi<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TData = DeepValue<TParentData, TName>,\n > {\n Field: FieldComponent<TData>\n }\n}\n\nexport type UseField<TParentData> = <TName extends DeepKeys<TParentData>>(\n opts?: { name: Narrow<TName> } & UseFieldOptions<\n TParentData,\n TName,\n DeepValue<TParentData, TName>\n >,\n) => FieldApi<TParentData, TName, DeepValue<TParentData, TName>>\n\nexport function useField<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TData = DeepValue<TParentData, TName>,\n>(\n opts: UseFieldOptions<TParentData, TName>,\n): {\n api: FieldApi<\n TParentData,\n TName\n // Omit<typeof opts, 'onMount'> & {\n // form: FormApi<TParentData>\n // }\n >\n state: Readonly<\n Ref<\n FieldApi<\n TParentData,\n TName,\n TData\n // Omit<typeof opts, 'onMount'> & {\n // form: FormApi<TParentData>\n // }\n >['state']\n >\n >\n} {\n // Get the form API either manually or from context\n const { formApi, parentFieldName } = useFormContext()\n\n const fieldApi = (() => {\n const api = new FieldApi({\n ...opts,\n form: formApi,\n name: opts.name,\n } as never)\n\n api.Field = Field as never\n\n return api\n })()\n\n const fieldState = useStore(fieldApi.store, (state) => state)\n\n let cleanup!: () => void\n onMounted(() => {\n cleanup = fieldApi.mount()\n })\n\n onUnmounted(() => {\n cleanup()\n })\n\n watch(\n () => opts,\n () => {\n // Keep options up to date as they are rendered\n fieldApi.update({ ...opts, form: formApi } as never)\n },\n )\n\n return { api: fieldApi, state: fieldState } as never\n}\n\nexport type FieldValue<TParentData, TName> = TParentData extends any[]\n ? unknown extends TName\n ? TParentData[number]\n : DeepValue<TParentData[number], TName>\n : DeepValue<TParentData, TName>\n\ntype FieldComponentProps<\n TParentData,\n TName extends DeepKeys<TParentData>,\n> = (TParentData extends any[]\n ? {\n name?: TName\n index: number\n }\n : {\n name: TName\n index?: never\n }) &\n Omit<UseFieldOptions<TParentData, TName>, 'name' | 'index'>\n\nexport type FieldComponent<TParentData> = <\n TName extends DeepKeys<TParentData>,\n TData = DeepValue<TParentData, TName>,\n>(\n fieldOptions: FieldComponentProps<TParentData, TName>,\n context: SetupContext<\n {},\n SlotsType<{\n default: {\n field: FieldApi<TParentData, TName, TData>\n state: FieldApi<TParentData, TName, TData>['state']\n }\n }>\n >,\n) => any\n\nexport const Field = defineComponent(\n <TParentData, TName extends DeepKeys<TParentData>>(\n fieldOptions: UseFieldOptions<TParentData, TName>,\n context: SetupContext,\n ) => {\n const fieldApi = useField({ ...fieldOptions, ...context.attrs } as any)\n\n provideFormContext({\n formApi: fieldApi.api.form,\n parentFieldName: fieldApi.api.name,\n } as never)\n\n return () =>\n context.slots.default!({\n field: fieldApi.api,\n state: fieldApi.state.value,\n })\n },\n { name: 'Field', inheritAttrs: false },\n)\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAAyB;AAEzB,uBAAyB;AACzB,sBAA+D;AAE/D,yBAAmD;AAsB5C,SAAS,SAKd,MAqBA;AAEA,QAAM,EAAE,SAAS,gBAAgB,QAAI,mCAAe;AAEpD,QAAM,YAAY,MAAM;AACtB,UAAM,MAAM,IAAI,0BAAS;AAAA,MACvB,GAAG;AAAA,MACH,MAAM;AAAA,MACN,MAAM,KAAK;AAAA,IACb,CAAU;AAEV,QAAI,QAAQ;AAEZ,WAAO;AAAA,EACT,GAAG;AAEH,QAAM,iBAAa,2BAAS,SAAS,OAAO,CAAC,UAAU,KAAK;AAE5D,MAAI;AACJ,iCAAU,MAAM;AACd,cAAU,SAAS,MAAM;AAAA,EAC3B,CAAC;AAED,mCAAY,MAAM;AAChB,YAAQ;AAAA,EACV,CAAC;AAED;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAEJ,eAAS,OAAO,EAAE,GAAG,MAAM,MAAM,QAAQ,CAAU;AAAA,IACrD;AAAA,EACF;AAEA,SAAO,EAAE,KAAK,UAAU,OAAO,WAAW;AAC5C;AAsCO,IAAM,YAAQ;AAAA,EACnB,CACE,cACA,YACG;AACH,UAAM,WAAW,SAAS,EAAE,GAAG,cAAc,GAAG,QAAQ,MAAM,CAAQ;AAEtE,+CAAmB;AAAA,MACjB,SAAS,SAAS,IAAI;AAAA,MACtB,iBAAiB,SAAS,IAAI;AAAA,IAChC,CAAU;AAEV,WAAO,MACL,QAAQ,MAAM,QAAS;AAAA,MACrB,OAAO,SAAS;AAAA,MAChB,OAAO,SAAS,MAAM;AAAA,IACxB,CAAC;AAAA,EACL;AAAA,EACA,EAAE,MAAM,SAAS,cAAc,MAAM;AACvC;","names":[]}
|
@@ -1,35 +1,35 @@
|
|
1
1
|
import * as _tanstack_form_core from '@tanstack/form-core';
|
2
|
-
import { DeepKeys,
|
2
|
+
import { DeepKeys, DeepValue, FieldApi, Narrow } from '@tanstack/form-core';
|
3
3
|
import { SetupContext, SlotsType, Ref } from 'vue-demi';
|
4
4
|
import { UseFieldOptions } from './types.cjs';
|
5
5
|
|
6
6
|
declare module '@tanstack/form-core' {
|
7
|
-
interface FieldApi<
|
8
|
-
Field: FieldComponent<
|
7
|
+
interface FieldApi<TParentData, TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>> {
|
8
|
+
Field: FieldComponent<TData>;
|
9
9
|
}
|
10
10
|
}
|
11
11
|
type UseField<TParentData> = <TName extends DeepKeys<TParentData>>(opts?: {
|
12
12
|
name: Narrow<TName>;
|
13
|
-
} & UseFieldOptions<
|
14
|
-
declare function useField<
|
15
|
-
api: FieldApi<
|
16
|
-
state: Readonly<Ref<FieldApi<
|
13
|
+
} & UseFieldOptions<TParentData, TName, DeepValue<TParentData, TName>>) => FieldApi<TParentData, TName, DeepValue<TParentData, TName>>;
|
14
|
+
declare function useField<TParentData, TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>>(opts: UseFieldOptions<TParentData, TName>): {
|
15
|
+
api: FieldApi<TParentData, TName>;
|
16
|
+
state: Readonly<Ref<FieldApi<TParentData, TName, TData>['state']>>;
|
17
17
|
};
|
18
18
|
type FieldValue<TParentData, TName> = TParentData extends any[] ? unknown extends TName ? TParentData[number] : DeepValue<TParentData[number], TName> : DeepValue<TParentData, TName>;
|
19
|
-
type FieldComponentProps<
|
19
|
+
type FieldComponentProps<TParentData, TName extends DeepKeys<TParentData>> = (TParentData extends any[] ? {
|
20
20
|
name?: TName;
|
21
21
|
index: number;
|
22
22
|
} : {
|
23
23
|
name: TName;
|
24
24
|
index?: never;
|
25
|
-
}) & Omit<UseFieldOptions<
|
26
|
-
type FieldComponent<TParentData> = <
|
25
|
+
}) & Omit<UseFieldOptions<TParentData, TName>, 'name' | 'index'>;
|
26
|
+
type FieldComponent<TParentData> = <TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>>(fieldOptions: FieldComponentProps<TParentData, TName>, context: SetupContext<{}, SlotsType<{
|
27
27
|
default: {
|
28
|
-
field: FieldApi<
|
29
|
-
state: FieldApi<
|
28
|
+
field: FieldApi<TParentData, TName, TData>;
|
29
|
+
state: FieldApi<TParentData, TName, TData>['state'];
|
30
30
|
};
|
31
31
|
}>>) => any;
|
32
|
-
declare const Field: <
|
32
|
+
declare const Field: <TParentData, TName extends DeepKeys<TParentData>>(props: _tanstack_form_core.FieldOptions<TParentData, TName, DeepValue<TParentData, TName>> & {
|
33
33
|
mode?: "value" | "array" | undefined;
|
34
34
|
} & ({
|
35
35
|
[x: `on${Capitalize<string>}`]: ((...args: never) => any) | undefined;
|
@@ -1,35 +1,35 @@
|
|
1
1
|
import * as _tanstack_form_core from '@tanstack/form-core';
|
2
|
-
import { DeepKeys,
|
2
|
+
import { DeepKeys, DeepValue, FieldApi, Narrow } from '@tanstack/form-core';
|
3
3
|
import { SetupContext, SlotsType, Ref } from 'vue-demi';
|
4
4
|
import { UseFieldOptions } from './types.js';
|
5
5
|
|
6
6
|
declare module '@tanstack/form-core' {
|
7
|
-
interface FieldApi<
|
8
|
-
Field: FieldComponent<
|
7
|
+
interface FieldApi<TParentData, TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>> {
|
8
|
+
Field: FieldComponent<TData>;
|
9
9
|
}
|
10
10
|
}
|
11
11
|
type UseField<TParentData> = <TName extends DeepKeys<TParentData>>(opts?: {
|
12
12
|
name: Narrow<TName>;
|
13
|
-
} & UseFieldOptions<
|
14
|
-
declare function useField<
|
15
|
-
api: FieldApi<
|
16
|
-
state: Readonly<Ref<FieldApi<
|
13
|
+
} & UseFieldOptions<TParentData, TName, DeepValue<TParentData, TName>>) => FieldApi<TParentData, TName, DeepValue<TParentData, TName>>;
|
14
|
+
declare function useField<TParentData, TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>>(opts: UseFieldOptions<TParentData, TName>): {
|
15
|
+
api: FieldApi<TParentData, TName>;
|
16
|
+
state: Readonly<Ref<FieldApi<TParentData, TName, TData>['state']>>;
|
17
17
|
};
|
18
18
|
type FieldValue<TParentData, TName> = TParentData extends any[] ? unknown extends TName ? TParentData[number] : DeepValue<TParentData[number], TName> : DeepValue<TParentData, TName>;
|
19
|
-
type FieldComponentProps<
|
19
|
+
type FieldComponentProps<TParentData, TName extends DeepKeys<TParentData>> = (TParentData extends any[] ? {
|
20
20
|
name?: TName;
|
21
21
|
index: number;
|
22
22
|
} : {
|
23
23
|
name: TName;
|
24
24
|
index?: never;
|
25
|
-
}) & Omit<UseFieldOptions<
|
26
|
-
type FieldComponent<TParentData> = <
|
25
|
+
}) & Omit<UseFieldOptions<TParentData, TName>, 'name' | 'index'>;
|
26
|
+
type FieldComponent<TParentData> = <TName extends DeepKeys<TParentData>, TData = DeepValue<TParentData, TName>>(fieldOptions: FieldComponentProps<TParentData, TName>, context: SetupContext<{}, SlotsType<{
|
27
27
|
default: {
|
28
|
-
field: FieldApi<
|
29
|
-
state: FieldApi<
|
28
|
+
field: FieldApi<TParentData, TName, TData>;
|
29
|
+
state: FieldApi<TParentData, TName, TData>['state'];
|
30
30
|
};
|
31
31
|
}>>) => any;
|
32
|
-
declare const Field: <
|
32
|
+
declare const Field: <TParentData, TName extends DeepKeys<TParentData>>(props: _tanstack_form_core.FieldOptions<TParentData, TName, DeepValue<TParentData, TName>> & {
|
33
33
|
mode?: "value" | "array" | undefined;
|
34
34
|
} & ({
|
35
35
|
[x: `on${Capitalize<string>}`]: ((...args: never) => any) | undefined;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../src/useField.tsx"],"sourcesContent":["import { FieldApi } from '@tanstack/form-core'\nimport type {
|
1
|
+
{"version":3,"sources":["../../src/useField.tsx"],"sourcesContent":["import { FieldApi } from '@tanstack/form-core'\nimport type { DeepKeys, DeepValue, Narrow } from '@tanstack/form-core'\nimport { useStore } from '@tanstack/vue-store'\nimport { defineComponent, onMounted, onUnmounted, watch } from 'vue-demi'\nimport type { SlotsType, SetupContext, Ref } from 'vue-demi'\nimport { provideFormContext, useFormContext } from './formContext'\nimport type { UseFieldOptions } from './types'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FieldApi<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TData = DeepValue<TParentData, TName>,\n > {\n Field: FieldComponent<TData>\n }\n}\n\nexport type UseField<TParentData> = <TName extends DeepKeys<TParentData>>(\n opts?: { name: Narrow<TName> } & UseFieldOptions<\n TParentData,\n TName,\n DeepValue<TParentData, TName>\n >,\n) => FieldApi<TParentData, TName, DeepValue<TParentData, TName>>\n\nexport function useField<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TData = DeepValue<TParentData, TName>,\n>(\n opts: UseFieldOptions<TParentData, TName>,\n): {\n api: FieldApi<\n TParentData,\n TName\n // Omit<typeof opts, 'onMount'> & {\n // form: FormApi<TParentData>\n // }\n >\n state: Readonly<\n Ref<\n FieldApi<\n TParentData,\n TName,\n TData\n // Omit<typeof opts, 'onMount'> & {\n // form: FormApi<TParentData>\n // }\n >['state']\n >\n >\n} {\n // Get the form API either manually or from context\n const { formApi, parentFieldName } = useFormContext()\n\n const fieldApi = (() => {\n const api = new FieldApi({\n ...opts,\n form: formApi,\n name: opts.name,\n } as never)\n\n api.Field = Field as never\n\n return api\n })()\n\n const fieldState = useStore(fieldApi.store, (state) => state)\n\n let cleanup!: () => void\n onMounted(() => {\n cleanup = fieldApi.mount()\n })\n\n onUnmounted(() => {\n cleanup()\n })\n\n watch(\n () => opts,\n () => {\n // Keep options up to date as they are rendered\n fieldApi.update({ ...opts, form: formApi } as never)\n },\n )\n\n return { api: fieldApi, state: fieldState } as never\n}\n\nexport type FieldValue<TParentData, TName> = TParentData extends any[]\n ? unknown extends TName\n ? TParentData[number]\n : DeepValue<TParentData[number], TName>\n : DeepValue<TParentData, TName>\n\ntype FieldComponentProps<\n TParentData,\n TName extends DeepKeys<TParentData>,\n> = (TParentData extends any[]\n ? {\n name?: TName\n index: number\n }\n : {\n name: TName\n index?: never\n }) &\n Omit<UseFieldOptions<TParentData, TName>, 'name' | 'index'>\n\nexport type FieldComponent<TParentData> = <\n TName extends DeepKeys<TParentData>,\n TData = DeepValue<TParentData, TName>,\n>(\n fieldOptions: FieldComponentProps<TParentData, TName>,\n context: SetupContext<\n {},\n SlotsType<{\n default: {\n field: FieldApi<TParentData, TName, TData>\n state: FieldApi<TParentData, TName, TData>['state']\n }\n }>\n >,\n) => any\n\nexport const Field = defineComponent(\n <TParentData, TName extends DeepKeys<TParentData>>(\n fieldOptions: UseFieldOptions<TParentData, TName>,\n context: SetupContext,\n ) => {\n const fieldApi = useField({ ...fieldOptions, ...context.attrs } as any)\n\n provideFormContext({\n formApi: fieldApi.api.form,\n parentFieldName: fieldApi.api.name,\n } as never)\n\n return () =>\n context.slots.default!({\n field: fieldApi.api,\n state: fieldApi.state.value,\n })\n },\n { name: 'Field', inheritAttrs: false },\n)\n"],"mappings":";AAAA,SAAS,gBAAgB;AAEzB,SAAS,gBAAgB;AACzB,SAAS,iBAAiB,WAAW,aAAa,aAAa;AAE/D,SAAS,oBAAoB,sBAAsB;AAsB5C,SAAS,SAKd,MAqBA;AAEA,QAAM,EAAE,SAAS,gBAAgB,IAAI,eAAe;AAEpD,QAAM,YAAY,MAAM;AACtB,UAAM,MAAM,IAAI,SAAS;AAAA,MACvB,GAAG;AAAA,MACH,MAAM;AAAA,MACN,MAAM,KAAK;AAAA,IACb,CAAU;AAEV,QAAI,QAAQ;AAEZ,WAAO;AAAA,EACT,GAAG;AAEH,QAAM,aAAa,SAAS,SAAS,OAAO,CAAC,UAAU,KAAK;AAE5D,MAAI;AACJ,YAAU,MAAM;AACd,cAAU,SAAS,MAAM;AAAA,EAC3B,CAAC;AAED,cAAY,MAAM;AAChB,YAAQ;AAAA,EACV,CAAC;AAED;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAEJ,eAAS,OAAO,EAAE,GAAG,MAAM,MAAM,QAAQ,CAAU;AAAA,IACrD;AAAA,EACF;AAEA,SAAO,EAAE,KAAK,UAAU,OAAO,WAAW;AAC5C;AAsCO,IAAM,QAAQ;AAAA,EACnB,CACE,cACA,YACG;AACH,UAAM,WAAW,SAAS,EAAE,GAAG,cAAc,GAAG,QAAQ,MAAM,CAAQ;AAEtE,uBAAmB;AAAA,MACjB,SAAS,SAAS,IAAI;AAAA,MACtB,iBAAiB,SAAS,IAAI;AAAA,IAChC,CAAU;AAEV,WAAO,MACL,QAAQ,MAAM,QAAS;AAAA,MACrB,OAAO,SAAS;AAAA,MAChB,OAAO,SAAS,MAAM;AAAA,IACxB,CAAC;AAAA,EACL;AAAA,EACA,EAAE,MAAM,SAAS,cAAc,MAAM;AACvC;","names":[]}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@tanstack/vue-form",
|
3
|
-
"version": "0.3.
|
3
|
+
"version": "0.3.7",
|
4
4
|
"description": "Powerful, type-safe forms for Vue.",
|
5
5
|
"author": "tannerlinsley",
|
6
6
|
"license": "MIT",
|
@@ -45,7 +45,7 @@
|
|
45
45
|
"@tanstack/store": "0.1.3",
|
46
46
|
"@tanstack/vue-store": "0.1.3",
|
47
47
|
"vue-demi": "^0.14.6",
|
48
|
-
"@tanstack/form-core": "0.3.
|
48
|
+
"@tanstack/form-core": "0.3.7"
|
49
49
|
},
|
50
50
|
"devDependencies": {
|
51
51
|
"@vue/composition-api": "1.7.2",
|
@@ -30,7 +30,7 @@ describe('useField', () => {
|
|
30
30
|
|
31
31
|
return () => (
|
32
32
|
<form.Field name="firstName" defaultValue="FirstName">
|
33
|
-
{({ field }: { field: FieldApi<
|
33
|
+
{({ field }: { field: FieldApi<Person, 'firstName'> }) => (
|
34
34
|
<input
|
35
35
|
data-testid={'fieldinput'}
|
36
36
|
value={field.state.value}
|
@@ -68,7 +68,7 @@ describe('useField', () => {
|
|
68
68
|
name="firstName"
|
69
69
|
onChange={(value) => (value === 'other' ? error : undefined)}
|
70
70
|
>
|
71
|
-
{({ field }: { field: FieldApi<
|
71
|
+
{({ field }: { field: FieldApi<Person, 'firstName'> }) => (
|
72
72
|
<div>
|
73
73
|
<input
|
74
74
|
data-testid="fieldinput"
|
@@ -111,7 +111,7 @@ describe('useField', () => {
|
|
111
111
|
name="firstName"
|
112
112
|
onChange={(value) => (value === 'other' ? error : undefined)}
|
113
113
|
>
|
114
|
-
{({ field }: { field: FieldApi<
|
114
|
+
{({ field }: { field: FieldApi<Person, 'firstName'> }) => (
|
115
115
|
<div>
|
116
116
|
<input
|
117
117
|
data-testid="fieldinput"
|
@@ -159,7 +159,7 @@ describe('useField', () => {
|
|
159
159
|
return error
|
160
160
|
}}
|
161
161
|
>
|
162
|
-
{({ field }: { field: FieldApi<
|
162
|
+
{({ field }: { field: FieldApi<Person, 'firstName'> }) => (
|
163
163
|
<div>
|
164
164
|
<input
|
165
165
|
data-testid="fieldinput"
|
@@ -211,7 +211,7 @@ describe('useField', () => {
|
|
211
211
|
return error
|
212
212
|
}}
|
213
213
|
>
|
214
|
-
{({ field }: { field: FieldApi<
|
214
|
+
{({ field }: { field: FieldApi<Person, 'firstName'> }) => (
|
215
215
|
<div>
|
216
216
|
<input
|
217
217
|
data-testid="fieldinput"
|
@@ -29,7 +29,7 @@ describe('useForm', () => {
|
|
29
29
|
|
30
30
|
return () => (
|
31
31
|
<form.Field name="firstName" defaultValue="">
|
32
|
-
{({ field }: { field: FieldApi<
|
32
|
+
{({ field }: { field: FieldApi<Person, 'firstName'> }) => (
|
33
33
|
<input
|
34
34
|
data-testid={'fieldinput'}
|
35
35
|
value={field.state.value}
|
@@ -68,8 +68,8 @@ describe('useForm', () => {
|
|
68
68
|
form.provideFormContext()
|
69
69
|
|
70
70
|
return () => (
|
71
|
-
<form.Field name="firstName"
|
72
|
-
{({ field }: { field: FieldApi<
|
71
|
+
<form.Field name="firstName">
|
72
|
+
{({ field }: { field: FieldApi<Person, 'firstName'> }) => (
|
73
73
|
<p>{field.state.value}</p>
|
74
74
|
)}
|
75
75
|
</form.Field>
|
@@ -81,6 +81,37 @@ describe('useForm', () => {
|
|
81
81
|
expect(queryByText('LastName')).not.toBeInTheDocument()
|
82
82
|
})
|
83
83
|
|
84
|
+
it('should use field default value first', async () => {
|
85
|
+
type Person = {
|
86
|
+
firstName: string
|
87
|
+
lastName: string
|
88
|
+
}
|
89
|
+
|
90
|
+
const formFactory = createFormFactory<Person>()
|
91
|
+
|
92
|
+
const Comp = defineComponent(() => {
|
93
|
+
const form = formFactory.useForm({
|
94
|
+
defaultValues: {
|
95
|
+
firstName: 'FirstName',
|
96
|
+
lastName: 'LastName',
|
97
|
+
},
|
98
|
+
})
|
99
|
+
form.provideFormContext()
|
100
|
+
|
101
|
+
return () => (
|
102
|
+
<form.Field name="firstName" defaultValue="otherName">
|
103
|
+
{({ field }: { field: FieldApi<Person, 'firstName'> }) => (
|
104
|
+
<p>{field.state.value}</p>
|
105
|
+
)}
|
106
|
+
</form.Field>
|
107
|
+
)
|
108
|
+
})
|
109
|
+
|
110
|
+
const { findByText, queryByText } = render(Comp)
|
111
|
+
expect(await findByText('otherName')).toBeInTheDocument()
|
112
|
+
expect(queryByText('LastName')).not.toBeInTheDocument()
|
113
|
+
})
|
114
|
+
|
84
115
|
it('should handle submitting properly', async () => {
|
85
116
|
const Comp = defineComponent(() => {
|
86
117
|
const submittedData = ref<{ firstName: string }>()
|
@@ -101,7 +132,7 @@ describe('useForm', () => {
|
|
101
132
|
{({
|
102
133
|
field,
|
103
134
|
}: {
|
104
|
-
field: FieldApi<
|
135
|
+
field: FieldApi<{ firstName: string }, 'firstName'>
|
105
136
|
}) => {
|
106
137
|
return (
|
107
138
|
<input
|
package/src/types.ts
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
import type { FieldOptions, DeepKeys } from '@tanstack/form-core'
|
1
|
+
import type { FieldOptions, DeepKeys, DeepValue } from '@tanstack/form-core'
|
2
2
|
|
3
3
|
export type UseFieldOptions<
|
4
|
-
TData,
|
5
4
|
TParentData,
|
6
5
|
TName extends DeepKeys<TParentData>,
|
7
|
-
|
6
|
+
TData = DeepValue<TParentData, TName>,
|
7
|
+
> = FieldOptions<TParentData, TName, TData> & {
|
8
8
|
mode?: 'value' | 'array'
|
9
9
|
}
|
package/src/useField.tsx
CHANGED
@@ -1,10 +1,5 @@
|
|
1
1
|
import { FieldApi } from '@tanstack/form-core'
|
2
|
-
import type {
|
3
|
-
DeepKeys,
|
4
|
-
DeepValue,
|
5
|
-
Narrow,
|
6
|
-
ResolveData,
|
7
|
-
} from '@tanstack/form-core'
|
2
|
+
import type { DeepKeys, DeepValue, Narrow } from '@tanstack/form-core'
|
8
3
|
import { useStore } from '@tanstack/vue-store'
|
9
4
|
import { defineComponent, onMounted, onUnmounted, watch } from 'vue-demi'
|
10
5
|
import type { SlotsType, SetupContext, Ref } from 'vue-demi'
|
@@ -14,36 +9,30 @@ import type { UseFieldOptions } from './types'
|
|
14
9
|
declare module '@tanstack/form-core' {
|
15
10
|
// eslint-disable-next-line no-shadow
|
16
11
|
interface FieldApi<
|
17
|
-
TData,
|
18
12
|
TParentData,
|
19
13
|
TName extends DeepKeys<TParentData>,
|
20
|
-
|
21
|
-
TData,
|
22
|
-
TParentData,
|
23
|
-
TName
|
24
|
-
>,
|
14
|
+
TData = DeepValue<TParentData, TName>,
|
25
15
|
> {
|
26
|
-
Field: FieldComponent<
|
16
|
+
Field: FieldComponent<TData>
|
27
17
|
}
|
28
18
|
}
|
29
19
|
|
30
20
|
export type UseField<TParentData> = <TName extends DeepKeys<TParentData>>(
|
31
21
|
opts?: { name: Narrow<TName> } & UseFieldOptions<
|
32
|
-
DeepValue<TParentData, TName>,
|
33
22
|
TParentData,
|
34
|
-
TName
|
23
|
+
TName,
|
24
|
+
DeepValue<TParentData, TName>
|
35
25
|
>,
|
36
|
-
) => FieldApi<
|
26
|
+
) => FieldApi<TParentData, TName, DeepValue<TParentData, TName>>
|
37
27
|
|
38
28
|
export function useField<
|
39
|
-
TData,
|
40
29
|
TParentData,
|
41
30
|
TName extends DeepKeys<TParentData>,
|
31
|
+
TData = DeepValue<TParentData, TName>,
|
42
32
|
>(
|
43
|
-
opts: UseFieldOptions<
|
33
|
+
opts: UseFieldOptions<TParentData, TName>,
|
44
34
|
): {
|
45
35
|
api: FieldApi<
|
46
|
-
TData,
|
47
36
|
TParentData,
|
48
37
|
TName
|
49
38
|
// Omit<typeof opts, 'onMount'> & {
|
@@ -53,9 +42,9 @@ export function useField<
|
|
53
42
|
state: Readonly<
|
54
43
|
Ref<
|
55
44
|
FieldApi<
|
56
|
-
TData,
|
57
45
|
TParentData,
|
58
|
-
TName
|
46
|
+
TName,
|
47
|
+
TData
|
59
48
|
// Omit<typeof opts, 'onMount'> & {
|
60
49
|
// form: FormApi<TParentData>
|
61
50
|
// }
|
@@ -107,7 +96,6 @@ export type FieldValue<TParentData, TName> = TParentData extends any[]
|
|
107
96
|
: DeepValue<TParentData, TName>
|
108
97
|
|
109
98
|
type FieldComponentProps<
|
110
|
-
TData,
|
111
99
|
TParentData,
|
112
100
|
TName extends DeepKeys<TParentData>,
|
113
101
|
> = (TParentData extends any[]
|
@@ -119,32 +107,27 @@ type FieldComponentProps<
|
|
119
107
|
name: TName
|
120
108
|
index?: never
|
121
109
|
}) &
|
122
|
-
Omit<UseFieldOptions<
|
110
|
+
Omit<UseFieldOptions<TParentData, TName>, 'name' | 'index'>
|
123
111
|
|
124
112
|
export type FieldComponent<TParentData> = <
|
125
|
-
TData,
|
126
113
|
TName extends DeepKeys<TParentData>,
|
127
|
-
|
128
|
-
TData,
|
129
|
-
TParentData,
|
130
|
-
TName
|
131
|
-
>,
|
114
|
+
TData = DeepValue<TParentData, TName>,
|
132
115
|
>(
|
133
|
-
fieldOptions: FieldComponentProps<
|
116
|
+
fieldOptions: FieldComponentProps<TParentData, TName>,
|
134
117
|
context: SetupContext<
|
135
118
|
{},
|
136
119
|
SlotsType<{
|
137
120
|
default: {
|
138
|
-
field: FieldApi<
|
139
|
-
state: FieldApi<
|
121
|
+
field: FieldApi<TParentData, TName, TData>
|
122
|
+
state: FieldApi<TParentData, TName, TData>['state']
|
140
123
|
}
|
141
124
|
}>
|
142
125
|
>,
|
143
126
|
) => any
|
144
127
|
|
145
128
|
export const Field = defineComponent(
|
146
|
-
<
|
147
|
-
fieldOptions: UseFieldOptions<
|
129
|
+
<TParentData, TName extends DeepKeys<TParentData>>(
|
130
|
+
fieldOptions: UseFieldOptions<TParentData, TName>,
|
148
131
|
context: SetupContext,
|
149
132
|
) => {
|
150
133
|
const fieldApi = useField({ ...fieldOptions, ...context.attrs } as any)
|