@tanstack/react-form 0.13.7 → 0.16.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/cjs/createFormFactory.cjs.map +1 -1
- package/dist/cjs/createFormFactory.d.cts +3 -3
- package/dist/cjs/types.d.cts +2 -2
- package/dist/cjs/useField.cjs +4 -17
- package/dist/cjs/useField.cjs.map +1 -1
- package/dist/cjs/useField.d.cts +4 -12
- package/dist/cjs/useForm.cjs +4 -6
- package/dist/cjs/useForm.cjs.map +1 -1
- package/dist/cjs/useForm.d.cts +3 -4
- package/dist/esm/createFormFactory.d.ts +3 -3
- package/dist/esm/createFormFactory.js.map +1 -1
- package/dist/esm/types.d.ts +2 -2
- package/dist/esm/useField.d.ts +4 -12
- package/dist/esm/useField.js +5 -18
- package/dist/esm/useField.js.map +1 -1
- package/dist/esm/useForm.d.ts +3 -4
- package/dist/esm/useForm.js +4 -6
- package/dist/esm/useForm.js.map +1 -1
- package/package.json +2 -2
- package/src/createFormFactory.ts +4 -4
- package/src/tests/createFormFactory.test.tsx +4 -5
- package/src/tests/useField.test-d.tsx +5 -5
- package/src/tests/useField.test.tsx +160 -86
- package/src/tests/useForm.test-d.tsx +1 -1
- package/src/tests/useForm.test.tsx +24 -25
- package/src/types.ts +8 -2
- package/src/useField.tsx +23 -53
- package/src/useForm.tsx +8 -13
- package/dist/cjs/formContext.cjs +0 -14
- package/dist/cjs/formContext.cjs.map +0 -1
- package/dist/cjs/formContext.d.cts +0 -10
- package/dist/esm/formContext.d.ts +0 -10
- package/dist/esm/formContext.js +0 -14
- package/dist/esm/formContext.js.map +0 -1
- package/src/formContext.ts +0 -17
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createFormFactory.cjs","sources":["../../src/createFormFactory.ts"],"sourcesContent":["import { Field, useField } from './useField'\nimport { useForm } from './useForm'\nimport { getValidateFormData } from './validateFormData'\nimport type { ValidateFormData } from './validateFormData'\nimport type { FieldComponent, UseField } from './useField'\nimport type { FormApi, FormOptions, Validator } from '@tanstack/form-core'\n\nexport type FormFactory<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = {\n useForm: (\n opts?: FormOptions<TFormData, TFormValidator>,\n ) => FormApi<TFormData, TFormValidator>\n useField:
|
|
1
|
+
{"version":3,"file":"createFormFactory.cjs","sources":["../../src/createFormFactory.ts"],"sourcesContent":["import { Field, useField } from './useField'\nimport { useForm } from './useForm'\nimport { getValidateFormData } from './validateFormData'\nimport type { ValidateFormData } from './validateFormData'\nimport type { FieldComponent, UseField } from './useField'\nimport type { FormApi, FormOptions, Validator } from '@tanstack/form-core'\n\nexport type FormFactory<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = {\n useForm: (\n opts?: FormOptions<TFormData, TFormValidator>,\n ) => FormApi<TFormData, TFormValidator>\n useField: typeof useField\n Field: typeof Field\n validateFormData: ValidateFormData<TFormData, TFormValidator>\n initialFormState: Partial<FormApi<TFormData, TFormValidator>['state']>\n}\n\nexport function createFormFactory<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(\n defaultOpts?: FormOptions<TFormData, TFormValidator>,\n): FormFactory<TFormData, TFormValidator> {\n return {\n useForm: (opts) => {\n const formOptions = Object.assign({}, defaultOpts, opts)\n return useForm<TFormData, TFormValidator>(formOptions)\n },\n useField: useField,\n Field: Field,\n validateFormData: getValidateFormData(defaultOpts) as never,\n initialFormState: {\n errorMap: {\n onServer: undefined,\n },\n errors: [],\n },\n }\n}\n"],"names":["useForm","useField","Field","getValidateFormData"],"mappings":";;;;;AAoBO,SAAS,kBAId,aACwC;AACjC,SAAA;AAAA,IACL,SAAS,CAAC,SAAS;AACjB,YAAM,cAAc,OAAO,OAAO,CAAA,GAAI,aAAa,IAAI;AACvD,aAAOA,QAAAA,QAAmC,WAAW;AAAA,IACvD;AAAA,IAAA,UACAC,SAAA;AAAA,IAAA,OACAC,SAAA;AAAA,IACA,kBAAkBC,qCAAoB,WAAW;AAAA,IACjD,kBAAkB;AAAA,MAChB,UAAU;AAAA,QACR,UAAU;AAAA,MACZ;AAAA,MACA,QAAQ,CAAC;AAAA,IACX;AAAA,EAAA;AAEJ;;"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { Field, useField } from './useField.cjs';
|
|
1
2
|
import type { ValidateFormData } from './validateFormData.cjs';
|
|
2
|
-
import type { FieldComponent, UseField } from './useField.cjs';
|
|
3
3
|
import type { FormApi, FormOptions, Validator } from '@tanstack/form-core';
|
|
4
4
|
export type FormFactory<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = {
|
|
5
5
|
useForm: (opts?: FormOptions<TFormData, TFormValidator>) => FormApi<TFormData, TFormValidator>;
|
|
6
|
-
useField:
|
|
7
|
-
Field:
|
|
6
|
+
useField: typeof useField;
|
|
7
|
+
Field: typeof Field;
|
|
8
8
|
validateFormData: ValidateFormData<TFormData, TFormValidator>;
|
|
9
9
|
initialFormState: Partial<FormApi<TFormData, TFormValidator>['state']>;
|
|
10
10
|
};
|
package/dist/cjs/types.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DeepKeys, DeepValue,
|
|
2
|
-
export type UseFieldOptions<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> =
|
|
1
|
+
import type { DeepKeys, DeepValue, FieldApiOptions, Validator } from '@tanstack/form-core';
|
|
2
|
+
export type UseFieldOptions<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FieldApiOptions<TParentData, TName, TFieldValidator, TFormValidator, TData> & {
|
|
3
3
|
mode?: 'value' | 'array';
|
|
4
4
|
};
|
package/dist/cjs/useField.cjs
CHANGED
|
@@ -4,24 +4,20 @@ const jsxRuntime = require("react/jsx-runtime");
|
|
|
4
4
|
const rehackt = require("rehackt");
|
|
5
5
|
const reactStore = require("@tanstack/react-store");
|
|
6
6
|
const formCore = require("@tanstack/form-core");
|
|
7
|
-
const formContext = require("./formContext.cjs");
|
|
8
7
|
const useIsomorphicLayoutEffect = require("./useIsomorphicLayoutEffect.cjs");
|
|
9
8
|
function useField(opts) {
|
|
10
|
-
const { formApi, parentFieldName } = formContext.useFormContext();
|
|
11
9
|
const [fieldApi] = rehackt.useState(() => {
|
|
12
|
-
const name = (typeof opts.index === "number" ? [parentFieldName, opts.index, opts.name] : [parentFieldName, opts.name]).filter((d) => d !== void 0).join(".");
|
|
13
10
|
const api = new formCore.FieldApi({
|
|
14
11
|
...opts,
|
|
15
|
-
form:
|
|
16
|
-
|
|
17
|
-
name
|
|
12
|
+
form: opts.form,
|
|
13
|
+
name: opts.name
|
|
18
14
|
});
|
|
19
15
|
api.Field = Field;
|
|
20
16
|
return api;
|
|
21
17
|
});
|
|
22
18
|
useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(fieldApi.mount, [fieldApi]);
|
|
23
19
|
useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(() => {
|
|
24
|
-
fieldApi.update(
|
|
20
|
+
fieldApi.update(opts);
|
|
25
21
|
});
|
|
26
22
|
reactStore.useStore(
|
|
27
23
|
fieldApi.store,
|
|
@@ -36,16 +32,7 @@ function Field({
|
|
|
36
32
|
...fieldOptions
|
|
37
33
|
}) {
|
|
38
34
|
const fieldApi = useField(fieldOptions);
|
|
39
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
40
|
-
formContext.formContext.Provider,
|
|
41
|
-
{
|
|
42
|
-
value: {
|
|
43
|
-
formApi: fieldApi.form,
|
|
44
|
-
parentFieldName: fieldApi.name
|
|
45
|
-
},
|
|
46
|
-
children: formCore.functionalUpdate(children, fieldApi)
|
|
47
|
-
}
|
|
48
|
-
);
|
|
35
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: formCore.functionalUpdate(children, fieldApi) });
|
|
49
36
|
}
|
|
50
37
|
exports.Field = Field;
|
|
51
38
|
exports.useField = useField;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useField.cjs","sources":["../../src/useField.tsx"],"sourcesContent":["import React, { useState } from 'rehackt'\nimport { useStore } from '@tanstack/react-store'\nimport { FieldApi, functionalUpdate } from '@tanstack/form-core'\nimport {
|
|
1
|
+
{"version":3,"file":"useField.cjs","sources":["../../src/useField.tsx"],"sourcesContent":["import React, { useState } from 'rehackt'\nimport { useStore } from '@tanstack/react-store'\nimport { FieldApi, functionalUpdate } from '@tanstack/form-core'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\nimport type { UseFieldOptions } from './types'\nimport type {\n DeepKeys,\n DeepValue,\n Narrow,\n Validator,\n} from '@tanstack/form-core'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FieldApi<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n > {\n Field: FieldComponent<TParentData, TFormValidator>\n }\n}\n\nexport type UseField<\n TParentData,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n> = <\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n>(\n opts: Omit<\n UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,\n 'form'\n >,\n) => FieldApi<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n DeepValue<TParentData, TName>\n>\n\nexport function useField<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n>(\n opts: UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,\n): FieldApi<TParentData, TName, TFieldValidator, TFormValidator> {\n const [fieldApi] = useState(() => {\n const api = new FieldApi({\n ...opts,\n form: opts.form,\n name: opts.name,\n })\n\n api.Field = Field as never\n\n return api\n })\n\n useIsomorphicLayoutEffect(fieldApi.mount, [fieldApi])\n\n /**\n * fieldApi.update should not have any side effects. Think of it like a `useRef`\n * that we need to keep updated every render with the most up-to-date information.\n */\n useIsomorphicLayoutEffect(() => {\n fieldApi.update(opts)\n })\n\n useStore(\n fieldApi.store,\n opts.mode === 'array'\n ? (state) => {\n return [state.meta, Object.keys(state.value).length]\n }\n : undefined,\n )\n\n return fieldApi as never\n}\n\ntype FieldComponentProps<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = {\n children: (\n fieldApi: FieldApi<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) => any\n} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>\n\nexport type FieldComponent<\n TParentData,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n> = <\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n>({\n children,\n ...fieldOptions\n}: Omit<\n FieldComponentProps<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n 'form'\n>) => any\n\nexport function Field<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n>({\n children,\n ...fieldOptions\n}: {\n children: (\n fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator>,\n ) => any\n} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>) {\n const fieldApi = useField(fieldOptions as any)\n\n return <>{functionalUpdate(children, fieldApi as any)}</>\n}\n"],"names":["useState","FieldApi","useIsomorphicLayoutEffect","useStore","jsx","Fragment","functionalUpdate"],"mappings":";;;;;;;AAoDO,SAAS,SAUd,MAC+D;AAC/D,QAAM,CAAC,QAAQ,IAAIA,QAAAA,SAAS,MAAM;AAC1B,UAAA,MAAM,IAAIC,kBAAS;AAAA,MACvB,GAAG;AAAA,MACH,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,IAAA,CACZ;AAED,QAAI,QAAQ;AAEL,WAAA;AAAA,EAAA,CACR;AAEDC,4BAAAA,0BAA0B,SAAS,OAAO,CAAC,QAAQ,CAAC;AAMpDA,4BAAAA,0BAA0B,MAAM;AAC9B,aAAS,OAAO,IAAI;AAAA,EAAA,CACrB;AAEDC,aAAA;AAAA,IACE,SAAS;AAAA,IACT,KAAK,SAAS,UACV,CAAC,UAAU;AACF,aAAA,CAAC,MAAM,MAAM,OAAO,KAAK,MAAM,KAAK,EAAE,MAAM;AAAA,IAErD,IAAA;AAAA,EAAA;AAGC,SAAA;AACT;AAiDO,SAAS,MASd;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAI0E;AAClE,QAAA,WAAW,SAAS,YAAmB;AAE7C,SAAUC,2BAAA,IAAAC,WAAA,UAAA,EAAA,UAAAC,SAAA,iBAAiB,UAAU,QAAe,EAAE,CAAA;AACxD;;;"}
|
package/dist/cjs/useField.d.cts
CHANGED
|
@@ -2,26 +2,18 @@
|
|
|
2
2
|
import React from 'rehackt';
|
|
3
3
|
import { FieldApi } from '@tanstack/form-core';
|
|
4
4
|
import type { UseFieldOptions } from './types.cjs';
|
|
5
|
-
import type { DeepKeys, DeepValue,
|
|
5
|
+
import type { DeepKeys, DeepValue, Validator } from '@tanstack/form-core';
|
|
6
6
|
declare module '@tanstack/form-core' {
|
|
7
7
|
interface FieldApi<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> {
|
|
8
8
|
Field: FieldComponent<TParentData, TFormValidator>;
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
|
-
export type UseField<TParentData> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator
|
|
12
|
-
name: Narrow<TName>;
|
|
13
|
-
} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>) => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, DeepValue<TParentData, TName>>;
|
|
11
|
+
export type UseField<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined>(opts: Omit<UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>, 'form'>) => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, DeepValue<TParentData, TName>>;
|
|
14
12
|
export declare function useField<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>(opts: UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>): FieldApi<TParentData, TName, TFieldValidator, TFormValidator>;
|
|
15
13
|
type FieldComponentProps<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = {
|
|
16
14
|
children: (fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>) => any;
|
|
17
|
-
} &
|
|
18
|
-
|
|
19
|
-
index: number;
|
|
20
|
-
} : {
|
|
21
|
-
name: TName;
|
|
22
|
-
index?: never;
|
|
23
|
-
}) & Omit<UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>, 'name' | 'index'>;
|
|
24
|
-
export type FieldComponent<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>>({ children, ...fieldOptions }: FieldComponentProps<TParentData, TName, TFieldValidator, TFormValidator, TData>) => any;
|
|
15
|
+
} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>;
|
|
16
|
+
export type FieldComponent<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>>({ children, ...fieldOptions }: Omit<FieldComponentProps<TParentData, TName, TFieldValidator, TFormValidator, TData>, 'form'>) => any;
|
|
25
17
|
export declare function Field<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>({ children, ...fieldOptions }: {
|
|
26
18
|
children: (fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator>) => any;
|
|
27
19
|
} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>): React.JSX.Element;
|
package/dist/cjs/useForm.cjs
CHANGED
|
@@ -5,17 +5,14 @@ const formCore = require("@tanstack/form-core");
|
|
|
5
5
|
const reactStore = require("@tanstack/react-store");
|
|
6
6
|
const rehackt = require("rehackt");
|
|
7
7
|
const useField = require("./useField.cjs");
|
|
8
|
-
const formContext = require("./formContext.cjs");
|
|
9
8
|
const useIsomorphicLayoutEffect = require("./useIsomorphicLayoutEffect.cjs");
|
|
10
9
|
function useForm(opts) {
|
|
11
10
|
const [formApi] = rehackt.useState(() => {
|
|
12
11
|
const api = new formCore.FormApi(opts);
|
|
13
|
-
api.
|
|
14
|
-
|
|
15
|
-
return /* @__PURE__ */ jsxRuntime.jsx(formContext.formContext.Provider, { ...props, value: { formApi: api } });
|
|
12
|
+
api.Field = function APIField(props) {
|
|
13
|
+
return /* @__PURE__ */ jsxRuntime.jsx(useField.Field, { ...props, form: api });
|
|
16
14
|
};
|
|
17
|
-
api.
|
|
18
|
-
api.useField = useField.useField;
|
|
15
|
+
api.useField = (props) => useField.useField({ ...props, form: api });
|
|
19
16
|
api.useStore = (selector) => {
|
|
20
17
|
return reactStore.useStore(api.store, selector);
|
|
21
18
|
};
|
|
@@ -28,6 +25,7 @@ function useForm(opts) {
|
|
|
28
25
|
};
|
|
29
26
|
return api;
|
|
30
27
|
});
|
|
28
|
+
useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(formApi.mount, []);
|
|
31
29
|
formApi.useStore((state) => state.isSubmitting);
|
|
32
30
|
useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(() => {
|
|
33
31
|
formApi.update(opts);
|
package/dist/cjs/useForm.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useForm.cjs","sources":["../../src/useForm.tsx"],"sourcesContent":["import { FormApi, functionalUpdate } from '@tanstack/form-core'\nimport { useStore } from '@tanstack/react-store'\nimport React, {\n type PropsWithChildren,\n type ReactNode,\n useState,\n} from 'rehackt'\nimport { Field,
|
|
1
|
+
{"version":3,"file":"useForm.cjs","sources":["../../src/useForm.tsx"],"sourcesContent":["import { FormApi, functionalUpdate } from '@tanstack/form-core'\nimport { useStore } from '@tanstack/react-store'\nimport React, {\n type PropsWithChildren,\n type ReactNode,\n useState,\n} from 'rehackt'\nimport { Field, type FieldComponent, type UseField, useField } from './useField'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\nimport type { NoInfer } from '@tanstack/react-store'\nimport type { FormOptions, FormState, Validator } from '@tanstack/form-core'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FormApi<TFormData, TFormValidator> {\n Field: FieldComponent<TFormData, TFormValidator>\n useField: UseField<TFormData, TFormValidator>\n useStore: <TSelected = NoInfer<FormState<TFormData>>>(\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,\n ) => TSelected\n Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {\n /**\n TypeScript versions <=5.0.4 have a bug that prevents\n the type of the `TSelected` generic from being inferred\n from the return type of this method.\n\n In these versions, `TSelected` will fall back to the default\n type (or `unknown` if that's not defined).\n\n @see {@link https://github.com/TanStack/form/pull/606/files#r1506715714 | This discussion on GitHub for the details}\n @see {@link https://github.com/microsoft/TypeScript/issues/52786 | The bug report in `microsoft/TypeScript`}\n */\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected\n children: ((state: NoInfer<TSelected>) => ReactNode) | ReactNode\n }) => JSX.Element\n }\n}\n\nexport function useForm<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(\n opts?: FormOptions<TFormData, TFormValidator>,\n): FormApi<TFormData, TFormValidator> {\n const [formApi] = useState(() => {\n const api = new FormApi<TFormData, TFormValidator>(opts)\n api.Field = function APIField(props) {\n return <Field {...props} form={api} />\n }\n // eslint-disable-next-line react-hooks/rules-of-hooks\n api.useField = (props) => useField({ ...props, form: api })\n api.useStore = (\n // @ts-ignore\n selector,\n ) => {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useStore(api.store as any, selector as any) as any\n }\n api.Subscribe = (\n // @ts-ignore\n props,\n ) => {\n return functionalUpdate(\n props.children,\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useStore(api.store as any, props.selector as any),\n ) as any\n }\n\n return api\n })\n\n useIsomorphicLayoutEffect(formApi.mount, [])\n\n formApi.useStore((state) => state.isSubmitting)\n\n /**\n * formApi.update should not have any side effects. Think of it like a `useRef`\n * that we need to keep updated every render with the most up-to-date information.\n */\n useIsomorphicLayoutEffect(() => {\n formApi.update(opts)\n })\n\n return formApi as any\n}\n"],"names":["useState","FormApi","jsx","Field","useField","useStore","functionalUpdate","useIsomorphicLayoutEffect"],"mappings":";;;;;;;;AAsCO,SAAS,QAId,MACoC;AACpC,QAAM,CAAC,OAAO,IAAIA,QAAAA,SAAS,MAAM;AACzB,UAAA,MAAM,IAAIC,iBAAmC,IAAI;AACnD,QAAA,QAAQ,SAAS,SAAS,OAAO;AACnC,aAAQC,2BAAAA,IAAAC,SAAAA,OAAA,EAAO,GAAG,OAAO,MAAM,IAAK,CAAA;AAAA,IAAA;AAGlC,QAAA,WAAW,CAAC,UAAUC,SAAA,SAAS,EAAE,GAAG,OAAO,MAAM,IAAA,CAAK;AACtD,QAAA,WAAW,CAEb,aACG;AAEI,aAAAC,oBAAS,IAAI,OAAc,QAAe;AAAA,IAAA;AAE/C,QAAA,YAAY,CAEd,UACG;AACI,aAAAC,SAAA;AAAA,QACL,MAAM;AAAA;AAAA,QAEND,WAAAA,SAAS,IAAI,OAAc,MAAM,QAAe;AAAA,MAAA;AAAA,IAClD;AAGK,WAAA;AAAA,EAAA,CACR;AAEyBE,4BAAAA,0BAAA,QAAQ,OAAO,CAAA,CAAE;AAE3C,UAAQ,SAAS,CAAC,UAAU,MAAM,YAAY;AAM9CA,4BAAAA,0BAA0B,MAAM;AAC9B,YAAQ,OAAO,IAAI;AAAA,EAAA,CACpB;AAEM,SAAA;AACT;;"}
|
package/dist/cjs/useForm.d.cts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { FormApi } from '@tanstack/form-core';
|
|
3
|
-
import { type
|
|
3
|
+
import { type ReactNode } from 'rehackt';
|
|
4
|
+
import { type FieldComponent, type UseField } from './useField.cjs';
|
|
4
5
|
import type { NoInfer } from '@tanstack/react-store';
|
|
5
6
|
import type { FormOptions, FormState, Validator } from '@tanstack/form-core';
|
|
6
|
-
import type { FieldComponent, UseField } from './useField.cjs';
|
|
7
7
|
declare module '@tanstack/form-core' {
|
|
8
8
|
interface FormApi<TFormData, TFormValidator> {
|
|
9
|
-
Provider: (props: PropsWithChildren) => JSX.Element;
|
|
10
9
|
Field: FieldComponent<TFormData, TFormValidator>;
|
|
11
|
-
useField: UseField<TFormData>;
|
|
10
|
+
useField: UseField<TFormData, TFormValidator>;
|
|
12
11
|
useStore: <TSelected = NoInfer<FormState<TFormData>>>(selector?: (state: NoInfer<FormState<TFormData>>) => TSelected) => TSelected;
|
|
13
12
|
Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
|
|
14
13
|
/**
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { Field, useField } from './useField.js';
|
|
1
2
|
import type { ValidateFormData } from './validateFormData.js';
|
|
2
|
-
import type { FieldComponent, UseField } from './useField.js';
|
|
3
3
|
import type { FormApi, FormOptions, Validator } from '@tanstack/form-core';
|
|
4
4
|
export type FormFactory<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = {
|
|
5
5
|
useForm: (opts?: FormOptions<TFormData, TFormValidator>) => FormApi<TFormData, TFormValidator>;
|
|
6
|
-
useField:
|
|
7
|
-
Field:
|
|
6
|
+
useField: typeof useField;
|
|
7
|
+
Field: typeof Field;
|
|
8
8
|
validateFormData: ValidateFormData<TFormData, TFormValidator>;
|
|
9
9
|
initialFormState: Partial<FormApi<TFormData, TFormValidator>['state']>;
|
|
10
10
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createFormFactory.js","sources":["../../src/createFormFactory.ts"],"sourcesContent":["import { Field, useField } from './useField'\nimport { useForm } from './useForm'\nimport { getValidateFormData } from './validateFormData'\nimport type { ValidateFormData } from './validateFormData'\nimport type { FieldComponent, UseField } from './useField'\nimport type { FormApi, FormOptions, Validator } from '@tanstack/form-core'\n\nexport type FormFactory<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = {\n useForm: (\n opts?: FormOptions<TFormData, TFormValidator>,\n ) => FormApi<TFormData, TFormValidator>\n useField:
|
|
1
|
+
{"version":3,"file":"createFormFactory.js","sources":["../../src/createFormFactory.ts"],"sourcesContent":["import { Field, useField } from './useField'\nimport { useForm } from './useForm'\nimport { getValidateFormData } from './validateFormData'\nimport type { ValidateFormData } from './validateFormData'\nimport type { FieldComponent, UseField } from './useField'\nimport type { FormApi, FormOptions, Validator } from '@tanstack/form-core'\n\nexport type FormFactory<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = {\n useForm: (\n opts?: FormOptions<TFormData, TFormValidator>,\n ) => FormApi<TFormData, TFormValidator>\n useField: typeof useField\n Field: typeof Field\n validateFormData: ValidateFormData<TFormData, TFormValidator>\n initialFormState: Partial<FormApi<TFormData, TFormValidator>['state']>\n}\n\nexport function createFormFactory<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(\n defaultOpts?: FormOptions<TFormData, TFormValidator>,\n): FormFactory<TFormData, TFormValidator> {\n return {\n useForm: (opts) => {\n const formOptions = Object.assign({}, defaultOpts, opts)\n return useForm<TFormData, TFormValidator>(formOptions)\n },\n useField: useField,\n Field: Field,\n validateFormData: getValidateFormData(defaultOpts) as never,\n initialFormState: {\n errorMap: {\n onServer: undefined,\n },\n errors: [],\n },\n }\n}\n"],"names":[],"mappings":";;;AAoBO,SAAS,kBAId,aACwC;AACjC,SAAA;AAAA,IACL,SAAS,CAAC,SAAS;AACjB,YAAM,cAAc,OAAO,OAAO,CAAA,GAAI,aAAa,IAAI;AACvD,aAAO,QAAmC,WAAW;AAAA,IACvD;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB,oBAAoB,WAAW;AAAA,IACjD,kBAAkB;AAAA,MAChB,UAAU;AAAA,QACR,UAAU;AAAA,MACZ;AAAA,MACA,QAAQ,CAAC;AAAA,IACX;AAAA,EAAA;AAEJ;"}
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DeepKeys, DeepValue,
|
|
2
|
-
export type UseFieldOptions<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> =
|
|
1
|
+
import type { DeepKeys, DeepValue, FieldApiOptions, Validator } from '@tanstack/form-core';
|
|
2
|
+
export type UseFieldOptions<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FieldApiOptions<TParentData, TName, TFieldValidator, TFormValidator, TData> & {
|
|
3
3
|
mode?: 'value' | 'array';
|
|
4
4
|
};
|
package/dist/esm/useField.d.ts
CHANGED
|
@@ -2,26 +2,18 @@
|
|
|
2
2
|
import React from 'rehackt';
|
|
3
3
|
import { FieldApi } from '@tanstack/form-core';
|
|
4
4
|
import type { UseFieldOptions } from './types.js';
|
|
5
|
-
import type { DeepKeys, DeepValue,
|
|
5
|
+
import type { DeepKeys, DeepValue, Validator } from '@tanstack/form-core';
|
|
6
6
|
declare module '@tanstack/form-core' {
|
|
7
7
|
interface FieldApi<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> {
|
|
8
8
|
Field: FieldComponent<TParentData, TFormValidator>;
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
|
-
export type UseField<TParentData> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator
|
|
12
|
-
name: Narrow<TName>;
|
|
13
|
-
} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>) => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, DeepValue<TParentData, TName>>;
|
|
11
|
+
export type UseField<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined>(opts: Omit<UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>, 'form'>) => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, DeepValue<TParentData, TName>>;
|
|
14
12
|
export declare function useField<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>(opts: UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>): FieldApi<TParentData, TName, TFieldValidator, TFormValidator>;
|
|
15
13
|
type FieldComponentProps<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = {
|
|
16
14
|
children: (fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>) => any;
|
|
17
|
-
} &
|
|
18
|
-
|
|
19
|
-
index: number;
|
|
20
|
-
} : {
|
|
21
|
-
name: TName;
|
|
22
|
-
index?: never;
|
|
23
|
-
}) & Omit<UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>, 'name' | 'index'>;
|
|
24
|
-
export type FieldComponent<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>>({ children, ...fieldOptions }: FieldComponentProps<TParentData, TName, TFieldValidator, TFormValidator, TData>) => any;
|
|
15
|
+
} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>;
|
|
16
|
+
export type FieldComponent<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>>({ children, ...fieldOptions }: Omit<FieldComponentProps<TParentData, TName, TFieldValidator, TFormValidator, TData>, 'form'>) => any;
|
|
25
17
|
export declare function Field<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>({ children, ...fieldOptions }: {
|
|
26
18
|
children: (fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator>) => any;
|
|
27
19
|
} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>): React.JSX.Element;
|
package/dist/esm/useField.js
CHANGED
|
@@ -1,25 +1,21 @@
|
|
|
1
|
-
import { jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from "rehackt";
|
|
3
3
|
import { useStore } from "@tanstack/react-store";
|
|
4
4
|
import { FieldApi, functionalUpdate } from "@tanstack/form-core";
|
|
5
|
-
import { useFormContext, formContext } from "./formContext.js";
|
|
6
5
|
import { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect.js";
|
|
7
6
|
function useField(opts) {
|
|
8
|
-
const { formApi, parentFieldName } = useFormContext();
|
|
9
7
|
const [fieldApi] = useState(() => {
|
|
10
|
-
const name = (typeof opts.index === "number" ? [parentFieldName, opts.index, opts.name] : [parentFieldName, opts.name]).filter((d) => d !== void 0).join(".");
|
|
11
8
|
const api = new FieldApi({
|
|
12
9
|
...opts,
|
|
13
|
-
form:
|
|
14
|
-
|
|
15
|
-
name
|
|
10
|
+
form: opts.form,
|
|
11
|
+
name: opts.name
|
|
16
12
|
});
|
|
17
13
|
api.Field = Field;
|
|
18
14
|
return api;
|
|
19
15
|
});
|
|
20
16
|
useIsomorphicLayoutEffect(fieldApi.mount, [fieldApi]);
|
|
21
17
|
useIsomorphicLayoutEffect(() => {
|
|
22
|
-
fieldApi.update(
|
|
18
|
+
fieldApi.update(opts);
|
|
23
19
|
});
|
|
24
20
|
useStore(
|
|
25
21
|
fieldApi.store,
|
|
@@ -34,16 +30,7 @@ function Field({
|
|
|
34
30
|
...fieldOptions
|
|
35
31
|
}) {
|
|
36
32
|
const fieldApi = useField(fieldOptions);
|
|
37
|
-
return /* @__PURE__ */ jsx(
|
|
38
|
-
formContext.Provider,
|
|
39
|
-
{
|
|
40
|
-
value: {
|
|
41
|
-
formApi: fieldApi.form,
|
|
42
|
-
parentFieldName: fieldApi.name
|
|
43
|
-
},
|
|
44
|
-
children: functionalUpdate(children, fieldApi)
|
|
45
|
-
}
|
|
46
|
-
);
|
|
33
|
+
return /* @__PURE__ */ jsx(Fragment, { children: functionalUpdate(children, fieldApi) });
|
|
47
34
|
}
|
|
48
35
|
export {
|
|
49
36
|
Field,
|
package/dist/esm/useField.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useField.js","sources":["../../src/useField.tsx"],"sourcesContent":["import React, { useState } from 'rehackt'\nimport { useStore } from '@tanstack/react-store'\nimport { FieldApi, functionalUpdate } from '@tanstack/form-core'\nimport {
|
|
1
|
+
{"version":3,"file":"useField.js","sources":["../../src/useField.tsx"],"sourcesContent":["import React, { useState } from 'rehackt'\nimport { useStore } from '@tanstack/react-store'\nimport { FieldApi, functionalUpdate } from '@tanstack/form-core'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\nimport type { UseFieldOptions } from './types'\nimport type {\n DeepKeys,\n DeepValue,\n Narrow,\n Validator,\n} from '@tanstack/form-core'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FieldApi<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n > {\n Field: FieldComponent<TParentData, TFormValidator>\n }\n}\n\nexport type UseField<\n TParentData,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n> = <\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n>(\n opts: Omit<\n UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,\n 'form'\n >,\n) => FieldApi<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n DeepValue<TParentData, TName>\n>\n\nexport function useField<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n>(\n opts: UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,\n): FieldApi<TParentData, TName, TFieldValidator, TFormValidator> {\n const [fieldApi] = useState(() => {\n const api = new FieldApi({\n ...opts,\n form: opts.form,\n name: opts.name,\n })\n\n api.Field = Field as never\n\n return api\n })\n\n useIsomorphicLayoutEffect(fieldApi.mount, [fieldApi])\n\n /**\n * fieldApi.update should not have any side effects. Think of it like a `useRef`\n * that we need to keep updated every render with the most up-to-date information.\n */\n useIsomorphicLayoutEffect(() => {\n fieldApi.update(opts)\n })\n\n useStore(\n fieldApi.store,\n opts.mode === 'array'\n ? (state) => {\n return [state.meta, Object.keys(state.value).length]\n }\n : undefined,\n )\n\n return fieldApi as never\n}\n\ntype FieldComponentProps<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = {\n children: (\n fieldApi: FieldApi<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) => any\n} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>\n\nexport type FieldComponent<\n TParentData,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n> = <\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n>({\n children,\n ...fieldOptions\n}: Omit<\n FieldComponentProps<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n 'form'\n>) => any\n\nexport function Field<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n>({\n children,\n ...fieldOptions\n}: {\n children: (\n fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator>,\n ) => any\n} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>) {\n const fieldApi = useField(fieldOptions as any)\n\n return <>{functionalUpdate(children, fieldApi as any)}</>\n}\n"],"names":[],"mappings":";;;;;AAoDO,SAAS,SAUd,MAC+D;AAC/D,QAAM,CAAC,QAAQ,IAAI,SAAS,MAAM;AAC1B,UAAA,MAAM,IAAI,SAAS;AAAA,MACvB,GAAG;AAAA,MACH,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,IAAA,CACZ;AAED,QAAI,QAAQ;AAEL,WAAA;AAAA,EAAA,CACR;AAED,4BAA0B,SAAS,OAAO,CAAC,QAAQ,CAAC;AAMpD,4BAA0B,MAAM;AAC9B,aAAS,OAAO,IAAI;AAAA,EAAA,CACrB;AAED;AAAA,IACE,SAAS;AAAA,IACT,KAAK,SAAS,UACV,CAAC,UAAU;AACF,aAAA,CAAC,MAAM,MAAM,OAAO,KAAK,MAAM,KAAK,EAAE,MAAM;AAAA,IAErD,IAAA;AAAA,EAAA;AAGC,SAAA;AACT;AAiDO,SAAS,MASd;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAI0E;AAClE,QAAA,WAAW,SAAS,YAAmB;AAE7C,SAAU,oBAAA,UAAA,EAAA,UAAA,iBAAiB,UAAU,QAAe,EAAE,CAAA;AACxD;"}
|
package/dist/esm/useForm.d.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { FormApi } from '@tanstack/form-core';
|
|
3
|
-
import { type
|
|
3
|
+
import { type ReactNode } from 'rehackt';
|
|
4
|
+
import { type FieldComponent, type UseField } from './useField.js';
|
|
4
5
|
import type { NoInfer } from '@tanstack/react-store';
|
|
5
6
|
import type { FormOptions, FormState, Validator } from '@tanstack/form-core';
|
|
6
|
-
import type { FieldComponent, UseField } from './useField.js';
|
|
7
7
|
declare module '@tanstack/form-core' {
|
|
8
8
|
interface FormApi<TFormData, TFormValidator> {
|
|
9
|
-
Provider: (props: PropsWithChildren) => JSX.Element;
|
|
10
9
|
Field: FieldComponent<TFormData, TFormValidator>;
|
|
11
|
-
useField: UseField<TFormData>;
|
|
10
|
+
useField: UseField<TFormData, TFormValidator>;
|
|
12
11
|
useStore: <TSelected = NoInfer<FormState<TFormData>>>(selector?: (state: NoInfer<FormState<TFormData>>) => TSelected) => TSelected;
|
|
13
12
|
Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
|
|
14
13
|
/**
|
package/dist/esm/useForm.js
CHANGED
|
@@ -3,17 +3,14 @@ import { FormApi, functionalUpdate } from "@tanstack/form-core";
|
|
|
3
3
|
import { useStore } from "@tanstack/react-store";
|
|
4
4
|
import { useState } from "rehackt";
|
|
5
5
|
import { Field, useField } from "./useField.js";
|
|
6
|
-
import { formContext } from "./formContext.js";
|
|
7
6
|
import { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect.js";
|
|
8
7
|
function useForm(opts) {
|
|
9
8
|
const [formApi] = useState(() => {
|
|
10
9
|
const api = new FormApi(opts);
|
|
11
|
-
api.
|
|
12
|
-
|
|
13
|
-
return /* @__PURE__ */ jsx(formContext.Provider, { ...props, value: { formApi: api } });
|
|
10
|
+
api.Field = function APIField(props) {
|
|
11
|
+
return /* @__PURE__ */ jsx(Field, { ...props, form: api });
|
|
14
12
|
};
|
|
15
|
-
api.
|
|
16
|
-
api.useField = useField;
|
|
13
|
+
api.useField = (props) => useField({ ...props, form: api });
|
|
17
14
|
api.useStore = (selector) => {
|
|
18
15
|
return useStore(api.store, selector);
|
|
19
16
|
};
|
|
@@ -26,6 +23,7 @@ function useForm(opts) {
|
|
|
26
23
|
};
|
|
27
24
|
return api;
|
|
28
25
|
});
|
|
26
|
+
useIsomorphicLayoutEffect(formApi.mount, []);
|
|
29
27
|
formApi.useStore((state) => state.isSubmitting);
|
|
30
28
|
useIsomorphicLayoutEffect(() => {
|
|
31
29
|
formApi.update(opts);
|
package/dist/esm/useForm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useForm.js","sources":["../../src/useForm.tsx"],"sourcesContent":["import { FormApi, functionalUpdate } from '@tanstack/form-core'\nimport { useStore } from '@tanstack/react-store'\nimport React, {\n type PropsWithChildren,\n type ReactNode,\n useState,\n} from 'rehackt'\nimport { Field,
|
|
1
|
+
{"version":3,"file":"useForm.js","sources":["../../src/useForm.tsx"],"sourcesContent":["import { FormApi, functionalUpdate } from '@tanstack/form-core'\nimport { useStore } from '@tanstack/react-store'\nimport React, {\n type PropsWithChildren,\n type ReactNode,\n useState,\n} from 'rehackt'\nimport { Field, type FieldComponent, type UseField, useField } from './useField'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\nimport type { NoInfer } from '@tanstack/react-store'\nimport type { FormOptions, FormState, Validator } from '@tanstack/form-core'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FormApi<TFormData, TFormValidator> {\n Field: FieldComponent<TFormData, TFormValidator>\n useField: UseField<TFormData, TFormValidator>\n useStore: <TSelected = NoInfer<FormState<TFormData>>>(\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,\n ) => TSelected\n Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {\n /**\n TypeScript versions <=5.0.4 have a bug that prevents\n the type of the `TSelected` generic from being inferred\n from the return type of this method.\n\n In these versions, `TSelected` will fall back to the default\n type (or `unknown` if that's not defined).\n\n @see {@link https://github.com/TanStack/form/pull/606/files#r1506715714 | This discussion on GitHub for the details}\n @see {@link https://github.com/microsoft/TypeScript/issues/52786 | The bug report in `microsoft/TypeScript`}\n */\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected\n children: ((state: NoInfer<TSelected>) => ReactNode) | ReactNode\n }) => JSX.Element\n }\n}\n\nexport function useForm<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(\n opts?: FormOptions<TFormData, TFormValidator>,\n): FormApi<TFormData, TFormValidator> {\n const [formApi] = useState(() => {\n const api = new FormApi<TFormData, TFormValidator>(opts)\n api.Field = function APIField(props) {\n return <Field {...props} form={api} />\n }\n // eslint-disable-next-line react-hooks/rules-of-hooks\n api.useField = (props) => useField({ ...props, form: api })\n api.useStore = (\n // @ts-ignore\n selector,\n ) => {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useStore(api.store as any, selector as any) as any\n }\n api.Subscribe = (\n // @ts-ignore\n props,\n ) => {\n return functionalUpdate(\n props.children,\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useStore(api.store as any, props.selector as any),\n ) as any\n }\n\n return api\n })\n\n useIsomorphicLayoutEffect(formApi.mount, [])\n\n formApi.useStore((state) => state.isSubmitting)\n\n /**\n * formApi.update should not have any side effects. Think of it like a `useRef`\n * that we need to keep updated every render with the most up-to-date information.\n */\n useIsomorphicLayoutEffect(() => {\n formApi.update(opts)\n })\n\n return formApi as any\n}\n"],"names":[],"mappings":";;;;;;AAsCO,SAAS,QAId,MACoC;AACpC,QAAM,CAAC,OAAO,IAAI,SAAS,MAAM;AACzB,UAAA,MAAM,IAAI,QAAmC,IAAI;AACnD,QAAA,QAAQ,SAAS,SAAS,OAAO;AACnC,aAAQ,oBAAA,OAAA,EAAO,GAAG,OAAO,MAAM,IAAK,CAAA;AAAA,IAAA;AAGlC,QAAA,WAAW,CAAC,UAAU,SAAS,EAAE,GAAG,OAAO,MAAM,IAAA,CAAK;AACtD,QAAA,WAAW,CAEb,aACG;AAEI,aAAA,SAAS,IAAI,OAAc,QAAe;AAAA,IAAA;AAE/C,QAAA,YAAY,CAEd,UACG;AACI,aAAA;AAAA,QACL,MAAM;AAAA;AAAA,QAEN,SAAS,IAAI,OAAc,MAAM,QAAe;AAAA,MAAA;AAAA,IAClD;AAGK,WAAA;AAAA,EAAA,CACR;AAEyB,4BAAA,QAAQ,OAAO,CAAA,CAAE;AAE3C,UAAQ,SAAS,CAAC,UAAU,MAAM,YAAY;AAM9C,4BAA0B,MAAM;AAC9B,YAAQ,OAAO,IAAI;AAAA,EAAA,CACpB;AAEM,SAAA;AACT;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/react-form",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Powerful, type-safe forms for React.",
|
|
5
5
|
"author": "tannerlinsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"@tanstack/react-store": "^0.3.1",
|
|
44
44
|
"decode-formdata": "^0.4.0",
|
|
45
45
|
"rehackt": "^0.0.3",
|
|
46
|
-
"@tanstack/form-core": "0.
|
|
46
|
+
"@tanstack/form-core": "0.16.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"react": "^17.0.0 || ^18.0.0"
|
package/src/createFormFactory.ts
CHANGED
|
@@ -12,8 +12,8 @@ export type FormFactory<
|
|
|
12
12
|
useForm: (
|
|
13
13
|
opts?: FormOptions<TFormData, TFormValidator>,
|
|
14
14
|
) => FormApi<TFormData, TFormValidator>
|
|
15
|
-
useField:
|
|
16
|
-
Field:
|
|
15
|
+
useField: typeof useField
|
|
16
|
+
Field: typeof Field
|
|
17
17
|
validateFormData: ValidateFormData<TFormData, TFormValidator>
|
|
18
18
|
initialFormState: Partial<FormApi<TFormData, TFormValidator>['state']>
|
|
19
19
|
}
|
|
@@ -29,8 +29,8 @@ export function createFormFactory<
|
|
|
29
29
|
const formOptions = Object.assign({}, defaultOpts, opts)
|
|
30
30
|
return useForm<TFormData, TFormValidator>(formOptions)
|
|
31
31
|
},
|
|
32
|
-
useField: useField
|
|
33
|
-
Field: Field
|
|
32
|
+
useField: useField,
|
|
33
|
+
Field: Field,
|
|
34
34
|
validateFormData: getValidateFormData(defaultOpts) as never,
|
|
35
35
|
initialFormState: {
|
|
36
36
|
errorMap: {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
/// <reference lib="dom" />
|
|
2
|
-
import { render } from '@testing-library/react'
|
|
3
|
-
import '@testing-library/jest-dom'
|
|
4
1
|
import * as React from 'react'
|
|
2
|
+
import { describe, expect, it } from 'vitest'
|
|
3
|
+
import { render } from '@testing-library/react'
|
|
5
4
|
import { createFormFactory } from '../index'
|
|
6
5
|
|
|
7
6
|
describe('createFormFactory', () => {
|
|
@@ -22,14 +21,14 @@ describe('createFormFactory', () => {
|
|
|
22
21
|
const form = formFactory.useForm({})
|
|
23
22
|
|
|
24
23
|
return (
|
|
25
|
-
|
|
24
|
+
<>
|
|
26
25
|
<form.Field
|
|
27
26
|
name="firstName"
|
|
28
27
|
children={(field) => {
|
|
29
28
|
return <p>{field.state.value}</p>
|
|
30
29
|
}}
|
|
31
30
|
/>
|
|
32
|
-
|
|
31
|
+
</>
|
|
33
32
|
)
|
|
34
33
|
}
|
|
35
34
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { assertType } from 'vitest'
|
|
2
1
|
import * as React from 'react'
|
|
2
|
+
import { assertType, it } from 'vitest'
|
|
3
3
|
import { useForm } from '../useForm'
|
|
4
4
|
|
|
5
5
|
it('should type state.value properly', () => {
|
|
@@ -12,7 +12,7 @@ it('should type state.value properly', () => {
|
|
|
12
12
|
} as const)
|
|
13
13
|
|
|
14
14
|
return (
|
|
15
|
-
|
|
15
|
+
<>
|
|
16
16
|
<form.Field
|
|
17
17
|
name="firstName"
|
|
18
18
|
children={(field) => {
|
|
@@ -25,7 +25,7 @@ it('should type state.value properly', () => {
|
|
|
25
25
|
assertType<84>(field.state.value)
|
|
26
26
|
}}
|
|
27
27
|
/>
|
|
28
|
-
|
|
28
|
+
</>
|
|
29
29
|
)
|
|
30
30
|
}
|
|
31
31
|
})
|
|
@@ -40,7 +40,7 @@ it('should type onChange properly', () => {
|
|
|
40
40
|
} as const)
|
|
41
41
|
|
|
42
42
|
return (
|
|
43
|
-
|
|
43
|
+
<>
|
|
44
44
|
<form.Field
|
|
45
45
|
name="firstName"
|
|
46
46
|
validators={{
|
|
@@ -61,7 +61,7 @@ it('should type onChange properly', () => {
|
|
|
61
61
|
}}
|
|
62
62
|
children={() => null}
|
|
63
63
|
/>
|
|
64
|
-
|
|
64
|
+
</>
|
|
65
65
|
)
|
|
66
66
|
}
|
|
67
67
|
})
|