@tanstack/form-core 1.20.0 → 1.21.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/EventClient.cjs +13 -0
- package/dist/cjs/EventClient.cjs.map +1 -0
- package/dist/cjs/EventClient.d.cts +52 -0
- package/dist/cjs/FormApi.cjs +68 -3
- package/dist/cjs/FormApi.cjs.map +1 -1
- package/dist/cjs/FormApi.d.cts +11 -2
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +1 -0
- package/dist/esm/EventClient.d.ts +52 -0
- package/dist/esm/EventClient.js +13 -0
- package/dist/esm/EventClient.js.map +1 -0
- package/dist/esm/FormApi.d.ts +11 -2
- package/dist/esm/FormApi.js +68 -3
- package/dist/esm/FormApi.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/package.json +3 -2
- package/src/EventClient.ts +73 -0
- package/src/FormApi.ts +123 -5
- package/src/index.ts +1 -0
package/src/FormApi.ts
CHANGED
|
@@ -19,6 +19,12 @@ import {
|
|
|
19
19
|
standardSchemaValidators,
|
|
20
20
|
} from './standardSchemaValidator'
|
|
21
21
|
import { defaultFieldMeta, metaHelper } from './metaHelper'
|
|
22
|
+
import { formEventClient } from './EventClient'
|
|
23
|
+
import type {
|
|
24
|
+
RequestFormForceReset,
|
|
25
|
+
RequestFormReset,
|
|
26
|
+
RequestFormState,
|
|
27
|
+
} from './EventClient'
|
|
22
28
|
import type { ValidationLogicFn } from './ValidationLogic'
|
|
23
29
|
import type {
|
|
24
30
|
StandardSchemaV1,
|
|
@@ -510,6 +516,21 @@ export interface FormOptions<
|
|
|
510
516
|
>
|
|
511
517
|
}
|
|
512
518
|
|
|
519
|
+
export type AnyFormOptions = FormOptions<
|
|
520
|
+
any,
|
|
521
|
+
any,
|
|
522
|
+
any,
|
|
523
|
+
any,
|
|
524
|
+
any,
|
|
525
|
+
any,
|
|
526
|
+
any,
|
|
527
|
+
any,
|
|
528
|
+
any,
|
|
529
|
+
any,
|
|
530
|
+
any,
|
|
531
|
+
any
|
|
532
|
+
>
|
|
533
|
+
|
|
513
534
|
/**
|
|
514
535
|
* An object representing the validation metadata for a field. Not intended for public usage.
|
|
515
536
|
*/
|
|
@@ -937,13 +958,21 @@ export class FormApi<
|
|
|
937
958
|
prevTransformArray: unknown[] = []
|
|
938
959
|
|
|
939
960
|
/**
|
|
940
|
-
*
|
|
961
|
+
* @private
|
|
941
962
|
*/
|
|
942
963
|
timeoutIds: {
|
|
943
964
|
validations: Record<ValidationCause, ReturnType<typeof setTimeout> | null>
|
|
944
965
|
listeners: Record<ListenerCause, ReturnType<typeof setTimeout> | null>
|
|
945
966
|
formListeners: Record<ListenerCause, ReturnType<typeof setTimeout> | null>
|
|
946
967
|
}
|
|
968
|
+
/**
|
|
969
|
+
* @private
|
|
970
|
+
*/
|
|
971
|
+
private _formId: string
|
|
972
|
+
/**
|
|
973
|
+
* @private
|
|
974
|
+
*/
|
|
975
|
+
private _devtoolsSubmissionOverride: boolean
|
|
947
976
|
|
|
948
977
|
/**
|
|
949
978
|
* Constructs a new `FormApi` instance with the given form options.
|
|
@@ -970,6 +999,10 @@ export class FormApi<
|
|
|
970
999
|
formListeners: {} as Record<ListenerCause, never>,
|
|
971
1000
|
}
|
|
972
1001
|
|
|
1002
|
+
this._formId = opts?.formId ?? crypto.randomUUID()
|
|
1003
|
+
|
|
1004
|
+
this._devtoolsSubmissionOverride = false
|
|
1005
|
+
|
|
973
1006
|
this.baseStore = new Store(
|
|
974
1007
|
getDefaultFormState({
|
|
975
1008
|
...(opts?.defaultState as any),
|
|
@@ -1261,10 +1294,42 @@ export class FormApi<
|
|
|
1261
1294
|
this.handleSubmit = this.handleSubmit.bind(this)
|
|
1262
1295
|
|
|
1263
1296
|
this.update(opts || {})
|
|
1297
|
+
|
|
1298
|
+
this.store.subscribe(() => {
|
|
1299
|
+
formEventClient.emit('form-state-change', {
|
|
1300
|
+
id: this._formId,
|
|
1301
|
+
state: this.store.state,
|
|
1302
|
+
options: this.options,
|
|
1303
|
+
})
|
|
1304
|
+
})
|
|
1305
|
+
|
|
1306
|
+
formEventClient.on('request-form-state', (e) => {
|
|
1307
|
+
if (e.payload.id === this._formId) {
|
|
1308
|
+
formEventClient.emit('form-state-change', {
|
|
1309
|
+
id: this._formId,
|
|
1310
|
+
state: this.store.state,
|
|
1311
|
+
options: this.options,
|
|
1312
|
+
})
|
|
1313
|
+
}
|
|
1314
|
+
})
|
|
1315
|
+
|
|
1316
|
+
formEventClient.on('request-form-reset', (e) => {
|
|
1317
|
+
if (e.payload.id === this._formId) {
|
|
1318
|
+
this.reset()
|
|
1319
|
+
}
|
|
1320
|
+
})
|
|
1321
|
+
|
|
1322
|
+
formEventClient.on('request-form-force-submit', (e) => {
|
|
1323
|
+
if (e.payload.id === this._formId) {
|
|
1324
|
+
this._devtoolsSubmissionOverride = true
|
|
1325
|
+
this.handleSubmit()
|
|
1326
|
+
this._devtoolsSubmissionOverride = false
|
|
1327
|
+
}
|
|
1328
|
+
})
|
|
1264
1329
|
}
|
|
1265
1330
|
|
|
1266
|
-
|
|
1267
|
-
return this.
|
|
1331
|
+
formId(): string | undefined {
|
|
1332
|
+
return this._formId
|
|
1268
1333
|
}
|
|
1269
1334
|
|
|
1270
1335
|
/**
|
|
@@ -1298,14 +1363,29 @@ export class FormApi<
|
|
|
1298
1363
|
const cleanup = () => {
|
|
1299
1364
|
cleanupFieldMetaDerived()
|
|
1300
1365
|
cleanupStoreDerived()
|
|
1366
|
+
|
|
1367
|
+
// broadcast form unmount for devtools
|
|
1368
|
+
formEventClient.emit('form-unmounted', {
|
|
1369
|
+
id: this._formId,
|
|
1370
|
+
})
|
|
1301
1371
|
}
|
|
1302
1372
|
|
|
1303
1373
|
this.options.listeners?.onMount?.({ formApi: this })
|
|
1304
1374
|
|
|
1305
1375
|
const { onMount } = this.options.validators || {}
|
|
1376
|
+
|
|
1377
|
+
// broadcast form state for devtools on mounting
|
|
1378
|
+
formEventClient.emit('form-state-change', {
|
|
1379
|
+
id: this._formId,
|
|
1380
|
+
state: this.store.state,
|
|
1381
|
+
options: this.options,
|
|
1382
|
+
})
|
|
1383
|
+
|
|
1384
|
+
// if no validation skip
|
|
1306
1385
|
if (!onMount) return cleanup
|
|
1307
|
-
this.validateSync('mount')
|
|
1308
1386
|
|
|
1387
|
+
// validate
|
|
1388
|
+
this.validateSync('mount')
|
|
1309
1389
|
return cleanup
|
|
1310
1390
|
}
|
|
1311
1391
|
|
|
@@ -1932,7 +2012,7 @@ export class FormApi<
|
|
|
1932
2012
|
)
|
|
1933
2013
|
})
|
|
1934
2014
|
|
|
1935
|
-
if (!this.state.canSubmit) return
|
|
2015
|
+
if (!this.state.canSubmit && !this._devtoolsSubmissionOverride) return
|
|
1936
2016
|
|
|
1937
2017
|
const submitMetaArg =
|
|
1938
2018
|
submitMeta ?? (this.options.onSubmitMeta as TSubmitMeta)
|
|
@@ -1947,11 +2027,22 @@ export class FormApi<
|
|
|
1947
2027
|
|
|
1948
2028
|
if (!this.state.isFieldsValid) {
|
|
1949
2029
|
done()
|
|
2030
|
+
|
|
1950
2031
|
this.options.onSubmitInvalid?.({
|
|
1951
2032
|
value: this.state.values,
|
|
1952
2033
|
formApi: this,
|
|
1953
2034
|
meta: submitMetaArg,
|
|
1954
2035
|
})
|
|
2036
|
+
|
|
2037
|
+
formEventClient.emit('form-submission-state-change', {
|
|
2038
|
+
id: this._formId,
|
|
2039
|
+
submissionAttempt: this.state.submissionAttempts,
|
|
2040
|
+
successful: false,
|
|
2041
|
+
stage: 'validateAllFields',
|
|
2042
|
+
errors: (Object.values(this.state.fieldMeta) as AnyFieldMeta[])
|
|
2043
|
+
.map((meta: AnyFieldMeta) => meta.errors)
|
|
2044
|
+
.flat(),
|
|
2045
|
+
})
|
|
1955
2046
|
return
|
|
1956
2047
|
}
|
|
1957
2048
|
|
|
@@ -1960,11 +2051,21 @@ export class FormApi<
|
|
|
1960
2051
|
// Fields are invalid, do not submit
|
|
1961
2052
|
if (!this.state.isValid) {
|
|
1962
2053
|
done()
|
|
2054
|
+
|
|
1963
2055
|
this.options.onSubmitInvalid?.({
|
|
1964
2056
|
value: this.state.values,
|
|
1965
2057
|
formApi: this,
|
|
1966
2058
|
meta: submitMetaArg,
|
|
1967
2059
|
})
|
|
2060
|
+
|
|
2061
|
+
formEventClient.emit('form-submission-state-change', {
|
|
2062
|
+
id: this._formId,
|
|
2063
|
+
submissionAttempt: this.state.submissionAttempts,
|
|
2064
|
+
successful: false,
|
|
2065
|
+
stage: 'validate',
|
|
2066
|
+
errors: this.state.errors,
|
|
2067
|
+
})
|
|
2068
|
+
|
|
1968
2069
|
return
|
|
1969
2070
|
}
|
|
1970
2071
|
|
|
@@ -1995,6 +2096,13 @@ export class FormApi<
|
|
|
1995
2096
|
isSubmitted: true,
|
|
1996
2097
|
isSubmitSuccessful: true, // Set isSubmitSuccessful to true on successful submission
|
|
1997
2098
|
}))
|
|
2099
|
+
|
|
2100
|
+
formEventClient.emit('form-submission-state-change', {
|
|
2101
|
+
id: this._formId,
|
|
2102
|
+
submissionAttempt: this.state.submissionAttempts,
|
|
2103
|
+
successful: true,
|
|
2104
|
+
})
|
|
2105
|
+
|
|
1998
2106
|
done()
|
|
1999
2107
|
})
|
|
2000
2108
|
} catch (err) {
|
|
@@ -2002,7 +2110,17 @@ export class FormApi<
|
|
|
2002
2110
|
...prev,
|
|
2003
2111
|
isSubmitSuccessful: false, // Ensure isSubmitSuccessful is false if an error occurs
|
|
2004
2112
|
}))
|
|
2113
|
+
|
|
2114
|
+
formEventClient.emit('form-submission-state-change', {
|
|
2115
|
+
id: this._formId,
|
|
2116
|
+
submissionAttempt: this.state.submissionAttempts,
|
|
2117
|
+
successful: false,
|
|
2118
|
+
stage: 'inflight',
|
|
2119
|
+
onError: err,
|
|
2120
|
+
})
|
|
2121
|
+
|
|
2005
2122
|
done()
|
|
2123
|
+
|
|
2006
2124
|
throw err
|
|
2007
2125
|
}
|
|
2008
2126
|
}
|
package/src/index.ts
CHANGED