@tanstack/form-core 1.16.0 → 1.18.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 +48 -40
- package/dist/cjs/FieldApi.cjs.map +1 -1
- package/dist/cjs/FieldApi.d.cts +33 -30
- package/dist/cjs/FieldGroupApi.cjs.map +1 -1
- package/dist/cjs/FieldGroupApi.d.cts +6 -6
- package/dist/cjs/FormApi.cjs +82 -69
- package/dist/cjs/FormApi.cjs.map +1 -1
- package/dist/cjs/FormApi.d.cts +45 -35
- package/dist/cjs/ValidationLogic.cjs +106 -0
- package/dist/cjs/ValidationLogic.cjs.map +1 -0
- package/dist/cjs/ValidationLogic.d.cts +47 -0
- package/dist/cjs/formOptions.cjs.map +1 -1
- package/dist/cjs/formOptions.d.cts +1 -1
- package/dist/cjs/index.cjs +3 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +1 -0
- package/dist/cjs/mergeForm.cjs.map +1 -1
- package/dist/cjs/mergeForm.d.cts +1 -1
- package/dist/cjs/metaHelper.cjs.map +1 -1
- package/dist/cjs/metaHelper.d.cts +1 -1
- package/dist/cjs/types.d.cts +6 -3
- package/dist/cjs/utils.cjs +51 -63
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +11 -5
- package/dist/esm/FieldApi.d.ts +33 -30
- package/dist/esm/FieldApi.js +48 -40
- package/dist/esm/FieldApi.js.map +1 -1
- package/dist/esm/FieldGroupApi.d.ts +6 -6
- package/dist/esm/FieldGroupApi.js.map +1 -1
- package/dist/esm/FormApi.d.ts +45 -35
- package/dist/esm/FormApi.js +82 -69
- package/dist/esm/FormApi.js.map +1 -1
- package/dist/esm/ValidationLogic.d.ts +47 -0
- package/dist/esm/ValidationLogic.js +106 -0
- package/dist/esm/ValidationLogic.js.map +1 -0
- package/dist/esm/formOptions.d.ts +1 -1
- package/dist/esm/formOptions.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/mergeForm.d.ts +1 -1
- package/dist/esm/mergeForm.js.map +1 -1
- package/dist/esm/metaHelper.d.ts +1 -1
- package/dist/esm/metaHelper.js.map +1 -1
- package/dist/esm/types.d.ts +6 -3
- package/dist/esm/utils.d.ts +11 -5
- package/dist/esm/utils.js +51 -63
- package/dist/esm/utils.js.map +1 -1
- package/package.json +16 -3
- package/src/FieldApi.ts +185 -14
- package/src/FieldGroupApi.ts +14 -0
- package/src/FormApi.ts +139 -3
- package/src/ValidationLogic.ts +200 -0
- package/src/formOptions.ts +1 -1
- package/src/index.ts +1 -0
- package/src/mergeForm.ts +16 -1
- package/src/metaHelper.ts +4 -0
- package/src/types.ts +17 -1
- package/src/utils.ts +159 -109
package/src/mergeForm.ts
CHANGED
|
@@ -81,10 +81,25 @@ export function mergeForm<TFormData>(
|
|
|
81
81
|
any,
|
|
82
82
|
any,
|
|
83
83
|
any,
|
|
84
|
+
any,
|
|
85
|
+
any,
|
|
84
86
|
any
|
|
85
87
|
>,
|
|
86
88
|
state: Partial<
|
|
87
|
-
FormApi<
|
|
89
|
+
FormApi<
|
|
90
|
+
TFormData,
|
|
91
|
+
any,
|
|
92
|
+
any,
|
|
93
|
+
any,
|
|
94
|
+
any,
|
|
95
|
+
any,
|
|
96
|
+
any,
|
|
97
|
+
any,
|
|
98
|
+
any,
|
|
99
|
+
any,
|
|
100
|
+
any,
|
|
101
|
+
any
|
|
102
|
+
>['state']
|
|
88
103
|
>,
|
|
89
104
|
) {
|
|
90
105
|
mutateMergeDeep(baseForm.state, state)
|
package/src/metaHelper.ts
CHANGED
|
@@ -30,6 +30,8 @@ export function metaHelper<
|
|
|
30
30
|
TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
31
31
|
TOnSubmit extends undefined | FormValidateOrFn<TFormData>,
|
|
32
32
|
TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
33
|
+
TOnDynamic extends undefined | FormValidateOrFn<TFormData>,
|
|
34
|
+
TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
33
35
|
TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
34
36
|
TSubmitMeta,
|
|
35
37
|
>(
|
|
@@ -42,6 +44,8 @@ export function metaHelper<
|
|
|
42
44
|
TOnBlurAsync,
|
|
43
45
|
TOnSubmit,
|
|
44
46
|
TOnSubmitAsync,
|
|
47
|
+
TOnDynamic,
|
|
48
|
+
TOnDynamicAsync,
|
|
45
49
|
TOnServer,
|
|
46
50
|
TSubmitMeta
|
|
47
51
|
>,
|
package/src/types.ts
CHANGED
|
@@ -10,7 +10,13 @@ export type ValidationSource = 'form' | 'field'
|
|
|
10
10
|
* "server" is only intended for SSR/SSG validation and should not execute anything
|
|
11
11
|
* @private
|
|
12
12
|
*/
|
|
13
|
-
export type ValidationCause =
|
|
13
|
+
export type ValidationCause =
|
|
14
|
+
| 'change'
|
|
15
|
+
| 'blur'
|
|
16
|
+
| 'submit'
|
|
17
|
+
| 'mount'
|
|
18
|
+
| 'server'
|
|
19
|
+
| 'dynamic'
|
|
14
20
|
|
|
15
21
|
/**
|
|
16
22
|
* @private
|
|
@@ -33,12 +39,15 @@ export type ValidationErrorMap<
|
|
|
33
39
|
TOnBlurAsyncReturn = unknown,
|
|
34
40
|
TOnSubmitReturn = unknown,
|
|
35
41
|
TOnSubmitAsyncReturn = unknown,
|
|
42
|
+
TOnDynamicReturn = unknown,
|
|
43
|
+
TOnDynamicAsyncReturn = unknown,
|
|
36
44
|
TOnServerReturn = unknown,
|
|
37
45
|
> = {
|
|
38
46
|
onMount?: TOnMountReturn
|
|
39
47
|
onChange?: TOnChangeReturn | TOnChangeAsyncReturn
|
|
40
48
|
onBlur?: TOnBlurReturn | TOnBlurAsyncReturn
|
|
41
49
|
onSubmit?: TOnSubmitReturn | TOnSubmitAsyncReturn
|
|
50
|
+
onDynamic?: TOnDynamicReturn | TOnDynamicAsyncReturn
|
|
42
51
|
onServer?: TOnServerReturn
|
|
43
52
|
}
|
|
44
53
|
|
|
@@ -51,6 +60,7 @@ export type ValidationErrorMapSource = {
|
|
|
51
60
|
onBlur?: ValidationSource
|
|
52
61
|
onSubmit?: ValidationSource
|
|
53
62
|
onServer?: ValidationSource
|
|
63
|
+
onDynamic?: ValidationSource
|
|
54
64
|
}
|
|
55
65
|
|
|
56
66
|
/**
|
|
@@ -65,6 +75,8 @@ export type FormValidationErrorMap<
|
|
|
65
75
|
TOnBlurAsyncReturn = unknown,
|
|
66
76
|
TOnSubmitReturn = unknown,
|
|
67
77
|
TOnSubmitAsyncReturn = unknown,
|
|
78
|
+
TOnDynamicReturn = unknown,
|
|
79
|
+
TOnDynamicAsyncReturn = unknown,
|
|
68
80
|
TOnServerReturn = unknown,
|
|
69
81
|
> = {
|
|
70
82
|
onMount?: TOnMountReturn | GlobalFormValidationError<TFormData>
|
|
@@ -80,6 +92,10 @@ export type FormValidationErrorMap<
|
|
|
80
92
|
| TOnSubmitReturn
|
|
81
93
|
| TOnSubmitAsyncReturn
|
|
82
94
|
| GlobalFormValidationError<TFormData>
|
|
95
|
+
onDynamic?:
|
|
96
|
+
| TOnDynamicReturn
|
|
97
|
+
| TOnDynamicAsyncReturn
|
|
98
|
+
| GlobalFormValidationError<TFormData>
|
|
83
99
|
onServer?: TOnServerReturn
|
|
84
100
|
}
|
|
85
101
|
|
package/src/utils.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { defaultValidationLogic } from './ValidationLogic'
|
|
2
|
+
import type { ValidationLogicProps } from './ValidationLogic'
|
|
1
3
|
import type { FieldValidators } from './FieldApi'
|
|
2
4
|
import type { FormValidators } from './FormApi'
|
|
3
5
|
import type {
|
|
@@ -225,78 +227,6 @@ export interface AsyncValidator<T> {
|
|
|
225
227
|
debounceMs: number
|
|
226
228
|
}
|
|
227
229
|
|
|
228
|
-
/**
|
|
229
|
-
* @private
|
|
230
|
-
*/
|
|
231
|
-
export function getAsyncValidatorArray<T>(
|
|
232
|
-
cause: ValidationCause,
|
|
233
|
-
options: AsyncValidatorArrayPartialOptions<T>,
|
|
234
|
-
): T extends FieldValidators<any, any, any, any, any, any, any, any, any, any>
|
|
235
|
-
? Array<
|
|
236
|
-
AsyncValidator<T['onChangeAsync'] | T['onBlurAsync'] | T['onSubmitAsync']>
|
|
237
|
-
>
|
|
238
|
-
: T extends FormValidators<any, any, any, any, any, any, any, any>
|
|
239
|
-
? Array<
|
|
240
|
-
AsyncValidator<
|
|
241
|
-
T['onChangeAsync'] | T['onBlurAsync'] | T['onSubmitAsync']
|
|
242
|
-
>
|
|
243
|
-
>
|
|
244
|
-
: never {
|
|
245
|
-
const { asyncDebounceMs } = options
|
|
246
|
-
const {
|
|
247
|
-
onChangeAsync,
|
|
248
|
-
onBlurAsync,
|
|
249
|
-
onSubmitAsync,
|
|
250
|
-
onBlurAsyncDebounceMs,
|
|
251
|
-
onChangeAsyncDebounceMs,
|
|
252
|
-
} = (options.validators || {}) as
|
|
253
|
-
| FieldValidators<any, any, any, any, any, any, any, any, any, any>
|
|
254
|
-
| FormValidators<any, any, any, any, any, any, any, any>
|
|
255
|
-
|
|
256
|
-
const defaultDebounceMs = asyncDebounceMs ?? 0
|
|
257
|
-
|
|
258
|
-
const changeValidator = {
|
|
259
|
-
cause: 'change',
|
|
260
|
-
validate: onChangeAsync,
|
|
261
|
-
debounceMs: onChangeAsyncDebounceMs ?? defaultDebounceMs,
|
|
262
|
-
} as const
|
|
263
|
-
|
|
264
|
-
const blurValidator = {
|
|
265
|
-
cause: 'blur',
|
|
266
|
-
validate: onBlurAsync,
|
|
267
|
-
debounceMs: onBlurAsyncDebounceMs ?? defaultDebounceMs,
|
|
268
|
-
} as const
|
|
269
|
-
|
|
270
|
-
const submitValidator = {
|
|
271
|
-
cause: 'submit',
|
|
272
|
-
validate: onSubmitAsync,
|
|
273
|
-
debounceMs: 0,
|
|
274
|
-
} as const
|
|
275
|
-
|
|
276
|
-
const noopValidator = (
|
|
277
|
-
validator:
|
|
278
|
-
| typeof changeValidator
|
|
279
|
-
| typeof blurValidator
|
|
280
|
-
| typeof submitValidator,
|
|
281
|
-
) => ({ ...validator, debounceMs: 0 }) as const
|
|
282
|
-
|
|
283
|
-
switch (cause) {
|
|
284
|
-
case 'submit':
|
|
285
|
-
return [
|
|
286
|
-
noopValidator(changeValidator),
|
|
287
|
-
noopValidator(blurValidator),
|
|
288
|
-
submitValidator,
|
|
289
|
-
] as never
|
|
290
|
-
case 'blur':
|
|
291
|
-
return [blurValidator] as never
|
|
292
|
-
case 'change':
|
|
293
|
-
return [changeValidator] as never
|
|
294
|
-
case 'server':
|
|
295
|
-
default:
|
|
296
|
-
return [] as never
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
230
|
interface SyncValidatorArrayPartialOptions<T> {
|
|
301
231
|
validators?: T
|
|
302
232
|
}
|
|
@@ -314,51 +244,171 @@ export interface SyncValidator<T> {
|
|
|
314
244
|
*/
|
|
315
245
|
export function getSyncValidatorArray<T>(
|
|
316
246
|
cause: ValidationCause,
|
|
317
|
-
options: SyncValidatorArrayPartialOptions<T
|
|
318
|
-
|
|
247
|
+
options: SyncValidatorArrayPartialOptions<T> & {
|
|
248
|
+
validationLogic?: any
|
|
249
|
+
form?: any
|
|
250
|
+
},
|
|
251
|
+
): T extends FieldValidators<
|
|
252
|
+
any,
|
|
253
|
+
any,
|
|
254
|
+
any,
|
|
255
|
+
any,
|
|
256
|
+
any,
|
|
257
|
+
any,
|
|
258
|
+
any,
|
|
259
|
+
any,
|
|
260
|
+
any,
|
|
261
|
+
any,
|
|
262
|
+
any,
|
|
263
|
+
any
|
|
264
|
+
>
|
|
319
265
|
? Array<
|
|
320
|
-
SyncValidator<
|
|
266
|
+
SyncValidator<
|
|
267
|
+
| T['onChange']
|
|
268
|
+
| T['onBlur']
|
|
269
|
+
| T['onSubmit']
|
|
270
|
+
| T['onMount']
|
|
271
|
+
| T['onDynamic']
|
|
272
|
+
>
|
|
321
273
|
>
|
|
322
|
-
: T extends FormValidators<any, any, any, any, any, any, any, any>
|
|
274
|
+
: T extends FormValidators<any, any, any, any, any, any, any, any, any, any>
|
|
323
275
|
? Array<
|
|
324
276
|
SyncValidator<
|
|
325
|
-
|
|
277
|
+
| T['onChange']
|
|
278
|
+
| T['onBlur']
|
|
279
|
+
| T['onSubmit']
|
|
280
|
+
| T['onMount']
|
|
281
|
+
| T['onDynamic']
|
|
326
282
|
>
|
|
327
283
|
>
|
|
328
284
|
: never {
|
|
329
|
-
const
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
// Allows us to clear onServer errors
|
|
339
|
-
const serverValidator = {
|
|
340
|
-
cause: 'server',
|
|
341
|
-
validate: () => undefined,
|
|
342
|
-
} as const
|
|
343
|
-
|
|
344
|
-
switch (cause) {
|
|
345
|
-
case 'mount':
|
|
346
|
-
return [mountValidator] as never
|
|
347
|
-
case 'submit':
|
|
348
|
-
return [
|
|
349
|
-
changeValidator,
|
|
350
|
-
blurValidator,
|
|
351
|
-
submitValidator,
|
|
352
|
-
serverValidator,
|
|
353
|
-
] as never
|
|
354
|
-
case 'server':
|
|
355
|
-
return [serverValidator] as never
|
|
356
|
-
case 'blur':
|
|
357
|
-
return [blurValidator, serverValidator] as never
|
|
358
|
-
case 'change':
|
|
359
|
-
default:
|
|
360
|
-
return [changeValidator, serverValidator] as never
|
|
285
|
+
const runValidation = (
|
|
286
|
+
props: Parameters<ValidationLogicProps['runValidation']>[0],
|
|
287
|
+
) => {
|
|
288
|
+
return props.validators.filter(Boolean).map((validator) => {
|
|
289
|
+
return {
|
|
290
|
+
cause: validator!.cause,
|
|
291
|
+
validate: validator!.fn,
|
|
292
|
+
}
|
|
293
|
+
})
|
|
361
294
|
}
|
|
295
|
+
|
|
296
|
+
return options.validationLogic({
|
|
297
|
+
form: options.form,
|
|
298
|
+
validators: options.validators,
|
|
299
|
+
event: { type: cause, async: false },
|
|
300
|
+
runValidation,
|
|
301
|
+
})
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* @private
|
|
306
|
+
*/
|
|
307
|
+
export function getAsyncValidatorArray<T>(
|
|
308
|
+
cause: ValidationCause,
|
|
309
|
+
options: AsyncValidatorArrayPartialOptions<T> & {
|
|
310
|
+
validationLogic?: any
|
|
311
|
+
form?: any
|
|
312
|
+
},
|
|
313
|
+
): T extends FieldValidators<
|
|
314
|
+
any,
|
|
315
|
+
any,
|
|
316
|
+
any,
|
|
317
|
+
any,
|
|
318
|
+
any,
|
|
319
|
+
any,
|
|
320
|
+
any,
|
|
321
|
+
any,
|
|
322
|
+
any,
|
|
323
|
+
any,
|
|
324
|
+
any,
|
|
325
|
+
any
|
|
326
|
+
>
|
|
327
|
+
? Array<
|
|
328
|
+
AsyncValidator<
|
|
329
|
+
| T['onChangeAsync']
|
|
330
|
+
| T['onBlurAsync']
|
|
331
|
+
| T['onSubmitAsync']
|
|
332
|
+
| T['onDynamicAsync']
|
|
333
|
+
>
|
|
334
|
+
>
|
|
335
|
+
: T extends FormValidators<any, any, any, any, any, any, any, any, any, any>
|
|
336
|
+
? Array<
|
|
337
|
+
AsyncValidator<
|
|
338
|
+
| T['onChangeAsync']
|
|
339
|
+
| T['onBlurAsync']
|
|
340
|
+
| T['onSubmitAsync']
|
|
341
|
+
| T['onDynamicAsync']
|
|
342
|
+
>
|
|
343
|
+
>
|
|
344
|
+
: never {
|
|
345
|
+
const { asyncDebounceMs } = options
|
|
346
|
+
const {
|
|
347
|
+
onBlurAsyncDebounceMs,
|
|
348
|
+
onChangeAsyncDebounceMs,
|
|
349
|
+
onDynamicAsyncDebounceMs,
|
|
350
|
+
} = (options.validators || {}) as
|
|
351
|
+
| FieldValidators<
|
|
352
|
+
any,
|
|
353
|
+
any,
|
|
354
|
+
any,
|
|
355
|
+
any,
|
|
356
|
+
any,
|
|
357
|
+
any,
|
|
358
|
+
any,
|
|
359
|
+
any,
|
|
360
|
+
any,
|
|
361
|
+
any,
|
|
362
|
+
any,
|
|
363
|
+
any
|
|
364
|
+
>
|
|
365
|
+
| FormValidators<any, any, any, any, any, any, any, any, any, any>
|
|
366
|
+
|
|
367
|
+
const defaultDebounceMs = asyncDebounceMs ?? 0
|
|
368
|
+
|
|
369
|
+
const runValidation = (
|
|
370
|
+
props: Parameters<ValidationLogicProps['runValidation']>[0],
|
|
371
|
+
) => {
|
|
372
|
+
return props.validators.filter(Boolean).map((validator) => {
|
|
373
|
+
const validatorCause = validator?.cause || cause
|
|
374
|
+
|
|
375
|
+
let debounceMs = defaultDebounceMs
|
|
376
|
+
|
|
377
|
+
switch (validatorCause) {
|
|
378
|
+
case 'change':
|
|
379
|
+
debounceMs = onChangeAsyncDebounceMs ?? defaultDebounceMs
|
|
380
|
+
break
|
|
381
|
+
case 'blur':
|
|
382
|
+
debounceMs = onBlurAsyncDebounceMs ?? defaultDebounceMs
|
|
383
|
+
break
|
|
384
|
+
case 'dynamic':
|
|
385
|
+
debounceMs = onDynamicAsyncDebounceMs ?? defaultDebounceMs
|
|
386
|
+
break
|
|
387
|
+
case 'submit':
|
|
388
|
+
debounceMs = 0 // submit validators are always run immediately
|
|
389
|
+
break
|
|
390
|
+
default:
|
|
391
|
+
break
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (cause === 'submit') {
|
|
395
|
+
debounceMs = 0
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
return {
|
|
399
|
+
cause: validatorCause,
|
|
400
|
+
validate: validator!.fn,
|
|
401
|
+
debounceMs: debounceMs,
|
|
402
|
+
}
|
|
403
|
+
})
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
return options.validationLogic({
|
|
407
|
+
form: options.form,
|
|
408
|
+
validators: options.validators,
|
|
409
|
+
event: { type: cause, async: true },
|
|
410
|
+
runValidation,
|
|
411
|
+
})
|
|
362
412
|
}
|
|
363
413
|
|
|
364
414
|
export const isGlobalFormValidationError = (
|