@tanstack/react-form 0.10.3 → 0.12.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.d.ts +11 -0
- package/dist/cjs/formContext.d.ts +10 -0
- package/dist/cjs/index.cjs +181 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/index.d.cts +8 -0
- package/dist/cjs/index.d.ts +8 -0
- package/dist/cjs/index.js +181 -0
- package/dist/cjs/tests/createFormFactory.test.d.ts +1 -0
- package/dist/cjs/tests/useField.test-d.d.ts +1 -0
- package/dist/cjs/tests/useField.test.d.ts +1 -0
- package/dist/cjs/tests/useForm.test-d.d.ts +1 -0
- package/dist/cjs/tests/useForm.test.d.ts +1 -0
- package/dist/cjs/tests/utils.d.ts +1 -0
- package/dist/cjs/types.d.ts +4 -0
- package/dist/cjs/useField.d.ts +28 -0
- package/dist/cjs/useForm.d.ts +19 -0
- package/dist/cjs/useIsomorphicEffectOnce.d.ts +5 -0
- package/dist/cjs/useIsomorphicLayoutEffect.d.ts +3 -0
- package/dist/cjs/useTransform.d.ts +5 -0
- package/dist/cjs/validateFormData.d.ts +14 -0
- package/dist/mjs/createFormFactory.d.ts +11 -0
- package/dist/mjs/formContext.d.ts +10 -0
- package/dist/mjs/index.d.mts +8 -0
- package/dist/mjs/index.d.ts +8 -0
- package/dist/mjs/index.js +170 -0
- package/dist/mjs/index.mjs +170 -0
- package/dist/mjs/index.mjs.map +1 -0
- package/dist/mjs/tests/createFormFactory.test.d.ts +1 -0
- package/dist/mjs/tests/useField.test-d.d.ts +1 -0
- package/dist/mjs/tests/useField.test.d.ts +1 -0
- package/dist/mjs/tests/useForm.test-d.d.ts +1 -0
- package/dist/mjs/tests/useForm.test.d.ts +1 -0
- package/dist/mjs/tests/utils.d.ts +1 -0
- package/dist/mjs/types.d.ts +4 -0
- package/dist/mjs/useField.d.ts +28 -0
- package/dist/mjs/useForm.d.ts +19 -0
- package/dist/mjs/useIsomorphicEffectOnce.d.ts +5 -0
- package/dist/mjs/useIsomorphicLayoutEffect.d.ts +3 -0
- package/dist/mjs/useTransform.d.ts +5 -0
- package/dist/mjs/validateFormData.d.ts +14 -0
- package/package.json +21 -24
- package/src/createFormFactory.ts +25 -9
- package/src/formContext.ts +5 -5
- package/src/index.ts +7 -1
- package/src/tests/createFormFactory.test.tsx +1 -1
- package/src/tests/useField.test-d.tsx +12 -8
- package/src/tests/useField.test.tsx +45 -33
- package/src/tests/useForm.test-d.tsx +36 -0
- package/src/tests/useForm.test.tsx +59 -42
- package/src/types.ts +13 -4
- package/src/useField.tsx +82 -40
- package/src/useForm.tsx +20 -11
- package/src/useIsomorphicEffectOnce.ts +38 -0
- package/src/useIsomorphicLayoutEffect.ts +1 -1
- package/src/useTransform.ts +16 -0
- package/src/validateFormData.ts +70 -0
- package/build/legacy/createFormFactory.cjs +0 -42
- package/build/legacy/createFormFactory.cjs.map +0 -1
- package/build/legacy/createFormFactory.d.cts +0 -12
- package/build/legacy/createFormFactory.d.ts +0 -12
- package/build/legacy/createFormFactory.js +0 -17
- package/build/legacy/createFormFactory.js.map +0 -1
- package/build/legacy/formContext.cjs +0 -51
- package/build/legacy/formContext.cjs.map +0 -1
- package/build/legacy/formContext.d.cts +0 -13
- package/build/legacy/formContext.d.ts +0 -13
- package/build/legacy/formContext.js +0 -15
- package/build/legacy/formContext.js.map +0 -1
- package/build/legacy/index.cjs +0 -46
- package/build/legacy/index.cjs.map +0 -1
- package/build/legacy/index.d.cts +0 -7
- package/build/legacy/index.d.ts +0 -7
- package/build/legacy/index.js +0 -15
- package/build/legacy/index.js.map +0 -1
- package/build/legacy/types.cjs +0 -19
- package/build/legacy/types.cjs.map +0 -1
- package/build/legacy/types.d.cts +0 -7
- package/build/legacy/types.d.ts +0 -7
- package/build/legacy/types.js +0 -1
- package/build/legacy/types.js.map +0 -1
- package/build/legacy/useField.cjs +0 -88
- package/build/legacy/useField.cjs.map +0 -1
- package/build/legacy/useField.d.cts +0 -27
- package/build/legacy/useField.d.ts +0 -27
- package/build/legacy/useField.js +0 -52
- package/build/legacy/useField.js.map +0 -1
- package/build/legacy/useForm.cjs +0 -73
- package/build/legacy/useForm.cjs.map +0 -1
- package/build/legacy/useForm.d.cts +0 -23
- package/build/legacy/useForm.d.ts +0 -23
- package/build/legacy/useForm.js +0 -38
- package/build/legacy/useForm.js.map +0 -1
- package/build/legacy/useIsomorphicLayoutEffect.cjs +0 -35
- package/build/legacy/useIsomorphicLayoutEffect.cjs.map +0 -1
- package/build/legacy/useIsomorphicLayoutEffect.d.cts +0 -5
- package/build/legacy/useIsomorphicLayoutEffect.d.ts +0 -5
- package/build/legacy/useIsomorphicLayoutEffect.js +0 -10
- package/build/legacy/useIsomorphicLayoutEffect.js.map +0 -1
- package/build/modern/createFormFactory.cjs +0 -42
- package/build/modern/createFormFactory.cjs.map +0 -1
- package/build/modern/createFormFactory.d.cts +0 -12
- package/build/modern/createFormFactory.d.ts +0 -12
- package/build/modern/createFormFactory.js +0 -17
- package/build/modern/createFormFactory.js.map +0 -1
- package/build/modern/formContext.cjs +0 -51
- package/build/modern/formContext.cjs.map +0 -1
- package/build/modern/formContext.d.cts +0 -13
- package/build/modern/formContext.d.ts +0 -13
- package/build/modern/formContext.js +0 -15
- package/build/modern/formContext.js.map +0 -1
- package/build/modern/index.cjs +0 -46
- package/build/modern/index.cjs.map +0 -1
- package/build/modern/index.d.cts +0 -7
- package/build/modern/index.d.ts +0 -7
- package/build/modern/index.js +0 -15
- package/build/modern/index.js.map +0 -1
- package/build/modern/types.cjs +0 -19
- package/build/modern/types.cjs.map +0 -1
- package/build/modern/types.d.cts +0 -7
- package/build/modern/types.d.ts +0 -7
- package/build/modern/types.js +0 -1
- package/build/modern/types.js.map +0 -1
- package/build/modern/useField.cjs +0 -88
- package/build/modern/useField.cjs.map +0 -1
- package/build/modern/useField.d.cts +0 -27
- package/build/modern/useField.d.ts +0 -27
- package/build/modern/useField.js +0 -52
- package/build/modern/useField.js.map +0 -1
- package/build/modern/useForm.cjs +0 -73
- package/build/modern/useForm.cjs.map +0 -1
- package/build/modern/useForm.d.cts +0 -23
- package/build/modern/useForm.d.ts +0 -23
- package/build/modern/useForm.js +0 -38
- package/build/modern/useForm.js.map +0 -1
- package/build/modern/useIsomorphicLayoutEffect.cjs +0 -35
- package/build/modern/useIsomorphicLayoutEffect.cjs.map +0 -1
- package/build/modern/useIsomorphicLayoutEffect.d.cts +0 -5
- package/build/modern/useIsomorphicLayoutEffect.d.ts +0 -5
- package/build/modern/useIsomorphicLayoutEffect.js +0 -10
- package/build/modern/useIsomorphicLayoutEffect.js.map +0 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { FormApi, FormOptions, Validator } from '@tanstack/form-core';
|
|
2
|
+
import { type UseField, type FieldComponent } from './useField';
|
|
3
|
+
import { type ValidateFormData } from './validateFormData';
|
|
4
|
+
export type FormFactory<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = {
|
|
5
|
+
useForm: (opts?: FormOptions<TFormData, TFormValidator>) => FormApi<TFormData, TFormValidator>;
|
|
6
|
+
useField: UseField<TFormData>;
|
|
7
|
+
Field: FieldComponent<TFormData, TFormValidator>;
|
|
8
|
+
validateFormData: ValidateFormData<TFormData, TFormValidator>;
|
|
9
|
+
initialFormState: Partial<FormApi<TFormData, TFormValidator>['state']>;
|
|
10
|
+
};
|
|
11
|
+
export declare function createFormFactory<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(defaultOpts?: FormOptions<TFormData, TFormValidator>): FormFactory<TFormData, TFormValidator>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { FormApi, Validator } from '@tanstack/form-core';
|
|
3
|
+
export declare const formContext: import("react").Context<{
|
|
4
|
+
formApi: FormApi<any, Validator<any, unknown> | undefined>;
|
|
5
|
+
parentFieldName?: string | undefined;
|
|
6
|
+
} | null>;
|
|
7
|
+
export declare function useFormContext(): {
|
|
8
|
+
formApi: FormApi<any, Validator<any, unknown> | undefined>;
|
|
9
|
+
parentFieldName?: string | undefined;
|
|
10
|
+
};
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const formCore = require("@tanstack/form-core");
|
|
4
|
+
const reactStore = require("@tanstack/react-store");
|
|
5
|
+
const React = require("rehackt");
|
|
6
|
+
const decodeFormdata = require("decode-formdata");
|
|
7
|
+
const formContext = React.createContext(null);
|
|
8
|
+
function useFormContext() {
|
|
9
|
+
const formApi = React.useContext(formContext);
|
|
10
|
+
if (!formApi) {
|
|
11
|
+
throw new Error(`You are trying to use the form API outside of a form!`);
|
|
12
|
+
}
|
|
13
|
+
return formApi;
|
|
14
|
+
}
|
|
15
|
+
const useIsomorphicLayoutEffect = (
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect
|
|
18
|
+
);
|
|
19
|
+
const useIsomorphicEffectOnce = (effect) => {
|
|
20
|
+
const destroyFunc = React.useRef();
|
|
21
|
+
const effectCalled = React.useRef(false);
|
|
22
|
+
const renderAfterCalled = React.useRef(false);
|
|
23
|
+
const [val, setVal] = React.useState(0);
|
|
24
|
+
if (effectCalled.current) {
|
|
25
|
+
renderAfterCalled.current = true;
|
|
26
|
+
}
|
|
27
|
+
useIsomorphicLayoutEffect(() => {
|
|
28
|
+
if (!effectCalled.current) {
|
|
29
|
+
destroyFunc.current = effect();
|
|
30
|
+
effectCalled.current = true;
|
|
31
|
+
}
|
|
32
|
+
setVal((v) => v + 1);
|
|
33
|
+
return () => {
|
|
34
|
+
if (!renderAfterCalled.current) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (destroyFunc.current) {
|
|
38
|
+
destroyFunc.current();
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}, []);
|
|
42
|
+
};
|
|
43
|
+
function useField(opts) {
|
|
44
|
+
const { formApi, parentFieldName } = useFormContext();
|
|
45
|
+
const [fieldApi] = React.useState(() => {
|
|
46
|
+
const name = (typeof opts.index === "number" ? [parentFieldName, opts.index, opts.name] : [parentFieldName, opts.name]).filter((d) => d !== void 0).join(".");
|
|
47
|
+
const api = new formCore.FieldApi({
|
|
48
|
+
...opts,
|
|
49
|
+
form: formApi,
|
|
50
|
+
// TODO: Fix typings to include `index` and `parentFieldName`, if present
|
|
51
|
+
name
|
|
52
|
+
});
|
|
53
|
+
api.Field = Field;
|
|
54
|
+
return api;
|
|
55
|
+
});
|
|
56
|
+
useIsomorphicLayoutEffect(() => {
|
|
57
|
+
fieldApi.update({ ...opts, form: formApi });
|
|
58
|
+
});
|
|
59
|
+
reactStore.useStore(
|
|
60
|
+
fieldApi.store,
|
|
61
|
+
opts.mode === "array" ? (state) => {
|
|
62
|
+
return [state.meta, Object.keys(state.value).length];
|
|
63
|
+
} : void 0
|
|
64
|
+
);
|
|
65
|
+
const unmountFn = React.useRef(null);
|
|
66
|
+
useIsomorphicEffectOnce(() => {
|
|
67
|
+
return () => {
|
|
68
|
+
var _a;
|
|
69
|
+
(_a = unmountFn.current) == null ? void 0 : _a.call(unmountFn);
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
if (!unmountFn.current) {
|
|
73
|
+
unmountFn.current = fieldApi.mount();
|
|
74
|
+
}
|
|
75
|
+
return fieldApi;
|
|
76
|
+
}
|
|
77
|
+
function Field({
|
|
78
|
+
children,
|
|
79
|
+
...fieldOptions
|
|
80
|
+
}) {
|
|
81
|
+
const fieldApi = useField(fieldOptions);
|
|
82
|
+
return /* @__PURE__ */ React.createElement(
|
|
83
|
+
formContext.Provider,
|
|
84
|
+
{
|
|
85
|
+
value: {
|
|
86
|
+
formApi: fieldApi.form,
|
|
87
|
+
parentFieldName: fieldApi.name
|
|
88
|
+
},
|
|
89
|
+
children: formCore.functionalUpdate(children, fieldApi)
|
|
90
|
+
}
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
function useForm(opts) {
|
|
94
|
+
const [formApi] = React.useState(() => {
|
|
95
|
+
const api = new formCore.FormApi(opts);
|
|
96
|
+
api.Provider = function Provider(props) {
|
|
97
|
+
useIsomorphicLayoutEffect(api.mount, []);
|
|
98
|
+
return /* @__PURE__ */ React.createElement(formContext.Provider, { ...props, value: { formApi: api } });
|
|
99
|
+
};
|
|
100
|
+
api.Field = Field;
|
|
101
|
+
api.useField = useField;
|
|
102
|
+
api.useStore = (selector) => {
|
|
103
|
+
return reactStore.useStore(api.store, selector);
|
|
104
|
+
};
|
|
105
|
+
api.Subscribe = (props) => {
|
|
106
|
+
return formCore.functionalUpdate(
|
|
107
|
+
props.children,
|
|
108
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
109
|
+
reactStore.useStore(api.store, props.selector)
|
|
110
|
+
);
|
|
111
|
+
};
|
|
112
|
+
return api;
|
|
113
|
+
});
|
|
114
|
+
formApi.useStore((state) => state.isSubmitting);
|
|
115
|
+
useIsomorphicLayoutEffect(() => {
|
|
116
|
+
formApi.update(opts);
|
|
117
|
+
});
|
|
118
|
+
return formApi;
|
|
119
|
+
}
|
|
120
|
+
const getValidateFormData = (defaultOpts) => async (formData, info) => {
|
|
121
|
+
const { validatorAdapter, onServerValidate } = defaultOpts || {};
|
|
122
|
+
const runValidator = (propsValue) => {
|
|
123
|
+
if (validatorAdapter && typeof onServerValidate !== "function") {
|
|
124
|
+
return validatorAdapter().validate(propsValue, onServerValidate);
|
|
125
|
+
}
|
|
126
|
+
return onServerValidate(propsValue);
|
|
127
|
+
};
|
|
128
|
+
const data = decodeFormdata.decode(formData, info);
|
|
129
|
+
const onServerError = runValidator({ value: data });
|
|
130
|
+
return {
|
|
131
|
+
errorMap: {
|
|
132
|
+
onServer: onServerError
|
|
133
|
+
},
|
|
134
|
+
errors: onServerError ? [onServerError] : []
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
function createFormFactory(defaultOpts) {
|
|
138
|
+
return {
|
|
139
|
+
useForm: (opts) => {
|
|
140
|
+
const formOptions = Object.assign({}, defaultOpts, opts);
|
|
141
|
+
return useForm(formOptions);
|
|
142
|
+
},
|
|
143
|
+
useField,
|
|
144
|
+
Field,
|
|
145
|
+
validateFormData: getValidateFormData(defaultOpts),
|
|
146
|
+
initialFormState: {
|
|
147
|
+
errorMap: {
|
|
148
|
+
onServer: void 0
|
|
149
|
+
},
|
|
150
|
+
errors: []
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function useTransform(fn, deps) {
|
|
155
|
+
return {
|
|
156
|
+
fn,
|
|
157
|
+
deps
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
Object.defineProperty(exports, "FieldApi", {
|
|
161
|
+
enumerable: true,
|
|
162
|
+
get: () => formCore.FieldApi
|
|
163
|
+
});
|
|
164
|
+
Object.defineProperty(exports, "FormApi", {
|
|
165
|
+
enumerable: true,
|
|
166
|
+
get: () => formCore.FormApi
|
|
167
|
+
});
|
|
168
|
+
Object.defineProperty(exports, "functionalUpdate", {
|
|
169
|
+
enumerable: true,
|
|
170
|
+
get: () => formCore.functionalUpdate
|
|
171
|
+
});
|
|
172
|
+
Object.defineProperty(exports, "mergeForm", {
|
|
173
|
+
enumerable: true,
|
|
174
|
+
get: () => formCore.mergeForm
|
|
175
|
+
});
|
|
176
|
+
exports.Field = Field;
|
|
177
|
+
exports.createFormFactory = createFormFactory;
|
|
178
|
+
exports.useField = useField;
|
|
179
|
+
exports.useForm = useForm;
|
|
180
|
+
exports.useTransform = useTransform;
|
|
181
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/formContext.ts","../../src/useIsomorphicLayoutEffect.ts","../../src/useIsomorphicEffectOnce.ts","../../src/useField.tsx","../../src/useForm.tsx","../../src/validateFormData.ts","../../src/createFormFactory.ts","../../src/useTransform.ts"],"sourcesContent":["import type { FormApi, Validator } from '@tanstack/form-core'\nimport { createContext, useContext } from 'rehackt'\n\nexport const formContext = createContext<{\n formApi: FormApi<any, Validator<any, unknown> | undefined>\n parentFieldName?: string\n} | null>(null!)\n\nexport function useFormContext() {\n const formApi = useContext(formContext)\n\n if (!formApi) {\n throw new Error(`You are trying to use the form API outside of a form!`)\n }\n\n return formApi\n}\n","import { useEffect, useLayoutEffect } from 'rehackt'\n\nexport const useIsomorphicLayoutEffect =\n // @ts-ignore\n typeof window !== 'undefined' ? useLayoutEffect : useEffect\n","import { useRef, useState, type EffectCallback } from 'rehackt'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\n\n/**\n * This hook handles StrictMode and prod mode\n */\nexport const useIsomorphicEffectOnce = (effect: EffectCallback) => {\n const destroyFunc = useRef<void | (() => void)>()\n const effectCalled = useRef(false)\n const renderAfterCalled = useRef(false)\n const [val, setVal] = useState(0)\n\n if (effectCalled.current) {\n renderAfterCalled.current = true\n }\n\n useIsomorphicLayoutEffect(() => {\n // only execute the effect first time around\n if (!effectCalled.current) {\n destroyFunc.current = effect()\n effectCalled.current = true\n }\n\n // this forces one render after the effect is run\n setVal((v) => v + 1)\n\n return () => {\n // if the comp didn't render since the useEffect was called,\n // we know it's the dummy React cycle\n if (!renderAfterCalled.current) {\n return\n }\n if (destroyFunc.current) {\n destroyFunc.current()\n }\n }\n }, [])\n}\n","import React, { useRef, useState } from 'rehackt'\nimport { useStore } from '@tanstack/react-store'\nimport type {\n DeepKeys,\n DeepValue,\n Narrow,\n Validator,\n} from '@tanstack/form-core'\nimport { FieldApi, functionalUpdate } from '@tanstack/form-core'\nimport { useFormContext, formContext } from './formContext'\nimport type { UseFieldOptions } from './types'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\nimport { useIsomorphicEffectOnce } from './useIsomorphicEffectOnce'\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<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?: { name: Narrow<TName> } & UseFieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator\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 // Get the form API either manually or from context\n const { formApi, parentFieldName } = useFormContext()\n\n const [fieldApi] = useState(() => {\n const name = (\n typeof opts.index === 'number'\n ? [parentFieldName, opts.index, opts.name]\n : [parentFieldName, opts.name]\n )\n .filter((d) => d !== undefined)\n .join('.')\n\n const api = new FieldApi({\n ...opts,\n form: formApi as never,\n // TODO: Fix typings to include `index` and `parentFieldName`, if present\n name: name as typeof opts.name as never,\n })\n\n api.Field = Field as never\n\n return api\n })\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, form: formApi } as never)\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 const unmountFn = useRef<(() => void) | null>(null)\n\n useIsomorphicEffectOnce(() => {\n return () => {\n unmountFn.current?.()\n }\n })\n\n // We have to mount it right as soon as it renders, otherwise we get:\n // https://github.com/TanStack/form/issues/523\n if (!unmountFn.current) {\n unmountFn.current = fieldApi.mount()\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} & (TParentData extends any[]\n ? {\n name?: TName\n index: number\n }\n : {\n name: TName\n index?: never\n }) &\n Omit<\n UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,\n 'name' | 'index'\n >\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}: FieldComponentProps<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\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 (\n <formContext.Provider\n value={{\n formApi: fieldApi.form as never,\n parentFieldName: fieldApi.name,\n }}\n children={functionalUpdate(children, fieldApi as any)}\n />\n )\n}\n","import type { FormState, FormOptions, Validator } from '@tanstack/form-core'\nimport { FormApi, functionalUpdate } from '@tanstack/form-core'\nimport type { NoInfer } from '@tanstack/react-store'\nimport { useStore } from '@tanstack/react-store'\nimport React, {\n type PropsWithChildren,\n type ReactNode,\n useState,\n} from 'rehackt'\nimport { type UseField, type FieldComponent, Field, useField } from './useField'\nimport { formContext } from './formContext'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FormApi<TFormData, TFormValidator> {\n Provider: (props: PropsWithChildren) => JSX.Element\n Field: FieldComponent<TFormData, TFormValidator>\n useField: UseField<TFormData>\n useStore: <TSelected = NoInfer<FormState<TFormData>>>(\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,\n ) => TSelected\n Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {\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 // @ts-ignore\n const api = new FormApi<TFormData, TFormValidator>(opts)\n\n api.Provider = function Provider(props) {\n useIsomorphicLayoutEffect(api.mount, [])\n return (\n <formContext.Provider {...props} value={{ formApi: api as never }} />\n )\n }\n api.Field = Field as any\n api.useField = useField as any\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 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","import { decode } from 'decode-formdata'\nimport type {\n FormApi,\n FormOptions,\n ValidationError,\n Validator,\n} from '@tanstack/form-core'\n\ntype OnServerValidateFn<TFormData> = (props: {\n value: TFormData\n}) => ValidationError\n\ntype OnServerValidateOrFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = TFormValidator extends Validator<TFormData, infer FFN>\n ? FFN | OnServerValidateFn<TFormData>\n : OnServerValidateFn<TFormData>\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FormOptions<\n TFormData,\n TFormValidator extends\n | Validator<TFormData, unknown>\n | undefined = undefined,\n > {\n onServerValidate?: OnServerValidateOrFn<TFormData, TFormValidator>\n }\n}\n\nexport type ValidateFormData<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = (\n formData: FormData,\n info?: Parameters<typeof decode>[1],\n) => Promise<Partial<FormApi<TFormData, TFormValidator>['state']>>\n\nexport const getValidateFormData = <\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(\n defaultOpts?: FormOptions<TFormData, TFormValidator>,\n) =>\n (async (\n formData: FormData,\n info?: Parameters<typeof decode>[1],\n ): Promise<Partial<FormApi<TFormData, TFormValidator>['state']>> => {\n const { validatorAdapter, onServerValidate } = defaultOpts || {}\n\n const runValidator = (propsValue: { value: TFormData }) => {\n if (validatorAdapter && typeof onServerValidate !== 'function') {\n return validatorAdapter().validate(propsValue, onServerValidate)\n }\n\n return (onServerValidate as OnServerValidateFn<TFormData>)(propsValue)\n }\n\n const data = decode(formData, info) as never as TFormData\n\n const onServerError = runValidator({ value: data })\n\n return {\n errorMap: {\n onServer: onServerError,\n },\n errors: onServerError ? [onServerError] : [],\n }\n }) as ValidateFormData<TFormData, TFormValidator>\n","import type { FormApi, FormOptions, Validator } from '@tanstack/form-core'\n\nimport { type UseField, type FieldComponent, Field, useField } from './useField'\nimport { useForm } from './useForm'\nimport { type ValidateFormData, getValidateFormData } from './validateFormData'\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: UseField<TFormData>\n Field: FieldComponent<TFormData, TFormValidator>\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 as any,\n Field: Field as any,\n validateFormData: getValidateFormData(defaultOpts) as never,\n initialFormState: {\n errorMap: {\n onServer: undefined,\n },\n errors: [],\n },\n }\n}\n","import type { FormApi, Validator } from '@tanstack/form-core'\n\nexport function useTransform<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(\n fn: (\n formBase: FormApi<TFormData, TFormValidator>,\n ) => FormApi<TFormData, TFormValidator>,\n deps: unknown[],\n) {\n return {\n fn,\n deps,\n }\n}\n"],"names":["createContext","useContext","useLayoutEffect","useEffect","useRef","useState","FieldApi","useStore","functionalUpdate","FormApi","decode"],"mappings":";;;;;;AAGa,MAAA,cAAcA,MAAAA,cAGjB,IAAK;AAER,SAAS,iBAAiB;AACzB,QAAA,UAAUC,iBAAW,WAAW;AAEtC,MAAI,CAAC,SAAS;AACN,UAAA,IAAI,MAAM,uDAAuD;AAAA,EACzE;AAEO,SAAA;AACT;ACda,MAAA;AAAA;AAAA,EAEX,OAAO,WAAW,cAAcC,MAAAA,kBAAkBC,MAAA;AAAA;ACEvC,MAAA,0BAA0B,CAAC,WAA2B;AACjE,QAAM,cAAcC,MAAAA;AACd,QAAA,eAAeA,aAAO,KAAK;AAC3B,QAAA,oBAAoBA,aAAO,KAAK;AACtC,QAAM,CAAC,KAAK,MAAM,IAAIC,eAAS,CAAC;AAEhC,MAAI,aAAa,SAAS;AACxB,sBAAkB,UAAU;AAAA,EAC9B;AAEA,4BAA0B,MAAM;AAE1B,QAAA,CAAC,aAAa,SAAS;AACzB,kBAAY,UAAU;AACtB,mBAAa,UAAU;AAAA,IACzB;AAGO,WAAA,CAAC,MAAM,IAAI,CAAC;AAEnB,WAAO,MAAM;AAGP,UAAA,CAAC,kBAAkB,SAAS;AAC9B;AAAA,MACF;AACA,UAAI,YAAY,SAAS;AACvB,oBAAY,QAAQ;AAAA,MACtB;AAAA,IAAA;AAAA,EAEJ,GAAG,CAAE,CAAA;AACP;ACiBO,SAAS,SAUd,MAC+D;AAE/D,QAAM,EAAE,SAAS,gBAAgB,IAAI,eAAe;AAEpD,QAAM,CAAC,QAAQ,IAAIA,MAAAA,SAAS,MAAM;AAC1B,UAAA,QACJ,OAAO,KAAK,UAAU,WAClB,CAAC,iBAAiB,KAAK,OAAO,KAAK,IAAI,IACvC,CAAC,iBAAiB,KAAK,IAAI,GAE9B,OAAO,CAAC,MAAM,MAAM,MAAS,EAC7B,KAAK,GAAG;AAEL,UAAA,MAAM,IAAIC,kBAAS;AAAA,MACvB,GAAG;AAAA,MACH,MAAM;AAAA;AAAA,MAEN;AAAA,IAAA,CACD;AAED,QAAI,QAAQ;AAEL,WAAA;AAAA,EAAA,CACR;AAMD,4BAA0B,MAAM;AAC9B,aAAS,OAAO,EAAE,GAAG,MAAM,MAAM,SAAkB;AAAA,EAAA,CACpD;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;AAEA,QAAA,YAAYH,aAA4B,IAAI;AAElD,0BAAwB,MAAM;AAC5B,WAAO,MAAM;;AACX,sBAAU,YAAV;AAAA,IAAoB;AAAA,EACtB,CACD;AAIG,MAAA,CAAC,UAAU,SAAS;AACZ,cAAA,UAAU,SAAS;EAC/B;AAEO,SAAA;AACT;AA0DO,SAAS,MASd;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAI0E;AAClE,QAAA,WAAW,SAAS,YAAmB;AAG3C,SAAA,sBAAA;AAAA,IAAC,YAAY;AAAA,IAAZ;AAAA,MACC,OAAO;AAAA,QACL,SAAS,SAAS;AAAA,QAClB,iBAAiB,SAAS;AAAA,MAC5B;AAAA,MACA,UAAUI,SAAAA,iBAAiB,UAAU,QAAe;AAAA,IAAA;AAAA,EAAA;AAG1D;AClLO,SAAS,QAId,MACoC;AACpC,QAAM,CAAC,OAAO,IAAIH,MAAAA,SAAS,MAAM;AAEzB,UAAA,MAAM,IAAII,iBAAmC,IAAI;AAEnD,QAAA,WAAW,SAAS,SAAS,OAAO;AACZ,gCAAA,IAAI,OAAO,CAAA,CAAE;AAErC,aAAA,sBAAA,cAAC,YAAY,UAAZ,EAAsB,GAAG,OAAO,OAAO,EAAE,SAAS,IAAA,EAAgB,CAAA;AAAA,IAAA;AAGvE,QAAI,QAAQ;AACZ,QAAI,WAAW;AACX,QAAA,WAAW,CAEb,aACG;AAEI,aAAAF,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;AAED,UAAQ,SAAS,CAAC,UAAU,MAAM,YAAY;AAM9C,4BAA0B,MAAM;AAC9B,YAAQ,OAAO,IAAI;AAAA,EAAA,CACpB;AAEM,SAAA;AACT;ACxCO,MAAM,sBAAsB,CAIjC,gBAEC,OACC,UACA,SACkE;AAClE,QAAM,EAAE,kBAAkB,qBAAqB,eAAe,CAAA;AAExD,QAAA,eAAe,CAAC,eAAqC;AACrD,QAAA,oBAAoB,OAAO,qBAAqB,YAAY;AAC9D,aAAO,iBAAiB,EAAE,SAAS,YAAY,gBAAgB;AAAA,IACjE;AAEA,WAAQ,iBAAmD,UAAU;AAAA,EAAA;AAGjE,QAAA,OAAOG,eAAAA,OAAO,UAAU,IAAI;AAElC,QAAM,gBAAgB,aAAa,EAAE,OAAO,KAAM,CAAA;AAE3C,SAAA;AAAA,IACL,UAAU;AAAA,MACR,UAAU;AAAA,IACZ;AAAA,IACA,QAAQ,gBAAgB,CAAC,aAAa,IAAI,CAAC;AAAA,EAAA;AAE/C;AClDK,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;ACtCgB,SAAA,aAId,IAGA,MACA;AACO,SAAA;AAAA,IACL;AAAA,IACA;AAAA,EAAA;AAEJ;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type { DeepKeys, DeepValue, FieldApiOptions, FieldInfo, FieldMeta, FieldOptions, FieldState, FormOptions, FormState, RequiredByKey, Updater, UpdaterFn, ValidationCause, ValidationError, ValidationMeta, } from '@tanstack/form-core';
|
|
2
|
+
export { FormApi, FieldApi, functionalUpdate, mergeForm, } from '@tanstack/form-core';
|
|
3
|
+
export { useForm } from './useForm';
|
|
4
|
+
export type { UseField, FieldComponent } from './useField';
|
|
5
|
+
export { useField, Field } from './useField';
|
|
6
|
+
export type { FormFactory } from './createFormFactory';
|
|
7
|
+
export { createFormFactory } from './createFormFactory';
|
|
8
|
+
export { useTransform } from './useTransform';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type { DeepKeys, DeepValue, FieldApiOptions, FieldInfo, FieldMeta, FieldOptions, FieldState, FormOptions, FormState, RequiredByKey, Updater, UpdaterFn, ValidationCause, ValidationError, ValidationMeta, } from '@tanstack/form-core';
|
|
2
|
+
export { FormApi, FieldApi, functionalUpdate, mergeForm, } from '@tanstack/form-core';
|
|
3
|
+
export { useForm } from './useForm';
|
|
4
|
+
export type { UseField, FieldComponent } from './useField';
|
|
5
|
+
export { useField, Field } from './useField';
|
|
6
|
+
export type { FormFactory } from './createFormFactory';
|
|
7
|
+
export { createFormFactory } from './createFormFactory';
|
|
8
|
+
export { useTransform } from './useTransform';
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const formCore = require("@tanstack/form-core");
|
|
4
|
+
const reactStore = require("@tanstack/react-store");
|
|
5
|
+
const React = require("rehackt");
|
|
6
|
+
const decodeFormdata = require("decode-formdata");
|
|
7
|
+
const formContext = React.createContext(null);
|
|
8
|
+
function useFormContext() {
|
|
9
|
+
const formApi = React.useContext(formContext);
|
|
10
|
+
if (!formApi) {
|
|
11
|
+
throw new Error(`You are trying to use the form API outside of a form!`);
|
|
12
|
+
}
|
|
13
|
+
return formApi;
|
|
14
|
+
}
|
|
15
|
+
const useIsomorphicLayoutEffect = (
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect
|
|
18
|
+
);
|
|
19
|
+
const useIsomorphicEffectOnce = (effect) => {
|
|
20
|
+
const destroyFunc = React.useRef();
|
|
21
|
+
const effectCalled = React.useRef(false);
|
|
22
|
+
const renderAfterCalled = React.useRef(false);
|
|
23
|
+
const [val, setVal] = React.useState(0);
|
|
24
|
+
if (effectCalled.current) {
|
|
25
|
+
renderAfterCalled.current = true;
|
|
26
|
+
}
|
|
27
|
+
useIsomorphicLayoutEffect(() => {
|
|
28
|
+
if (!effectCalled.current) {
|
|
29
|
+
destroyFunc.current = effect();
|
|
30
|
+
effectCalled.current = true;
|
|
31
|
+
}
|
|
32
|
+
setVal((v) => v + 1);
|
|
33
|
+
return () => {
|
|
34
|
+
if (!renderAfterCalled.current) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (destroyFunc.current) {
|
|
38
|
+
destroyFunc.current();
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}, []);
|
|
42
|
+
};
|
|
43
|
+
function useField(opts) {
|
|
44
|
+
const { formApi, parentFieldName } = useFormContext();
|
|
45
|
+
const [fieldApi] = React.useState(() => {
|
|
46
|
+
const name = (typeof opts.index === "number" ? [parentFieldName, opts.index, opts.name] : [parentFieldName, opts.name]).filter((d) => d !== void 0).join(".");
|
|
47
|
+
const api = new formCore.FieldApi({
|
|
48
|
+
...opts,
|
|
49
|
+
form: formApi,
|
|
50
|
+
// TODO: Fix typings to include `index` and `parentFieldName`, if present
|
|
51
|
+
name
|
|
52
|
+
});
|
|
53
|
+
api.Field = Field;
|
|
54
|
+
return api;
|
|
55
|
+
});
|
|
56
|
+
useIsomorphicLayoutEffect(() => {
|
|
57
|
+
fieldApi.update({ ...opts, form: formApi });
|
|
58
|
+
});
|
|
59
|
+
reactStore.useStore(
|
|
60
|
+
fieldApi.store,
|
|
61
|
+
opts.mode === "array" ? (state) => {
|
|
62
|
+
return [state.meta, Object.keys(state.value).length];
|
|
63
|
+
} : void 0
|
|
64
|
+
);
|
|
65
|
+
const unmountFn = React.useRef(null);
|
|
66
|
+
useIsomorphicEffectOnce(() => {
|
|
67
|
+
return () => {
|
|
68
|
+
var _a;
|
|
69
|
+
(_a = unmountFn.current) == null ? void 0 : _a.call(unmountFn);
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
if (!unmountFn.current) {
|
|
73
|
+
unmountFn.current = fieldApi.mount();
|
|
74
|
+
}
|
|
75
|
+
return fieldApi;
|
|
76
|
+
}
|
|
77
|
+
function Field({
|
|
78
|
+
children,
|
|
79
|
+
...fieldOptions
|
|
80
|
+
}) {
|
|
81
|
+
const fieldApi = useField(fieldOptions);
|
|
82
|
+
return /* @__PURE__ */ React.createElement(
|
|
83
|
+
formContext.Provider,
|
|
84
|
+
{
|
|
85
|
+
value: {
|
|
86
|
+
formApi: fieldApi.form,
|
|
87
|
+
parentFieldName: fieldApi.name
|
|
88
|
+
},
|
|
89
|
+
children: formCore.functionalUpdate(children, fieldApi)
|
|
90
|
+
}
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
function useForm(opts) {
|
|
94
|
+
const [formApi] = React.useState(() => {
|
|
95
|
+
const api = new formCore.FormApi(opts);
|
|
96
|
+
api.Provider = function Provider(props) {
|
|
97
|
+
useIsomorphicLayoutEffect(api.mount, []);
|
|
98
|
+
return /* @__PURE__ */ React.createElement(formContext.Provider, { ...props, value: { formApi: api } });
|
|
99
|
+
};
|
|
100
|
+
api.Field = Field;
|
|
101
|
+
api.useField = useField;
|
|
102
|
+
api.useStore = (selector) => {
|
|
103
|
+
return reactStore.useStore(api.store, selector);
|
|
104
|
+
};
|
|
105
|
+
api.Subscribe = (props) => {
|
|
106
|
+
return formCore.functionalUpdate(
|
|
107
|
+
props.children,
|
|
108
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
109
|
+
reactStore.useStore(api.store, props.selector)
|
|
110
|
+
);
|
|
111
|
+
};
|
|
112
|
+
return api;
|
|
113
|
+
});
|
|
114
|
+
formApi.useStore((state) => state.isSubmitting);
|
|
115
|
+
useIsomorphicLayoutEffect(() => {
|
|
116
|
+
formApi.update(opts);
|
|
117
|
+
});
|
|
118
|
+
return formApi;
|
|
119
|
+
}
|
|
120
|
+
const getValidateFormData = (defaultOpts) => async (formData, info) => {
|
|
121
|
+
const { validatorAdapter, onServerValidate } = defaultOpts || {};
|
|
122
|
+
const runValidator = (propsValue) => {
|
|
123
|
+
if (validatorAdapter && typeof onServerValidate !== "function") {
|
|
124
|
+
return validatorAdapter().validate(propsValue, onServerValidate);
|
|
125
|
+
}
|
|
126
|
+
return onServerValidate(propsValue);
|
|
127
|
+
};
|
|
128
|
+
const data = decodeFormdata.decode(formData, info);
|
|
129
|
+
const onServerError = runValidator({ value: data });
|
|
130
|
+
return {
|
|
131
|
+
errorMap: {
|
|
132
|
+
onServer: onServerError
|
|
133
|
+
},
|
|
134
|
+
errors: onServerError ? [onServerError] : []
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
function createFormFactory(defaultOpts) {
|
|
138
|
+
return {
|
|
139
|
+
useForm: (opts) => {
|
|
140
|
+
const formOptions = Object.assign({}, defaultOpts, opts);
|
|
141
|
+
return useForm(formOptions);
|
|
142
|
+
},
|
|
143
|
+
useField,
|
|
144
|
+
Field,
|
|
145
|
+
validateFormData: getValidateFormData(defaultOpts),
|
|
146
|
+
initialFormState: {
|
|
147
|
+
errorMap: {
|
|
148
|
+
onServer: void 0
|
|
149
|
+
},
|
|
150
|
+
errors: []
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function useTransform(fn, deps) {
|
|
155
|
+
return {
|
|
156
|
+
fn,
|
|
157
|
+
deps
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
Object.defineProperty(exports, "FieldApi", {
|
|
161
|
+
enumerable: true,
|
|
162
|
+
get: () => formCore.FieldApi
|
|
163
|
+
});
|
|
164
|
+
Object.defineProperty(exports, "FormApi", {
|
|
165
|
+
enumerable: true,
|
|
166
|
+
get: () => formCore.FormApi
|
|
167
|
+
});
|
|
168
|
+
Object.defineProperty(exports, "functionalUpdate", {
|
|
169
|
+
enumerable: true,
|
|
170
|
+
get: () => formCore.functionalUpdate
|
|
171
|
+
});
|
|
172
|
+
Object.defineProperty(exports, "mergeForm", {
|
|
173
|
+
enumerable: true,
|
|
174
|
+
get: () => formCore.mergeForm
|
|
175
|
+
});
|
|
176
|
+
exports.Field = Field;
|
|
177
|
+
exports.createFormFactory = createFormFactory;
|
|
178
|
+
exports.useField = useField;
|
|
179
|
+
exports.useForm = useForm;
|
|
180
|
+
exports.useTransform = useTransform;
|
|
181
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function sleep(timeout: number): Promise<void>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { FieldOptions, DeepKeys, DeepValue, 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>> = FieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData> & {
|
|
3
|
+
mode?: 'value' | 'array';
|
|
4
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import React from 'rehackt';
|
|
3
|
+
import type { DeepKeys, DeepValue, Narrow, Validator } from '@tanstack/form-core';
|
|
4
|
+
import { FieldApi } from '@tanstack/form-core';
|
|
5
|
+
import type { UseFieldOptions } from './types';
|
|
6
|
+
declare module '@tanstack/form-core' {
|
|
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
|
+
Field: FieldComponent<TParentData, TFormValidator>;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export type UseField<TParentData> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>(opts?: {
|
|
12
|
+
name: Narrow<TName>;
|
|
13
|
+
} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>) => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, DeepValue<TParentData, TName>>;
|
|
14
|
+
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
|
+
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
|
+
children: (fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>) => any;
|
|
17
|
+
} & (TParentData extends any[] ? {
|
|
18
|
+
name?: TName;
|
|
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;
|
|
25
|
+
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
|
+
children: (fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator>) => any;
|
|
27
|
+
} & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>): React.JSX.Element;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { FormState, FormOptions, Validator } from '@tanstack/form-core';
|
|
3
|
+
import { FormApi } from '@tanstack/form-core';
|
|
4
|
+
import type { NoInfer } from '@tanstack/react-store';
|
|
5
|
+
import { type PropsWithChildren, type ReactNode } from 'rehackt';
|
|
6
|
+
import { type UseField, type FieldComponent } from './useField';
|
|
7
|
+
declare module '@tanstack/form-core' {
|
|
8
|
+
interface FormApi<TFormData, TFormValidator> {
|
|
9
|
+
Provider: (props: PropsWithChildren) => JSX.Element;
|
|
10
|
+
Field: FieldComponent<TFormData, TFormValidator>;
|
|
11
|
+
useField: UseField<TFormData>;
|
|
12
|
+
useStore: <TSelected = NoInfer<FormState<TFormData>>>(selector?: (state: NoInfer<FormState<TFormData>>) => TSelected) => TSelected;
|
|
13
|
+
Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
|
|
14
|
+
selector?: (state: NoInfer<FormState<TFormData>>) => TSelected;
|
|
15
|
+
children: ((state: NoInfer<TSelected>) => ReactNode) | ReactNode;
|
|
16
|
+
}) => JSX.Element;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export declare function useForm<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(opts?: FormOptions<TFormData, TFormValidator>): FormApi<TFormData, TFormValidator>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { FormApi, Validator } from '@tanstack/form-core';
|
|
2
|
+
export declare function useTransform<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(fn: (formBase: FormApi<TFormData, TFormValidator>) => FormApi<TFormData, TFormValidator>, deps: unknown[]): {
|
|
3
|
+
fn: (formBase: FormApi<TFormData, TFormValidator>) => FormApi<TFormData, TFormValidator>;
|
|
4
|
+
deps: unknown[];
|
|
5
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { decode } from 'decode-formdata';
|
|
2
|
+
import type { FormApi, FormOptions, ValidationError, Validator } from '@tanstack/form-core';
|
|
3
|
+
type OnServerValidateFn<TFormData> = (props: {
|
|
4
|
+
value: TFormData;
|
|
5
|
+
}) => ValidationError;
|
|
6
|
+
type OnServerValidateOrFn<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = TFormValidator extends Validator<TFormData, infer FFN> ? FFN | OnServerValidateFn<TFormData> : OnServerValidateFn<TFormData>;
|
|
7
|
+
declare module '@tanstack/form-core' {
|
|
8
|
+
interface FormOptions<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> {
|
|
9
|
+
onServerValidate?: OnServerValidateOrFn<TFormData, TFormValidator>;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export type ValidateFormData<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = (formData: FormData, info?: Parameters<typeof decode>[1]) => Promise<Partial<FormApi<TFormData, TFormValidator>['state']>>;
|
|
13
|
+
export declare const getValidateFormData: <TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(defaultOpts?: FormOptions<TFormData, TFormValidator> | undefined) => ValidateFormData<TFormData, TFormValidator>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { FormApi, FormOptions, Validator } from '@tanstack/form-core';
|
|
2
|
+
import { type UseField, type FieldComponent } from './useField';
|
|
3
|
+
import { type ValidateFormData } from './validateFormData';
|
|
4
|
+
export type FormFactory<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = {
|
|
5
|
+
useForm: (opts?: FormOptions<TFormData, TFormValidator>) => FormApi<TFormData, TFormValidator>;
|
|
6
|
+
useField: UseField<TFormData>;
|
|
7
|
+
Field: FieldComponent<TFormData, TFormValidator>;
|
|
8
|
+
validateFormData: ValidateFormData<TFormData, TFormValidator>;
|
|
9
|
+
initialFormState: Partial<FormApi<TFormData, TFormValidator>['state']>;
|
|
10
|
+
};
|
|
11
|
+
export declare function createFormFactory<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(defaultOpts?: FormOptions<TFormData, TFormValidator>): FormFactory<TFormData, TFormValidator>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { FormApi, Validator } from '@tanstack/form-core';
|
|
3
|
+
export declare const formContext: import("react").Context<{
|
|
4
|
+
formApi: FormApi<any, Validator<any, unknown> | undefined>;
|
|
5
|
+
parentFieldName?: string | undefined;
|
|
6
|
+
} | null>;
|
|
7
|
+
export declare function useFormContext(): {
|
|
8
|
+
formApi: FormApi<any, Validator<any, unknown> | undefined>;
|
|
9
|
+
parentFieldName?: string | undefined;
|
|
10
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type { DeepKeys, DeepValue, FieldApiOptions, FieldInfo, FieldMeta, FieldOptions, FieldState, FormOptions, FormState, RequiredByKey, Updater, UpdaterFn, ValidationCause, ValidationError, ValidationMeta, } from '@tanstack/form-core';
|
|
2
|
+
export { FormApi, FieldApi, functionalUpdate, mergeForm, } from '@tanstack/form-core';
|
|
3
|
+
export { useForm } from './useForm';
|
|
4
|
+
export type { UseField, FieldComponent } from './useField';
|
|
5
|
+
export { useField, Field } from './useField';
|
|
6
|
+
export type { FormFactory } from './createFormFactory';
|
|
7
|
+
export { createFormFactory } from './createFormFactory';
|
|
8
|
+
export { useTransform } from './useTransform';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type { DeepKeys, DeepValue, FieldApiOptions, FieldInfo, FieldMeta, FieldOptions, FieldState, FormOptions, FormState, RequiredByKey, Updater, UpdaterFn, ValidationCause, ValidationError, ValidationMeta, } from '@tanstack/form-core';
|
|
2
|
+
export { FormApi, FieldApi, functionalUpdate, mergeForm, } from '@tanstack/form-core';
|
|
3
|
+
export { useForm } from './useForm';
|
|
4
|
+
export type { UseField, FieldComponent } from './useField';
|
|
5
|
+
export { useField, Field } from './useField';
|
|
6
|
+
export type { FormFactory } from './createFormFactory';
|
|
7
|
+
export { createFormFactory } from './createFormFactory';
|
|
8
|
+
export { useTransform } from './useTransform';
|