@tanstack/form-core 0.42.1 → 0.43.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/FieldApi.cjs +17 -28
- package/dist/cjs/FieldApi.cjs.map +1 -1
- package/dist/cjs/FieldApi.d.cts +91 -79
- package/dist/cjs/FormApi.cjs +50 -53
- package/dist/cjs/FormApi.cjs.map +1 -1
- package/dist/cjs/FormApi.d.cts +74 -67
- package/dist/cjs/formOptions.cjs.map +1 -1
- package/dist/cjs/formOptions.d.cts +2 -3
- package/dist/cjs/index.cjs +2 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/mergeForm.cjs.map +1 -1
- package/dist/cjs/mergeForm.d.cts +1 -2
- package/dist/cjs/metaHelper.cjs.map +1 -1
- package/dist/cjs/metaHelper.d.cts +2 -3
- package/dist/cjs/standardSchemaValidator.cjs +24 -31
- package/dist/cjs/standardSchemaValidator.cjs.map +1 -1
- package/dist/cjs/standardSchemaValidator.d.cts +24 -4
- package/dist/cjs/types.d.cts +15 -27
- package/dist/cjs/util-types.d.cts +1 -0
- package/dist/cjs/utils.cjs +4 -0
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +4 -3
- package/dist/esm/FieldApi.d.ts +91 -79
- package/dist/esm/FieldApi.js +18 -29
- package/dist/esm/FieldApi.js.map +1 -1
- package/dist/esm/FormApi.d.ts +74 -67
- package/dist/esm/FormApi.js +52 -55
- package/dist/esm/FormApi.js.map +1 -1
- package/dist/esm/formOptions.d.ts +2 -3
- package/dist/esm/formOptions.js.map +1 -1
- package/dist/esm/index.js +4 -3
- package/dist/esm/mergeForm.d.ts +1 -2
- package/dist/esm/mergeForm.js.map +1 -1
- package/dist/esm/metaHelper.d.ts +2 -3
- package/dist/esm/metaHelper.js.map +1 -1
- package/dist/esm/standardSchemaValidator.d.ts +24 -4
- package/dist/esm/standardSchemaValidator.js +24 -31
- package/dist/esm/standardSchemaValidator.js.map +1 -1
- package/dist/esm/types.d.ts +15 -27
- package/dist/esm/util-types.d.ts +1 -0
- package/dist/esm/utils.d.ts +4 -3
- package/dist/esm/utils.js +4 -0
- package/dist/esm/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/FieldApi.ts +803 -273
- package/src/FormApi.ts +613 -183
- package/src/formOptions.ts +26 -4
- package/src/mergeForm.ts +5 -7
- package/src/metaHelper.ts +28 -6
- package/src/standardSchemaValidator.ts +47 -58
- package/src/types.ts +39 -34
- package/src/util-types.ts +2 -0
- package/src/utils.ts +15 -9
package/dist/esm/FormApi.d.ts
CHANGED
|
@@ -1,26 +1,30 @@
|
|
|
1
1
|
import { Derived, Store } from '@tanstack/store';
|
|
2
|
-
import { StandardSchemaV1 } from './standardSchemaValidator.js';
|
|
3
|
-
import {
|
|
4
|
-
import { FormValidationError, FormValidationErrorMap, UpdateMetaOptions, ValidationCause, ValidationError, ValidationErrorMap, ValidationErrorMapKeys
|
|
2
|
+
import { StandardSchemaV1, StandardSchemaV1Issue, TStandardSchemaValidatorValue } from './standardSchemaValidator.js';
|
|
3
|
+
import { AnyFieldMeta, AnyFieldMetaBase, FieldApi } from './FieldApi.js';
|
|
4
|
+
import { FormValidationError, FormValidationErrorMap, UpdateMetaOptions, ValidationCause, ValidationError, ValidationErrorMap, ValidationErrorMapKeys } from './types.js';
|
|
5
5
|
import { DeepKeys, DeepValue } from './util-types.js';
|
|
6
6
|
import { Updater } from './utils.js';
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
/**
|
|
8
|
+
* @private
|
|
9
|
+
*/
|
|
10
|
+
type FormErrorMapFromValidator<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>> = Partial<Record<DeepKeys<TFormData>, ValidationErrorMap<TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync>>>;
|
|
11
|
+
export type FormValidateFn<TFormData> = (props: {
|
|
9
12
|
value: TFormData;
|
|
10
|
-
formApi: FormApi<TFormData,
|
|
11
|
-
}) =>
|
|
13
|
+
formApi: FormApi<TFormData, any, any, any, any, any, any, any, any>;
|
|
14
|
+
}) => unknown;
|
|
12
15
|
/**
|
|
13
16
|
* @private
|
|
14
17
|
*/
|
|
15
|
-
export type FormValidateOrFn<TFormData
|
|
18
|
+
export type FormValidateOrFn<TFormData> = FormValidateFn<TFormData> | StandardSchemaV1<TFormData, unknown>;
|
|
19
|
+
export type UnwrapFormValidateOrFn<TValidateOrFn extends undefined | FormValidateOrFn<any>> = [TValidateOrFn] extends [FormValidateFn<any>] ? ReturnType<TValidateOrFn> : [TValidateOrFn] extends [StandardSchemaV1<any, any>] ? Record<string, StandardSchemaV1Issue[]> : undefined;
|
|
16
20
|
/**
|
|
17
21
|
* @private
|
|
18
22
|
*/
|
|
19
|
-
export type FormValidateAsyncFn<TFormData
|
|
23
|
+
export type FormValidateAsyncFn<TFormData> = (props: {
|
|
20
24
|
value: TFormData;
|
|
21
|
-
formApi: FormApi<TFormData,
|
|
25
|
+
formApi: FormApi<TFormData, any, any, any, any, any, any, any, any>;
|
|
22
26
|
signal: AbortSignal;
|
|
23
|
-
}) =>
|
|
27
|
+
}) => unknown | Promise<unknown>;
|
|
24
28
|
export type FormValidator<TFormData, TType, TFn = unknown> = {
|
|
25
29
|
validate(options: {
|
|
26
30
|
value: TType;
|
|
@@ -32,20 +36,21 @@ export type FormValidator<TFormData, TType, TFn = unknown> = {
|
|
|
32
36
|
/**
|
|
33
37
|
* @private
|
|
34
38
|
*/
|
|
35
|
-
export type FormAsyncValidateOrFn<TFormData
|
|
36
|
-
export
|
|
39
|
+
export type FormAsyncValidateOrFn<TFormData> = FormValidateAsyncFn<TFormData> | StandardSchemaV1<TFormData, unknown>;
|
|
40
|
+
export type UnwrapFormAsyncValidateOrFn<TValidateOrFn extends undefined | FormAsyncValidateOrFn<any>> = [TValidateOrFn] extends [FormValidateAsyncFn<any>] ? Awaited<ReturnType<TValidateOrFn>> : [TValidateOrFn] extends [StandardSchemaV1<any, any>] ? Record<string, StandardSchemaV1Issue[]> : undefined;
|
|
41
|
+
export interface FormValidators<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>> {
|
|
37
42
|
/**
|
|
38
43
|
* Optional function that fires as soon as the component mounts.
|
|
39
44
|
*/
|
|
40
|
-
onMount?:
|
|
45
|
+
onMount?: TOnMount;
|
|
41
46
|
/**
|
|
42
47
|
* Optional function that checks the validity of your data whenever a value changes
|
|
43
48
|
*/
|
|
44
|
-
onChange?:
|
|
49
|
+
onChange?: TOnChange;
|
|
45
50
|
/**
|
|
46
51
|
* Optional onChange asynchronous counterpart to onChange. Useful for more complex validation logic that might involve server requests.
|
|
47
52
|
*/
|
|
48
|
-
onChangeAsync?:
|
|
53
|
+
onChangeAsync?: TOnChangeAsync;
|
|
49
54
|
/**
|
|
50
55
|
* The default time in milliseconds that if set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds.
|
|
51
56
|
*/
|
|
@@ -53,29 +58,29 @@ export interface FormValidators<TFormData, TFormValidator extends Validator<TFor
|
|
|
53
58
|
/**
|
|
54
59
|
* Optional function that validates the form data when a field loses focus, returns a `FormValidationError`
|
|
55
60
|
*/
|
|
56
|
-
onBlur?:
|
|
61
|
+
onBlur?: TOnBlur;
|
|
57
62
|
/**
|
|
58
63
|
* Optional onBlur asynchronous validation method for when a field loses focus returns a ` FormValidationError` or a promise of `Promise<FormValidationError>`
|
|
59
64
|
*/
|
|
60
|
-
onBlurAsync?:
|
|
65
|
+
onBlurAsync?: TOnBlurAsync;
|
|
61
66
|
/**
|
|
62
67
|
* The default time in milliseconds that if set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds.
|
|
63
68
|
*/
|
|
64
69
|
onBlurAsyncDebounceMs?: number;
|
|
65
|
-
onSubmit?:
|
|
66
|
-
onSubmitAsync?:
|
|
70
|
+
onSubmit?: TOnSubmit;
|
|
71
|
+
onSubmitAsync?: TOnSubmitAsync;
|
|
67
72
|
}
|
|
68
73
|
/**
|
|
69
74
|
* @private
|
|
70
75
|
*/
|
|
71
|
-
export interface FormTransform<TFormData,
|
|
72
|
-
fn: (formBase: FormApi<TFormData,
|
|
76
|
+
export interface FormTransform<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>> {
|
|
77
|
+
fn: (formBase: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer>) => FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer>;
|
|
73
78
|
deps: unknown[];
|
|
74
79
|
}
|
|
75
80
|
/**
|
|
76
81
|
* An object representing the options for a form.
|
|
77
82
|
*/
|
|
78
|
-
export interface FormOptions<TFormData,
|
|
83
|
+
export interface FormOptions<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>> {
|
|
79
84
|
/**
|
|
80
85
|
* Set initial values for your form.
|
|
81
86
|
*/
|
|
@@ -83,7 +88,7 @@ export interface FormOptions<TFormData, TFormValidator extends Validator<TFormDa
|
|
|
83
88
|
/**
|
|
84
89
|
* The default state for the form.
|
|
85
90
|
*/
|
|
86
|
-
defaultState?: Partial<FormState<TFormData>>;
|
|
91
|
+
defaultState?: Partial<FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer>>;
|
|
87
92
|
/**
|
|
88
93
|
* If true, always run async validation, even when sync validation has produced an error. Defaults to undefined.
|
|
89
94
|
*/
|
|
@@ -92,29 +97,25 @@ export interface FormOptions<TFormData, TFormValidator extends Validator<TFormDa
|
|
|
92
97
|
* Optional time in milliseconds if you want to introduce a delay before firing off an async action.
|
|
93
98
|
*/
|
|
94
99
|
asyncDebounceMs?: number;
|
|
95
|
-
/**
|
|
96
|
-
* A validator adapter to support usage of extra validation types (IE: Zod, Yup, or Valibot usage)
|
|
97
|
-
*/
|
|
98
|
-
validatorAdapter?: TFormValidator;
|
|
99
100
|
/**
|
|
100
101
|
* A list of validators to pass to the form
|
|
101
102
|
*/
|
|
102
|
-
validators?: FormValidators<TFormData,
|
|
103
|
+
validators?: FormValidators<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync>;
|
|
103
104
|
/**
|
|
104
105
|
* A function to be called when the form is submitted, what should happen once the user submits a valid form returns `any` or a promise `Promise<any>`
|
|
105
106
|
*/
|
|
106
107
|
onSubmit?: (props: {
|
|
107
108
|
value: TFormData;
|
|
108
|
-
formApi: FormApi<TFormData,
|
|
109
|
+
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer>;
|
|
109
110
|
}) => any | Promise<any>;
|
|
110
111
|
/**
|
|
111
112
|
* Specify an action for scenarios where the user tries to submit an invalid form.
|
|
112
113
|
*/
|
|
113
114
|
onSubmitInvalid?: (props: {
|
|
114
115
|
value: TFormData;
|
|
115
|
-
formApi: FormApi<TFormData,
|
|
116
|
+
formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer>;
|
|
116
117
|
}) => void;
|
|
117
|
-
transform?: FormTransform<TFormData,
|
|
118
|
+
transform?: FormTransform<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer>;
|
|
118
119
|
}
|
|
119
120
|
/**
|
|
120
121
|
* An object representing the validation metadata for a field. Not intended for public usage.
|
|
@@ -128,11 +129,11 @@ export type ValidationMeta = {
|
|
|
128
129
|
/**
|
|
129
130
|
* An object representing the field information for a specific field within the form.
|
|
130
131
|
*/
|
|
131
|
-
export type FieldInfo<TFormData
|
|
132
|
+
export type FieldInfo<TFormData> = {
|
|
132
133
|
/**
|
|
133
134
|
* An instance of the FieldAPI.
|
|
134
135
|
*/
|
|
135
|
-
instance: FieldApi<TFormData, any,
|
|
136
|
+
instance: FieldApi<TFormData, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any, any> | null;
|
|
136
137
|
/**
|
|
137
138
|
* A record of field validation internal handling.
|
|
138
139
|
*/
|
|
@@ -141,7 +142,7 @@ export type FieldInfo<TFormData, TFormValidator extends Validator<TFormData, unk
|
|
|
141
142
|
/**
|
|
142
143
|
* An object representing the current state of the form.
|
|
143
144
|
*/
|
|
144
|
-
export type BaseFormState<TFormData
|
|
145
|
+
export type BaseFormState<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>> = {
|
|
145
146
|
/**
|
|
146
147
|
* The current values of the form fields.
|
|
147
148
|
*/
|
|
@@ -149,7 +150,7 @@ export type BaseFormState<TFormData> = {
|
|
|
149
150
|
/**
|
|
150
151
|
* The error map for the form itself.
|
|
151
152
|
*/
|
|
152
|
-
errorMap: FormValidationErrorMap
|
|
153
|
+
errorMap: FormValidationErrorMap<UnwrapFormValidateOrFn<TOnMount>, UnwrapFormValidateOrFn<TOnChange>, UnwrapFormAsyncValidateOrFn<TOnChangeAsync>, UnwrapFormValidateOrFn<TOnBlur>, UnwrapFormAsyncValidateOrFn<TOnBlurAsync>, UnwrapFormValidateOrFn<TOnSubmit>, UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>, UnwrapFormAsyncValidateOrFn<TOnServer>>;
|
|
153
154
|
/**
|
|
154
155
|
* An internal mechanism used for keeping track of validation logic in a form.
|
|
155
156
|
*/
|
|
@@ -157,7 +158,7 @@ export type BaseFormState<TFormData> = {
|
|
|
157
158
|
/**
|
|
158
159
|
* A record of field metadata for each field in the form, not including the derived properties, like `errors` and such
|
|
159
160
|
*/
|
|
160
|
-
fieldMetaBase: Record<DeepKeys<TFormData>,
|
|
161
|
+
fieldMetaBase: Record<DeepKeys<TFormData>, AnyFieldMetaBase>;
|
|
161
162
|
/**
|
|
162
163
|
* A boolean indicating if the form is currently in the process of being submitted after `handleSubmit` is called.
|
|
163
164
|
*
|
|
@@ -184,7 +185,7 @@ export type BaseFormState<TFormData> = {
|
|
|
184
185
|
*/
|
|
185
186
|
submissionAttempts: number;
|
|
186
187
|
};
|
|
187
|
-
export type DerivedFormState<TFormData
|
|
188
|
+
export type DerivedFormState<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>> = {
|
|
188
189
|
/**
|
|
189
190
|
* A boolean indicating if the form is currently validating.
|
|
190
191
|
*/
|
|
@@ -196,7 +197,7 @@ export type DerivedFormState<TFormData> = {
|
|
|
196
197
|
/**
|
|
197
198
|
* The error array for the form itself.
|
|
198
199
|
*/
|
|
199
|
-
errors:
|
|
200
|
+
errors: Array<UnwrapFormValidateOrFn<TOnMount> | UnwrapFormValidateOrFn<TOnChange> | UnwrapFormAsyncValidateOrFn<TOnChangeAsync> | UnwrapFormValidateOrFn<TOnBlur> | UnwrapFormAsyncValidateOrFn<TOnBlurAsync> | UnwrapFormValidateOrFn<TOnSubmit> | UnwrapFormAsyncValidateOrFn<TOnSubmitAsync> | UnwrapFormAsyncValidateOrFn<TOnServer>>;
|
|
200
201
|
/**
|
|
201
202
|
* A boolean indicating if any of the form fields are currently validating.
|
|
202
203
|
*/
|
|
@@ -232,9 +233,16 @@ export type DerivedFormState<TFormData> = {
|
|
|
232
233
|
/**
|
|
233
234
|
* A record of field metadata for each field in the form.
|
|
234
235
|
*/
|
|
235
|
-
fieldMeta: Record<DeepKeys<TFormData>,
|
|
236
|
+
fieldMeta: Record<DeepKeys<TFormData>, AnyFieldMeta>;
|
|
236
237
|
};
|
|
237
|
-
export type FormState<TFormData
|
|
238
|
+
export type FormState<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>> = BaseFormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer> & DerivedFormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer>;
|
|
239
|
+
export type AnyFormState = FormState<any, any, any, any, any, any, any, any, any>;
|
|
240
|
+
/**
|
|
241
|
+
* @public
|
|
242
|
+
*
|
|
243
|
+
* A type representing the Form API with all generics set to `any` for convenience.
|
|
244
|
+
*/
|
|
245
|
+
export type AnyFormApi = FormApi<any, any, any, any, any, any, any, any, any>;
|
|
238
246
|
/**
|
|
239
247
|
* A class representing the Form API. It handles the logic and interactions with the form state.
|
|
240
248
|
*
|
|
@@ -242,19 +250,19 @@ export type FormState<TFormData> = BaseFormState<TFormData> & DerivedFormState<T
|
|
|
242
250
|
* hook/function like `useForm` or `createForm` to create a new instance for you that uses your framework's reactivity model.
|
|
243
251
|
* However, if you need to create a new instance manually, you can do so by calling the `new FormApi` constructor.
|
|
244
252
|
*/
|
|
245
|
-
export declare class FormApi<TFormData,
|
|
253
|
+
export declare class FormApi<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>> {
|
|
246
254
|
/**
|
|
247
255
|
* The options for the form.
|
|
248
256
|
*/
|
|
249
|
-
options: FormOptions<TFormData,
|
|
250
|
-
baseStore: Store<BaseFormState<TFormData>>;
|
|
251
|
-
fieldMetaDerived: Derived<Record<DeepKeys<TFormData>,
|
|
252
|
-
store: Derived<FormState<TFormData>>;
|
|
257
|
+
options: FormOptions<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer>;
|
|
258
|
+
baseStore: Store<BaseFormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer>>;
|
|
259
|
+
fieldMetaDerived: Derived<Record<DeepKeys<TFormData>, AnyFieldMeta>>;
|
|
260
|
+
store: Derived<FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer>>;
|
|
253
261
|
/**
|
|
254
262
|
* A record of field information for each field in the form.
|
|
255
263
|
*/
|
|
256
|
-
fieldInfo: Record<DeepKeys<TFormData>, FieldInfo<TFormData
|
|
257
|
-
get state(): FormState<TFormData>;
|
|
264
|
+
fieldInfo: Record<DeepKeys<TFormData>, FieldInfo<TFormData>>;
|
|
265
|
+
get state(): FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer>;
|
|
258
266
|
/**
|
|
259
267
|
* @private
|
|
260
268
|
*/
|
|
@@ -262,24 +270,22 @@ export declare class FormApi<TFormData, TFormValidator extends Validator<TFormDa
|
|
|
262
270
|
/**
|
|
263
271
|
* Constructs a new `FormApi` instance with the given form options.
|
|
264
272
|
*/
|
|
265
|
-
constructor(opts?: FormOptions<TFormData,
|
|
273
|
+
constructor(opts?: FormOptions<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer>);
|
|
266
274
|
/**
|
|
267
275
|
* @private
|
|
268
276
|
*/
|
|
269
|
-
runValidator<TValue extends {
|
|
270
|
-
|
|
271
|
-
formApi: FormApi<any, any>;
|
|
272
|
-
validationSource: ValidationSource;
|
|
277
|
+
runValidator<TValue extends TStandardSchemaValidatorValue<TFormData> & {
|
|
278
|
+
formApi: AnyFormApi;
|
|
273
279
|
}, TType extends 'validate' | 'validateAsync'>(props: {
|
|
274
|
-
validate: TType extends 'validate' ? FormValidateOrFn<TFormData
|
|
280
|
+
validate: TType extends 'validate' ? FormValidateOrFn<TFormData> : FormAsyncValidateOrFn<TFormData>;
|
|
275
281
|
value: TValue;
|
|
276
282
|
type: TType;
|
|
277
|
-
}):
|
|
283
|
+
}): unknown;
|
|
278
284
|
mount: () => () => void;
|
|
279
285
|
/**
|
|
280
286
|
* Updates the form options and form state.
|
|
281
287
|
*/
|
|
282
|
-
update: (options?: FormOptions<TFormData,
|
|
288
|
+
update: (options?: FormOptions<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer>) => void;
|
|
283
289
|
/**
|
|
284
290
|
* Resets the form state to the default values.
|
|
285
291
|
* If values are provided, the form will be reset to those values instead and the default values will be updated.
|
|
@@ -293,31 +299,31 @@ export declare class FormApi<TFormData, TFormValidator extends Validator<TFormDa
|
|
|
293
299
|
/**
|
|
294
300
|
* Validates all fields using the correct handlers for a given validation cause.
|
|
295
301
|
*/
|
|
296
|
-
validateAllFields: (cause: ValidationCause) => Promise<
|
|
302
|
+
validateAllFields: (cause: ValidationCause) => Promise<unknown[]>;
|
|
297
303
|
/**
|
|
298
304
|
* Validates the children of a specified array in the form starting from a given index until the end using the correct handlers for a given validation type.
|
|
299
305
|
*/
|
|
300
|
-
validateArrayFieldsStartingFrom: <TField extends DeepKeys<TFormData>>(field: TField, index: number, cause: ValidationCause) => Promise<
|
|
306
|
+
validateArrayFieldsStartingFrom: <TField extends DeepKeys<TFormData>>(field: TField, index: number, cause: ValidationCause) => Promise<unknown[]>;
|
|
301
307
|
/**
|
|
302
308
|
* Validates a specified field in the form using the correct handlers for a given validation type.
|
|
303
309
|
*/
|
|
304
|
-
validateField: <TField extends DeepKeys<TFormData>>(field: TField, cause: ValidationCause) =>
|
|
310
|
+
validateField: <TField extends DeepKeys<TFormData>>(field: TField, cause: ValidationCause) => unknown[] | Promise<unknown[]>;
|
|
305
311
|
/**
|
|
306
312
|
* TODO: This code is copied from FieldApi, we should refactor to share
|
|
307
313
|
* @private
|
|
308
314
|
*/
|
|
309
315
|
validateSync: (cause: ValidationCause) => {
|
|
310
316
|
hasErrored: boolean;
|
|
311
|
-
fieldsErrorMap:
|
|
317
|
+
fieldsErrorMap: FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync>;
|
|
312
318
|
};
|
|
313
319
|
/**
|
|
314
320
|
* @private
|
|
315
321
|
*/
|
|
316
|
-
validateAsync: (cause: ValidationCause) => Promise<
|
|
322
|
+
validateAsync: (cause: ValidationCause) => Promise<FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync>>;
|
|
317
323
|
/**
|
|
318
324
|
* @private
|
|
319
325
|
*/
|
|
320
|
-
validate: (cause: ValidationCause) =>
|
|
326
|
+
validate: (cause: ValidationCause) => FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync> | Promise<FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync>>;
|
|
321
327
|
/**
|
|
322
328
|
* Handles the form submission, performs validation, and calls the appropriate onSubmit or onInvalidSubmit callbacks.
|
|
323
329
|
*/
|
|
@@ -329,16 +335,16 @@ export declare class FormApi<TFormData, TFormValidator extends Validator<TFormDa
|
|
|
329
335
|
/**
|
|
330
336
|
* Gets the metadata of the specified field.
|
|
331
337
|
*/
|
|
332
|
-
getFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField) =>
|
|
338
|
+
getFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField) => AnyFieldMeta | undefined;
|
|
333
339
|
/**
|
|
334
340
|
* Gets the field info of the specified field.
|
|
335
341
|
*/
|
|
336
|
-
getFieldInfo: <TField extends DeepKeys<TFormData>>(field: TField) => FieldInfo<TFormData
|
|
342
|
+
getFieldInfo: <TField extends DeepKeys<TFormData>>(field: TField) => FieldInfo<TFormData>;
|
|
337
343
|
/**
|
|
338
344
|
* Updates the metadata of the specified field.
|
|
339
345
|
*/
|
|
340
|
-
setFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField, updater: Updater<
|
|
341
|
-
resetFieldMeta: <TField extends DeepKeys<TFormData>>(fieldMeta: Record<TField,
|
|
346
|
+
setFieldMeta: <TField extends DeepKeys<TFormData>>(field: TField, updater: Updater<AnyFieldMeta>) => void;
|
|
347
|
+
resetFieldMeta: <TField extends DeepKeys<TFormData>>(fieldMeta: Record<TField, AnyFieldMeta>) => Record<TField, AnyFieldMeta>;
|
|
342
348
|
/**
|
|
343
349
|
* Sets the value of the specified field and optionally updates the touched state.
|
|
344
350
|
*/
|
|
@@ -368,5 +374,6 @@ export declare class FormApi<TFormData, TFormValidator extends Validator<TFormDa
|
|
|
368
374
|
/**
|
|
369
375
|
* Updates the form's errorMap
|
|
370
376
|
*/
|
|
371
|
-
setErrorMap(errorMap: ValidationErrorMap): void;
|
|
377
|
+
setErrorMap(errorMap: ValidationErrorMap<TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync>): void;
|
|
372
378
|
}
|
|
379
|
+
export {};
|
package/dist/esm/FormApi.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { batch, Store, Derived } from "@tanstack/store";
|
|
2
|
-
import { shallow, getSyncValidatorArray, getAsyncValidatorArray, getBy, functionalUpdate, setBy, deleteBy, isNonEmptyArray } from "./utils.js";
|
|
3
|
-
import { isStandardSchemaValidator,
|
|
2
|
+
import { shallow, getSyncValidatorArray, getAsyncValidatorArray, getBy, functionalUpdate, setBy, deleteBy, isNonEmptyArray, isGlobalFormValidationError } from "./utils.js";
|
|
3
|
+
import { isStandardSchemaValidator, standardSchemaValidators } from "./standardSchemaValidator.js";
|
|
4
4
|
import { metaHelper } from "./metaHelper.js";
|
|
5
5
|
function getDefaultFormState(defaultState) {
|
|
6
6
|
return {
|
|
@@ -20,9 +20,6 @@ function getDefaultFormState(defaultState) {
|
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
|
-
const isFormValidationError = (error) => {
|
|
24
|
-
return typeof error === "object";
|
|
25
|
-
};
|
|
26
23
|
class FormApi {
|
|
27
24
|
/**
|
|
28
25
|
* Constructs a new `FormApi` instance with the given form options.
|
|
@@ -89,19 +86,21 @@ class FormApi {
|
|
|
89
86
|
this.validateAllFields = async (cause) => {
|
|
90
87
|
const fieldValidationPromises = [];
|
|
91
88
|
batch(() => {
|
|
92
|
-
void Object.values(this.fieldInfo).forEach(
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
()
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
field.instance.
|
|
89
|
+
void Object.values(this.fieldInfo).forEach(
|
|
90
|
+
(field) => {
|
|
91
|
+
if (!field.instance) return;
|
|
92
|
+
const fieldInstance = field.instance;
|
|
93
|
+
fieldValidationPromises.push(
|
|
94
|
+
// Remember, `validate` is either a sync operation or a promise
|
|
95
|
+
Promise.resolve().then(
|
|
96
|
+
() => fieldInstance.validate(cause, { skipFormValidation: true })
|
|
97
|
+
)
|
|
98
|
+
);
|
|
99
|
+
if (!field.instance.state.meta.isTouched) {
|
|
100
|
+
field.instance.setMeta((prev) => ({ ...prev, isTouched: true }));
|
|
101
|
+
}
|
|
103
102
|
}
|
|
104
|
-
|
|
103
|
+
);
|
|
105
104
|
});
|
|
106
105
|
const fieldErrorMapMap = await Promise.all(fieldValidationPromises);
|
|
107
106
|
return fieldErrorMapMap.flat();
|
|
@@ -340,13 +339,15 @@ class FormApi {
|
|
|
340
339
|
return;
|
|
341
340
|
}
|
|
342
341
|
batch(() => {
|
|
343
|
-
void Object.values(this.fieldInfo).forEach(
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
342
|
+
void Object.values(this.fieldInfo).forEach(
|
|
343
|
+
(field) => {
|
|
344
|
+
var _a3, _b2, _c2;
|
|
345
|
+
(_c2 = (_b2 = (_a3 = field.instance) == null ? void 0 : _a3.options.listeners) == null ? void 0 : _b2.onSubmit) == null ? void 0 : _c2.call(_b2, {
|
|
346
|
+
value: field.instance.state.value,
|
|
347
|
+
fieldApi: field.instance
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
);
|
|
350
351
|
});
|
|
351
352
|
try {
|
|
352
353
|
await ((_f = (_e = this.options).onSubmit) == null ? void 0 : _f.call(_e, { value: this.state.values, formApi: this }));
|
|
@@ -532,13 +533,13 @@ class FormApi {
|
|
|
532
533
|
this.baseStore = new Store(
|
|
533
534
|
getDefaultFormState({
|
|
534
535
|
...opts == null ? void 0 : opts.defaultState,
|
|
535
|
-
values: (opts == null ? void 0 : opts.defaultValues) ?? ((_a = opts == null ? void 0 : opts.defaultState) == null ? void 0 : _a.values)
|
|
536
|
-
isFormValid: true
|
|
536
|
+
values: (opts == null ? void 0 : opts.defaultValues) ?? ((_a = opts == null ? void 0 : opts.defaultState) == null ? void 0 : _a.values)
|
|
537
537
|
})
|
|
538
538
|
);
|
|
539
539
|
this.fieldMetaDerived = new Derived({
|
|
540
540
|
deps: [this.baseStore],
|
|
541
541
|
fn: ({ prevDepVals, currDepVals, prevVal: _prevVal }) => {
|
|
542
|
+
var _a2;
|
|
542
543
|
const prevVal = _prevVal;
|
|
543
544
|
const prevBaseStore = prevDepVals == null ? void 0 : prevDepVals[0];
|
|
544
545
|
const currBaseStore = currDepVals[0];
|
|
@@ -555,6 +556,12 @@ class FormApi {
|
|
|
555
556
|
fieldErrors = Object.values(currBaseVal.errorMap ?? {}).filter(
|
|
556
557
|
(val) => val !== void 0
|
|
557
558
|
);
|
|
559
|
+
const fieldInstance = (_a2 = this.getFieldInfo(fieldName)) == null ? void 0 : _a2.instance;
|
|
560
|
+
if (fieldInstance && !fieldInstance.options.disableErrorFlat) {
|
|
561
|
+
fieldErrors = fieldErrors == null ? void 0 : fieldErrors.flat(
|
|
562
|
+
1
|
|
563
|
+
);
|
|
564
|
+
}
|
|
558
565
|
}
|
|
559
566
|
const isFieldPristine = !currBaseVal.isDirty;
|
|
560
567
|
if (prevFieldInfo && prevFieldInfo.isPristine === isFieldPristine && prevFieldInfo.errors === fieldErrors && currBaseVal === prevBaseVal) {
|
|
@@ -607,20 +614,15 @@ class FormApi {
|
|
|
607
614
|
const isValidating = !!isFieldsValidating;
|
|
608
615
|
let errors = (prevVal == null ? void 0 : prevVal.errors) ?? [];
|
|
609
616
|
if (!prevBaseStore || currBaseStore.errorMap !== prevBaseStore.errorMap) {
|
|
610
|
-
errors = Object.values(currBaseStore.errorMap).reduce(
|
|
611
|
-
(
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
prev.push(curr);
|
|
615
|
-
return prev;
|
|
616
|
-
} else if (curr && isFormValidationError(curr)) {
|
|
617
|
-
prev.push(curr.form);
|
|
618
|
-
return prev;
|
|
619
|
-
}
|
|
617
|
+
errors = Object.values(currBaseStore.errorMap).reduce((prev, curr) => {
|
|
618
|
+
if (curr === void 0) return prev;
|
|
619
|
+
if (curr && isGlobalFormValidationError(curr)) {
|
|
620
|
+
prev.push(curr.form);
|
|
620
621
|
return prev;
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
|
|
622
|
+
}
|
|
623
|
+
prev.push(curr);
|
|
624
|
+
return prev;
|
|
625
|
+
}, []);
|
|
624
626
|
}
|
|
625
627
|
const isFormValid = errors.length === 0;
|
|
626
628
|
const isValid = isFieldsValid && isFormValid;
|
|
@@ -670,12 +672,8 @@ class FormApi {
|
|
|
670
672
|
* @private
|
|
671
673
|
*/
|
|
672
674
|
runValidator(props) {
|
|
673
|
-
const adapter = this.options.validatorAdapter;
|
|
674
|
-
if (adapter && (typeof props.validate !== "function" || "~standard" in props.validate)) {
|
|
675
|
-
return adapter()[props.type](props.value, props.validate);
|
|
676
|
-
}
|
|
677
675
|
if (isStandardSchemaValidator(props.validate)) {
|
|
678
|
-
return
|
|
676
|
+
return standardSchemaValidators[props.type](
|
|
679
677
|
props.value,
|
|
680
678
|
props.validate
|
|
681
679
|
);
|
|
@@ -686,25 +684,24 @@ class FormApi {
|
|
|
686
684
|
* Updates the form's errorMap
|
|
687
685
|
*/
|
|
688
686
|
setErrorMap(errorMap) {
|
|
689
|
-
this.baseStore.setState(
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
687
|
+
this.baseStore.setState(
|
|
688
|
+
(prev) => ({
|
|
689
|
+
...prev,
|
|
690
|
+
errorMap: {
|
|
691
|
+
...prev.errorMap,
|
|
692
|
+
...errorMap
|
|
693
|
+
}
|
|
694
|
+
})
|
|
695
|
+
);
|
|
696
696
|
}
|
|
697
697
|
}
|
|
698
698
|
function normalizeError(rawError) {
|
|
699
699
|
if (rawError) {
|
|
700
|
-
if (
|
|
700
|
+
if (isGlobalFormValidationError(rawError)) {
|
|
701
701
|
const formError = normalizeError(rawError.form).formError;
|
|
702
702
|
const fieldErrors = rawError.fields;
|
|
703
703
|
return { formError, fieldErrors };
|
|
704
704
|
}
|
|
705
|
-
if (typeof rawError !== "string") {
|
|
706
|
-
return { formError: "Invalid Form Values" };
|
|
707
|
-
}
|
|
708
705
|
return { formError: rawError };
|
|
709
706
|
}
|
|
710
707
|
return { formError: void 0 };
|