diff --git a/docs/framework/react/guides/listeners.md b/docs/framework/react/guides/listeners.md
index 934ca6f3f..1f68d6a8c 100644
--- a/docs/framework/react/guides/listeners.md
+++ b/docs/framework/react/guides/listeners.md
@@ -67,3 +67,25 @@ function App() {
)
}
```
+
+### Built-in Debouncing
+
+If you are making an API request inside a listener, you may want to debounce the calls as it can lead to performance issues.
+We enable an easy method for debouncing your listeners by adding a `onChangeDebounceMs` or `onBlurDebounceMs`.
+
+```tsx
+
{
+ console.log(`Country changed to: ${value} without a change within 500ms, resetting province`)
+ form.setFieldValue('province', '')
+ },
+ }}
+>
+ {(field) => (
+ /* ... */
+ )}
+
+```
diff --git a/docs/reference/classes/fieldapi.md b/docs/reference/classes/fieldapi.md
index 34df8b000..93daf3c36 100644
--- a/docs/reference/classes/fieldapi.md
+++ b/docs/reference/classes/fieldapi.md
@@ -7,7 +7,7 @@ title: FieldApi
# Class: FieldApi\
-Defined in: [packages/form-core/src/FieldApi.ts:842](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L842)
+Defined in: [packages/form-core/src/FieldApi.ts:845](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L845)
A class representing the API for managing a form field.
@@ -65,7 +65,7 @@ the `new FieldApi` constructor.
new FieldApi(opts): FieldApi
```
-Defined in: [packages/form-core/src/FieldApi.ts:970](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L970)
+Defined in: [packages/form-core/src/FieldApi.ts:976](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L976)
Initializes a new `FieldApi` instance.
@@ -87,7 +87,7 @@ Initializes a new `FieldApi` instance.
form: FormApi;
```
-Defined in: [packages/form-core/src/FieldApi.ts:886](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L886)
+Defined in: [packages/form-core/src/FieldApi.ts:889](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L889)
A reference to the form API instance.
@@ -99,7 +99,7 @@ A reference to the form API instance.
name: DeepKeys;
```
-Defined in: [packages/form-core/src/FieldApi.ts:910](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L910)
+Defined in: [packages/form-core/src/FieldApi.ts:913](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L913)
The field name.
@@ -111,7 +111,7 @@ The field name.
options: FieldApiOptions;
```
-Defined in: [packages/form-core/src/FieldApi.ts:914](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L914)
+Defined in: [packages/form-core/src/FieldApi.ts:917](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L917)
The field options.
@@ -123,7 +123,7 @@ The field options.
store: Derived>;
```
-Defined in: [packages/form-core/src/FieldApi.ts:938](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L938)
+Defined in: [packages/form-core/src/FieldApi.ts:941](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L941)
The field state store.
@@ -132,10 +132,22 @@ The field state store.
### timeoutIds
```ts
-timeoutIds: Record;
+timeoutIds: object;
```
-Defined in: [packages/form-core/src/FieldApi.ts:965](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L965)
+Defined in: [packages/form-core/src/FieldApi.ts:968](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L968)
+
+#### listeners
+
+```ts
+listeners: Record;
+```
+
+#### validations
+
+```ts
+validations: Record;
+```
## Accessors
@@ -147,7 +159,7 @@ Defined in: [packages/form-core/src/FieldApi.ts:965](https://github.com/TanStack
get state(): FieldState
```
-Defined in: [packages/form-core/src/FieldApi.ts:962](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L962)
+Defined in: [packages/form-core/src/FieldApi.ts:965](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L965)
The current field state.
@@ -163,7 +175,7 @@ The current field state.
getInfo(): FieldInfo
```
-Defined in: [packages/form-core/src/FieldApi.ts:1218](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1218)
+Defined in: [packages/form-core/src/FieldApi.ts:1224](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1224)
Gets the field information object.
@@ -179,7 +191,7 @@ Gets the field information object.
getMeta(): FieldMeta
```
-Defined in: [packages/form-core/src/FieldApi.ts:1186](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1186)
+Defined in: [packages/form-core/src/FieldApi.ts:1192](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1192)
#### Returns
@@ -193,7 +205,7 @@ Defined in: [packages/form-core/src/FieldApi.ts:1186](https://github.com/TanStac
getValue(): TData
```
-Defined in: [packages/form-core/src/FieldApi.ts:1168](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1168)
+Defined in: [packages/form-core/src/FieldApi.ts:1177](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1177)
Gets the current field value.
@@ -213,7 +225,7 @@ Use `field.state.value` instead.
handleBlur(): void
```
-Defined in: [packages/form-core/src/FieldApi.ts:1625](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1625)
+Defined in: [packages/form-core/src/FieldApi.ts:1616](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1616)
Handles the blur event.
@@ -229,7 +241,7 @@ Handles the blur event.
handleChange(updater): void
```
-Defined in: [packages/form-core/src/FieldApi.ts:1618](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1618)
+Defined in: [packages/form-core/src/FieldApi.ts:1609](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1609)
Handles the change event.
@@ -254,7 +266,7 @@ insertValue(
opts?): void
```
-Defined in: [packages/form-core/src/FieldApi.ts:1238](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1238)
+Defined in: [packages/form-core/src/FieldApi.ts:1241](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1241)
Inserts a value at the specified index, shifting the subsequent values to the right.
@@ -284,7 +296,7 @@ Inserts a value at the specified index, shifting the subsequent values to the ri
mount(): () => void
```
-Defined in: [packages/form-core/src/FieldApi.ts:1063](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1063)
+Defined in: [packages/form-core/src/FieldApi.ts:1072](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1072)
Mounts the field instance to the form.
@@ -307,7 +319,7 @@ moveValue(
opts?): void
```
-Defined in: [packages/form-core/src/FieldApi.ts:1294](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1294)
+Defined in: [packages/form-core/src/FieldApi.ts:1285](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1285)
Moves the value at the first specified index to the second specified index.
@@ -337,7 +349,7 @@ Moves the value at the first specified index to the second specified index.
pushValue(value, opts?): void
```
-Defined in: [packages/form-core/src/FieldApi.ts:1223](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1223)
+Defined in: [packages/form-core/src/FieldApi.ts:1229](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1229)
Pushes a new value to the field.
@@ -363,7 +375,7 @@ Pushes a new value to the field.
removeValue(index, opts?): void
```
-Defined in: [packages/form-core/src/FieldApi.ts:1270](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1270)
+Defined in: [packages/form-core/src/FieldApi.ts:1267](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1267)
Removes a value at the specified index.
@@ -422,7 +434,7 @@ Replaces a value at the specified index.
setErrorMap(errorMap): void
```
-Defined in: [packages/form-core/src/FieldApi.ts:1645](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1645)
+Defined in: [packages/form-core/src/FieldApi.ts:1633](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1633)
Updates the field's errorMap
@@ -444,7 +456,7 @@ Updates the field's errorMap
setMeta(updater): void
```
-Defined in: [packages/form-core/src/FieldApi.ts:1191](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1191)
+Defined in: [packages/form-core/src/FieldApi.ts:1197](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1197)
Sets the field metadata.
@@ -466,7 +478,7 @@ Sets the field metadata.
setValue(updater, options?): void
```
-Defined in: [packages/form-core/src/FieldApi.ts:1175](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1175)
+Defined in: [packages/form-core/src/FieldApi.ts:1184](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1184)
Sets the field value and run the `change` validator.
@@ -495,7 +507,7 @@ swapValues(
opts?): void
```
-Defined in: [packages/form-core/src/FieldApi.ts:1282](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1282)
+Defined in: [packages/form-core/src/FieldApi.ts:1276](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1276)
Swaps the values at the specified indices.
@@ -525,7 +537,7 @@ Swaps the values at the specified indices.
update(opts): void
```
-Defined in: [packages/form-core/src/FieldApi.ts:1111](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1111)
+Defined in: [packages/form-core/src/FieldApi.ts:1120](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1120)
Updates the field instance with new options.
@@ -547,7 +559,7 @@ Updates the field instance with new options.
validate(cause, opts?): unknown[] | Promise
```
-Defined in: [packages/form-core/src/FieldApi.ts:1585](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1585)
+Defined in: [packages/form-core/src/FieldApi.ts:1576](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L1576)
Validates the field value.
diff --git a/docs/reference/interfaces/fieldapioptions.md b/docs/reference/interfaces/fieldapioptions.md
index ced5f164b..8886296a0 100644
--- a/docs/reference/interfaces/fieldapioptions.md
+++ b/docs/reference/interfaces/fieldapioptions.md
@@ -7,7 +7,7 @@ title: FieldApiOptions
# Interface: FieldApiOptions\
-Defined in: [packages/form-core/src/FieldApi.ts:446](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L446)
+Defined in: [packages/form-core/src/FieldApi.ts:449](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L449)
An object type representing the required options for the FieldApi class.
@@ -63,7 +63,7 @@ An object type representing the required options for the FieldApi class.
optional asyncAlways: boolean;
```
-Defined in: [packages/form-core/src/FieldApi.ts:393](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L393)
+Defined in: [packages/form-core/src/FieldApi.ts:396](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L396)
If `true`, always run async validation, even if there are errors emitted during synchronous validation.
@@ -79,7 +79,7 @@ If `true`, always run async validation, even if there are errors emitted during
optional asyncDebounceMs: number;
```
-Defined in: [packages/form-core/src/FieldApi.ts:389](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L389)
+Defined in: [packages/form-core/src/FieldApi.ts:392](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L392)
The default time to debounce async validation if there is not a more specific debounce time passed.
@@ -95,7 +95,7 @@ The default time to debounce async validation if there is not a more specific de
optional defaultMeta: Partial>;
```
-Defined in: [packages/form-core/src/FieldApi.ts:412](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L412)
+Defined in: [packages/form-core/src/FieldApi.ts:415](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L415)
An optional object with default metadata for the field.
@@ -111,7 +111,7 @@ An optional object with default metadata for the field.
optional defaultValue: NoInfer;
```
-Defined in: [packages/form-core/src/FieldApi.ts:385](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L385)
+Defined in: [packages/form-core/src/FieldApi.ts:388](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L388)
An optional default value for the field.
@@ -127,7 +127,7 @@ An optional default value for the field.
optional disableErrorFlat: boolean;
```
-Defined in: [packages/form-core/src/FieldApi.ts:440](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L440)
+Defined in: [packages/form-core/src/FieldApi.ts:443](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L443)
Disable the `flat(1)` operation on `field.errors`. This is useful if you want to keep the error structure as is. Not suggested for most use-cases.
@@ -143,7 +143,7 @@ Disable the `flat(1)` operation on `field.errors`. This is useful if you want to
form: FormApi;
```
-Defined in: [packages/form-core/src/FieldApi.ts:498](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L498)
+Defined in: [packages/form-core/src/FieldApi.ts:501](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L501)
***
@@ -153,7 +153,7 @@ Defined in: [packages/form-core/src/FieldApi.ts:498](https://github.com/TanStack
optional listeners: FieldListeners;
```
-Defined in: [packages/form-core/src/FieldApi.ts:436](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L436)
+Defined in: [packages/form-core/src/FieldApi.ts:439](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L439)
A list of listeners which attach to the corresponding events
@@ -169,7 +169,7 @@ A list of listeners which attach to the corresponding events
name: TName;
```
-Defined in: [packages/form-core/src/FieldApi.ts:381](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L381)
+Defined in: [packages/form-core/src/FieldApi.ts:384](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L384)
The field name. The type will be `DeepKeys` to ensure your name is a deep key of the parent dataset.
@@ -185,7 +185,7 @@ The field name. The type will be `DeepKeys` to ensure your name is
optional validators: FieldValidators;
```
-Defined in: [packages/form-core/src/FieldApi.ts:397](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L397)
+Defined in: [packages/form-core/src/FieldApi.ts:400](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L400)
A list of validators to pass to the field
diff --git a/docs/reference/interfaces/fieldlisteners.md b/docs/reference/interfaces/fieldlisteners.md
index 7c64c8e01..277f98380 100644
--- a/docs/reference/interfaces/fieldlisteners.md
+++ b/docs/reference/interfaces/fieldlisteners.md
@@ -7,7 +7,7 @@ title: FieldListeners
# Interface: FieldListeners\
-Defined in: [packages/form-core/src/FieldApi.ts:346](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L346)
+Defined in: [packages/form-core/src/FieldApi.ts:347](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L347)
## Type Parameters
@@ -25,7 +25,17 @@ Defined in: [packages/form-core/src/FieldApi.ts:346](https://github.com/TanStack
optional onBlur: FieldListenerFn;
```
-Defined in: [packages/form-core/src/FieldApi.ts:352](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L352)
+Defined in: [packages/form-core/src/FieldApi.ts:354](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L354)
+
+***
+
+### onBlurDebounceMs?
+
+```ts
+optional onBlurDebounceMs: number;
+```
+
+Defined in: [packages/form-core/src/FieldApi.ts:355](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L355)
***
@@ -35,7 +45,17 @@ Defined in: [packages/form-core/src/FieldApi.ts:352](https://github.com/TanStack
optional onChange: FieldListenerFn;
```
-Defined in: [packages/form-core/src/FieldApi.ts:351](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L351)
+Defined in: [packages/form-core/src/FieldApi.ts:352](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L352)
+
+***
+
+### onChangeDebounceMs?
+
+```ts
+optional onChangeDebounceMs: number;
+```
+
+Defined in: [packages/form-core/src/FieldApi.ts:353](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L353)
***
@@ -45,7 +65,7 @@ Defined in: [packages/form-core/src/FieldApi.ts:351](https://github.com/TanStack
optional onMount: FieldListenerFn;
```
-Defined in: [packages/form-core/src/FieldApi.ts:353](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L353)
+Defined in: [packages/form-core/src/FieldApi.ts:356](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L356)
***
@@ -55,4 +75,4 @@ Defined in: [packages/form-core/src/FieldApi.ts:353](https://github.com/TanStack
optional onSubmit: FieldListenerFn;
```
-Defined in: [packages/form-core/src/FieldApi.ts:354](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L354)
+Defined in: [packages/form-core/src/FieldApi.ts:357](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L357)
diff --git a/docs/reference/interfaces/fieldoptions.md b/docs/reference/interfaces/fieldoptions.md
index a433202be..fbae41166 100644
--- a/docs/reference/interfaces/fieldoptions.md
+++ b/docs/reference/interfaces/fieldoptions.md
@@ -7,7 +7,7 @@ title: FieldOptions
# Interface: FieldOptions\
-Defined in: [packages/form-core/src/FieldApi.ts:360](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L360)
+Defined in: [packages/form-core/src/FieldApi.ts:363](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L363)
An object type representing the options for a field in a form.
@@ -45,7 +45,7 @@ An object type representing the options for a field in a form.
optional asyncAlways: boolean;
```
-Defined in: [packages/form-core/src/FieldApi.ts:393](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L393)
+Defined in: [packages/form-core/src/FieldApi.ts:396](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L396)
If `true`, always run async validation, even if there are errors emitted during synchronous validation.
@@ -57,7 +57,7 @@ If `true`, always run async validation, even if there are errors emitted during
optional asyncDebounceMs: number;
```
-Defined in: [packages/form-core/src/FieldApi.ts:389](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L389)
+Defined in: [packages/form-core/src/FieldApi.ts:392](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L392)
The default time to debounce async validation if there is not a more specific debounce time passed.
@@ -69,7 +69,7 @@ The default time to debounce async validation if there is not a more specific de
optional defaultMeta: Partial>;
```
-Defined in: [packages/form-core/src/FieldApi.ts:412](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L412)
+Defined in: [packages/form-core/src/FieldApi.ts:415](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L415)
An optional object with default metadata for the field.
@@ -81,7 +81,7 @@ An optional object with default metadata for the field.
optional defaultValue: NoInfer;
```
-Defined in: [packages/form-core/src/FieldApi.ts:385](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L385)
+Defined in: [packages/form-core/src/FieldApi.ts:388](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L388)
An optional default value for the field.
@@ -93,7 +93,7 @@ An optional default value for the field.
optional disableErrorFlat: boolean;
```
-Defined in: [packages/form-core/src/FieldApi.ts:440](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L440)
+Defined in: [packages/form-core/src/FieldApi.ts:443](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L443)
Disable the `flat(1)` operation on `field.errors`. This is useful if you want to keep the error structure as is. Not suggested for most use-cases.
@@ -105,7 +105,7 @@ Disable the `flat(1)` operation on `field.errors`. This is useful if you want to
optional listeners: FieldListeners;
```
-Defined in: [packages/form-core/src/FieldApi.ts:436](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L436)
+Defined in: [packages/form-core/src/FieldApi.ts:439](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L439)
A list of listeners which attach to the corresponding events
@@ -117,7 +117,7 @@ A list of listeners which attach to the corresponding events
name: TName;
```
-Defined in: [packages/form-core/src/FieldApi.ts:381](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L381)
+Defined in: [packages/form-core/src/FieldApi.ts:384](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L384)
The field name. The type will be `DeepKeys` to ensure your name is a deep key of the parent dataset.
@@ -129,6 +129,6 @@ The field name. The type will be `DeepKeys` to ensure your name is
optional validators: FieldValidators;
```
-Defined in: [packages/form-core/src/FieldApi.ts:397](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L397)
+Defined in: [packages/form-core/src/FieldApi.ts:400](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L400)
A list of validators to pass to the field
diff --git a/docs/reference/interfaces/fieldvalidators.md b/docs/reference/interfaces/fieldvalidators.md
index 321e28081..bd82893e1 100644
--- a/docs/reference/interfaces/fieldvalidators.md
+++ b/docs/reference/interfaces/fieldvalidators.md
@@ -7,7 +7,7 @@ title: FieldValidators
# Interface: FieldValidators\
-Defined in: [packages/form-core/src/FieldApi.ts:265](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L265)
+Defined in: [packages/form-core/src/FieldApi.ts:266](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L266)
## Type Parameters
@@ -39,7 +39,7 @@ Defined in: [packages/form-core/src/FieldApi.ts:265](https://github.com/TanStack
optional onBlur: TOnBlur;
```
-Defined in: [packages/form-core/src/FieldApi.ts:314](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L314)
+Defined in: [packages/form-core/src/FieldApi.ts:315](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L315)
An optional function, that runs on the blur event of input.
@@ -57,7 +57,7 @@ z.string().min(1)
optional onBlurAsync: TOnBlurAsync;
```
-Defined in: [packages/form-core/src/FieldApi.ts:320](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L320)
+Defined in: [packages/form-core/src/FieldApi.ts:321](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L321)
An optional property similar to `onBlur` but async validation.
@@ -75,7 +75,7 @@ z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })
optional onBlurAsyncDebounceMs: number;
```
-Defined in: [packages/form-core/src/FieldApi.ts:327](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L327)
+Defined in: [packages/form-core/src/FieldApi.ts:328](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L328)
An optional number to represent how long the `onBlurAsync` should wait before running
@@ -89,7 +89,7 @@ If set to a number larger than 0, will debounce the async validation event by th
optional onBlurListenTo: DeepKeys[];
```
-Defined in: [packages/form-core/src/FieldApi.ts:331](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L331)
+Defined in: [packages/form-core/src/FieldApi.ts:332](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L332)
An optional list of field names that should trigger this field's `onBlur` and `onBlurAsync` events when its value changes
@@ -101,7 +101,7 @@ An optional list of field names that should trigger this field's `onBlur` and `o
optional onChange: TOnChange;
```
-Defined in: [packages/form-core/src/FieldApi.ts:292](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L292)
+Defined in: [packages/form-core/src/FieldApi.ts:293](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L293)
An optional function, that runs on the change event of input.
@@ -119,7 +119,7 @@ z.string().min(1)
optional onChangeAsync: TOnChangeAsync;
```
-Defined in: [packages/form-core/src/FieldApi.ts:298](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L298)
+Defined in: [packages/form-core/src/FieldApi.ts:299](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L299)
An optional property similar to `onChange` but async validation
@@ -137,7 +137,7 @@ z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })
optional onChangeAsyncDebounceMs: number;
```
-Defined in: [packages/form-core/src/FieldApi.ts:304](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L304)
+Defined in: [packages/form-core/src/FieldApi.ts:305](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L305)
An optional number to represent how long the `onChangeAsync` should wait before running
@@ -151,7 +151,7 @@ If set to a number larger than 0, will debounce the async validation event by th
optional onChangeListenTo: DeepKeys[];
```
-Defined in: [packages/form-core/src/FieldApi.ts:308](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L308)
+Defined in: [packages/form-core/src/FieldApi.ts:309](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L309)
An optional list of field names that should trigger this field's `onChange` and `onChangeAsync` events when its value changes
@@ -163,7 +163,7 @@ An optional list of field names that should trigger this field's `onChange` and
optional onMount: TOnMount;
```
-Defined in: [packages/form-core/src/FieldApi.ts:286](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L286)
+Defined in: [packages/form-core/src/FieldApi.ts:287](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L287)
An optional function, that runs on the mount event of input.
@@ -175,7 +175,7 @@ An optional function, that runs on the mount event of input.
optional onSubmit: TOnSubmit;
```
-Defined in: [packages/form-core/src/FieldApi.ts:337](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L337)
+Defined in: [packages/form-core/src/FieldApi.ts:338](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L338)
An optional function, that runs on the submit event of form.
@@ -193,7 +193,7 @@ z.string().min(1)
optional onSubmitAsync: TOnSubmitAsync;
```
-Defined in: [packages/form-core/src/FieldApi.ts:343](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L343)
+Defined in: [packages/form-core/src/FieldApi.ts:344](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L344)
An optional property similar to `onSubmit` but async validation.
diff --git a/docs/reference/type-aliases/anyfieldapi.md b/docs/reference/type-aliases/anyfieldapi.md
index 3f5b3063c..1a44d5328 100644
--- a/docs/reference/type-aliases/anyfieldapi.md
+++ b/docs/reference/type-aliases/anyfieldapi.md
@@ -11,6 +11,6 @@ title: AnyFieldApi
type AnyFieldApi = FieldApi;
```
-Defined in: [packages/form-core/src/FieldApi.ts:811](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L811)
+Defined in: [packages/form-core/src/FieldApi.ts:814](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L814)
A type representing the Field API with all generics set to `any` for convenience.
diff --git a/docs/reference/type-aliases/anyfieldmeta.md b/docs/reference/type-aliases/anyfieldmeta.md
index 8b84f14d6..4f33d7694 100644
--- a/docs/reference/type-aliases/anyfieldmeta.md
+++ b/docs/reference/type-aliases/anyfieldmeta.md
@@ -11,4 +11,4 @@ title: AnyFieldMeta
type AnyFieldMeta = FieldMeta;
```
-Defined in: [packages/form-core/src/FieldApi.ts:730](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L730)
+Defined in: [packages/form-core/src/FieldApi.ts:733](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L733)
diff --git a/docs/reference/type-aliases/anyfieldmetabase.md b/docs/reference/type-aliases/anyfieldmetabase.md
index 61ef8ceee..db1e9aba8 100644
--- a/docs/reference/type-aliases/anyfieldmetabase.md
+++ b/docs/reference/type-aliases/anyfieldmetabase.md
@@ -11,4 +11,4 @@ title: AnyFieldMetaBase
type AnyFieldMetaBase = FieldMetaBase;
```
-Defined in: [packages/form-core/src/FieldApi.ts:567](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L567)
+Defined in: [packages/form-core/src/FieldApi.ts:570](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L570)
diff --git a/docs/reference/type-aliases/anyfieldmetaderived.md b/docs/reference/type-aliases/anyfieldmetaderived.md
index 6189f393c..b9a8a3261 100644
--- a/docs/reference/type-aliases/anyfieldmetaderived.md
+++ b/docs/reference/type-aliases/anyfieldmetaderived.md
@@ -11,4 +11,4 @@ title: AnyFieldMetaDerived
type AnyFieldMetaDerived = FieldMetaDerived;
```
-Defined in: [packages/form-core/src/FieldApi.ts:644](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L644)
+Defined in: [packages/form-core/src/FieldApi.ts:647](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L647)
diff --git a/docs/reference/type-aliases/fieldmeta.md b/docs/reference/type-aliases/fieldmeta.md
index c4d16234a..b92195a1b 100644
--- a/docs/reference/type-aliases/fieldmeta.md
+++ b/docs/reference/type-aliases/fieldmeta.md
@@ -11,7 +11,7 @@ title: FieldMeta
type FieldMeta = FieldMetaBase & FieldMetaDerived;
```
-Defined in: [packages/form-core/src/FieldApi.ts:667](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L667)
+Defined in: [packages/form-core/src/FieldApi.ts:670](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L670)
An object type representing the metadata of a field in a form.
diff --git a/docs/reference/type-aliases/fieldmetabase.md b/docs/reference/type-aliases/fieldmetabase.md
index 5077778f5..043c1a281 100644
--- a/docs/reference/type-aliases/fieldmetabase.md
+++ b/docs/reference/type-aliases/fieldmetabase.md
@@ -11,7 +11,7 @@ title: FieldMetaBase
type FieldMetaBase = object;
```
-Defined in: [packages/form-core/src/FieldApi.ts:512](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L512)
+Defined in: [packages/form-core/src/FieldApi.ts:515](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L515)
## Type Parameters
diff --git a/docs/reference/type-aliases/fieldmetaderived.md b/docs/reference/type-aliases/fieldmetaderived.md
index 1d2211802..b16b173e3 100644
--- a/docs/reference/type-aliases/fieldmetaderived.md
+++ b/docs/reference/type-aliases/fieldmetaderived.md
@@ -11,7 +11,7 @@ title: FieldMetaDerived
type FieldMetaDerived = object;
```
-Defined in: [packages/form-core/src/FieldApi.ts:587](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L587)
+Defined in: [packages/form-core/src/FieldApi.ts:590](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L590)
## Type Parameters
diff --git a/docs/reference/type-aliases/fieldstate.md b/docs/reference/type-aliases/fieldstate.md
index 5bd0e3c85..be6727599 100644
--- a/docs/reference/type-aliases/fieldstate.md
+++ b/docs/reference/type-aliases/fieldstate.md
@@ -11,7 +11,7 @@ title: FieldState
type FieldState = object;
```
-Defined in: [packages/form-core/src/FieldApi.ts:753](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L753)
+Defined in: [packages/form-core/src/FieldApi.ts:756](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L756)
An object type representing the state of a field.
diff --git a/docs/reference/type-aliases/formvalidationerror.md b/docs/reference/type-aliases/formvalidationerror.md
index e8178d450..a1c894218 100644
--- a/docs/reference/type-aliases/formvalidationerror.md
+++ b/docs/reference/type-aliases/formvalidationerror.md
@@ -13,7 +13,7 @@ type FormValidationError =
| GlobalFormValidationError;
```
-Defined in: [packages/form-core/src/types.ts:58](https://github.com/TanStack/form/blob/main/packages/form-core/src/types.ts#L58)
+Defined in: [packages/form-core/src/types.ts:63](https://github.com/TanStack/form/blob/main/packages/form-core/src/types.ts#L63)
## Type Parameters
diff --git a/docs/reference/type-aliases/unwrapfieldasyncvalidateorfn.md b/docs/reference/type-aliases/unwrapfieldasyncvalidateorfn.md
index f775de43d..f93e3ad69 100644
--- a/docs/reference/type-aliases/unwrapfieldasyncvalidateorfn.md
+++ b/docs/reference/type-aliases/unwrapfieldasyncvalidateorfn.md
@@ -14,7 +14,7 @@ type UnwrapFieldAsyncValidateOrFn =
| [TValidateOrFn] extends [FieldValidateAsyncFn] ? Awaited> : [TValidateOrFn] extends [StandardSchemaV1] ? StandardSchemaV1Issue[] : undefined;
```
-Defined in: [packages/form-core/src/FieldApi.ts:203](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L203)
+Defined in: [packages/form-core/src/FieldApi.ts:204](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L204)
## Type Parameters
diff --git a/docs/reference/type-aliases/unwrapfieldvalidateorfn.md b/docs/reference/type-aliases/unwrapfieldvalidateorfn.md
index 5f8b4b354..7852654f5 100644
--- a/docs/reference/type-aliases/unwrapfieldvalidateorfn.md
+++ b/docs/reference/type-aliases/unwrapfieldvalidateorfn.md
@@ -14,7 +14,7 @@ type UnwrapFieldValidateOrFn =
| [TValidateOrFn] extends [FieldValidateFn] ? ReturnType : [TValidateOrFn] extends [StandardSchemaV1] ? StandardSchemaV1Issue[] : undefined;
```
-Defined in: [packages/form-core/src/FieldApi.ts:121](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L121)
+Defined in: [packages/form-core/src/FieldApi.ts:122](https://github.com/TanStack/form/blob/main/packages/form-core/src/FieldApi.ts#L122)
## Type Parameters
diff --git a/packages/form-core/src/FieldApi.ts b/packages/form-core/src/FieldApi.ts
index 2af502b1b..b3f85f79e 100644
--- a/packages/form-core/src/FieldApi.ts
+++ b/packages/form-core/src/FieldApi.ts
@@ -20,6 +20,7 @@ import type {
FormValidateOrFn,
} from './FormApi'
import type {
+ ListenerCause,
UpdateMetaOptions,
ValidationCause,
ValidationError,
@@ -349,7 +350,9 @@ export interface FieldListeners<
TData extends DeepValue = DeepValue,
> {
onChange?: FieldListenerFn
+ onChangeDebounceMs?: number
onBlur?: FieldListenerFn
+ onBlurDebounceMs?: number
onMount?: FieldListenerFn
onSubmit?: FieldListenerFn
}
@@ -962,7 +965,10 @@ export class FieldApi<
get state() {
return this.store.state
}
- timeoutIds: Record | null>
+ timeoutIds: {
+ validations: Record | null>
+ listeners: Record | null>
+ }
/**
* Initializes a new `FieldApi` instance.
@@ -992,7 +998,10 @@ export class FieldApi<
) {
this.form = opts.form as never
this.name = opts.name as never
- this.timeoutIds = {} as Record
+ this.timeoutIds = {
+ validations: {} as Record,
+ listeners: {} as Record,
+ }
this.store = new Derived({
deps: [this.form.store],
@@ -1175,10 +1184,7 @@ export class FieldApi<
setValue = (updater: Updater, options?: UpdateMetaOptions) => {
this.form.setFieldValue(this.name, updater as never, options)
- this.options.listeners?.onChange?.({
- value: this.state.value,
- fieldApi: this,
- })
+ this.triggerOnChangeListener()
this.validate('change')
}
@@ -1226,10 +1232,7 @@ export class FieldApi<
) => {
this.form.pushFieldValue(this.name, value as any, opts)
- this.options.listeners?.onChange?.({
- value: this.state.value,
- fieldApi: this,
- })
+ this.triggerOnChangeListener()
}
/**
@@ -1242,10 +1245,7 @@ export class FieldApi<
) => {
this.form.insertFieldValue(this.name, index, value as any, opts)
- this.options.listeners?.onChange?.({
- value: this.state.value,
- fieldApi: this,
- })
+ this.triggerOnChangeListener()
}
/**
@@ -1258,10 +1258,7 @@ export class FieldApi<
) => {
this.form.replaceFieldValue(this.name, index, value as any, opts)
- this.options.listeners?.onChange?.({
- value: this.state.value,
- fieldApi: this,
- })
+ this.triggerOnChangeListener()
}
/**
@@ -1270,10 +1267,7 @@ export class FieldApi<
removeValue = (index: number, opts?: UpdateMetaOptions) => {
this.form.removeFieldValue(this.name, index, opts)
- this.options.listeners?.onChange?.({
- value: this.state.value,
- fieldApi: this,
- })
+ this.triggerOnChangeListener()
}
/**
@@ -1282,10 +1276,7 @@ export class FieldApi<
swapValues = (aIndex: number, bIndex: number, opts?: UpdateMetaOptions) => {
this.form.swapFieldValues(this.name, aIndex, bIndex, opts)
- this.options.listeners?.onChange?.({
- value: this.state.value,
- fieldApi: this,
- })
+ this.triggerOnChangeListener()
}
/**
@@ -1294,10 +1285,7 @@ export class FieldApi<
moveValue = (aIndex: number, bIndex: number, opts?: UpdateMetaOptions) => {
this.form.moveFieldValues(this.name, aIndex, bIndex, opts)
- this.options.listeners?.onChange?.({
- value: this.state.value,
- fieldApi: this,
- })
+ this.triggerOnChangeListener()
}
/**
@@ -1502,29 +1490,32 @@ export class FieldApi<
let rawError!: ValidationError | undefined
try {
rawError = await new Promise((rawResolve, rawReject) => {
- if (this.timeoutIds[validateObj.cause]) {
- clearTimeout(this.timeoutIds[validateObj.cause]!)
+ if (this.timeoutIds.validations[validateObj.cause]) {
+ clearTimeout(this.timeoutIds.validations[validateObj.cause]!)
}
- this.timeoutIds[validateObj.cause] = setTimeout(async () => {
- if (controller.signal.aborted) return rawResolve(undefined)
- try {
- rawResolve(
- await this.runValidator({
- validate: validateObj.validate,
- value: {
- value: field.store.state.value,
- fieldApi: field,
- signal: controller.signal,
- validationSource: 'field',
- },
- type: 'validateAsync',
- }),
- )
- } catch (e) {
- rawReject(e)
- }
- }, validateObj.debounceMs)
+ this.timeoutIds.validations[validateObj.cause] = setTimeout(
+ async () => {
+ if (controller.signal.aborted) return rawResolve(undefined)
+ try {
+ rawResolve(
+ await this.runValidator({
+ validate: validateObj.validate,
+ value: {
+ value: field.store.state.value,
+ fieldApi: field,
+ signal: controller.signal,
+ validationSource: 'field',
+ },
+ type: 'validateAsync',
+ }),
+ )
+ } catch (e) {
+ rawReject(e)
+ }
+ },
+ validateObj.debounceMs,
+ )
})
} catch (e: unknown) {
rawError = e as ValidationError
@@ -1633,10 +1624,7 @@ export class FieldApi<
}
this.validate('blur')
- this.options.listeners?.onBlur?.({
- value: this.state.value,
- fieldApi: this,
- })
+ this.triggerOnBlurListener()
}
/**
@@ -1654,6 +1642,50 @@ export class FieldApi<
}) as never,
)
}
+
+ private triggerOnBlurListener() {
+ const debounceMs = this.options.listeners?.onBlurDebounceMs
+
+ if (debounceMs && debounceMs > 0) {
+ if (this.timeoutIds.listeners.blur) {
+ clearTimeout(this.timeoutIds.listeners.blur)
+ }
+
+ this.timeoutIds.listeners.blur = setTimeout(() => {
+ this.options.listeners?.onBlur?.({
+ value: this.state.value,
+ fieldApi: this,
+ })
+ }, debounceMs)
+ } else {
+ this.options.listeners?.onBlur?.({
+ value: this.state.value,
+ fieldApi: this,
+ })
+ }
+ }
+
+ private triggerOnChangeListener() {
+ const debounceMs = this.options.listeners?.onChangeDebounceMs
+
+ if (debounceMs && debounceMs > 0) {
+ if (this.timeoutIds.listeners.change) {
+ clearTimeout(this.timeoutIds.listeners.change)
+ }
+
+ this.timeoutIds.listeners.change = setTimeout(() => {
+ this.options.listeners?.onChange?.({
+ value: this.state.value,
+ fieldApi: this,
+ })
+ }, debounceMs)
+ } else {
+ this.options.listeners?.onChange?.({
+ value: this.state.value,
+ fieldApi: this,
+ })
+ }
+ }
}
function normalizeError(rawError?: ValidationError) {
diff --git a/packages/form-core/src/types.ts b/packages/form-core/src/types.ts
index 7dacf8b42..7875a0f92 100644
--- a/packages/form-core/src/types.ts
+++ b/packages/form-core/src/types.ts
@@ -10,6 +10,11 @@ export type ValidationSource = 'form' | 'field'
*/
export type ValidationCause = 'change' | 'blur' | 'submit' | 'mount' | 'server'
+/**
+ * @private
+ */
+export type ListenerCause = 'change' | 'blur' | 'submit' | 'mount'
+
/**
* @private
*/
diff --git a/packages/form-core/tests/FieldApi.spec.ts b/packages/form-core/tests/FieldApi.spec.ts
index 8175718f4..6d8ed17d4 100644
--- a/packages/form-core/tests/FieldApi.spec.ts
+++ b/packages/form-core/tests/FieldApi.spec.ts
@@ -1890,4 +1890,68 @@ describe('field api', () => {
expect(field.getMeta().errors).toStrictEqual([])
expect(form.state.canSubmit).toBe(true)
})
+
+ it('should debounce onChange listener', async () => {
+ vi.useFakeTimers()
+ const form = new FormApi({
+ defaultValues: {
+ name: '',
+ },
+ })
+
+ form.mount()
+
+ const onChangeMock = vi.fn()
+ const field = new FieldApi({
+ form,
+ name: 'name',
+ listeners: {
+ onChange: onChangeMock,
+ onChangeDebounceMs: 500,
+ },
+ })
+
+ field.mount()
+
+ field.handleChange('first')
+ field.handleChange('second')
+ expect(onChangeMock).not.toHaveBeenCalled()
+
+ await vi.advanceTimersByTimeAsync(500)
+ expect(onChangeMock).toHaveBeenCalledTimes(1)
+ expect(onChangeMock).toHaveBeenCalledWith({
+ value: 'second',
+ fieldApi: field,
+ })
+ })
+
+ it('should debounce onBlur listener', async () => {
+ vi.useFakeTimers()
+ const form = new FormApi({
+ defaultValues: {
+ name: '',
+ },
+ })
+
+ form.mount()
+
+ const onBlurMock = vi.fn()
+ const field = new FieldApi({
+ form,
+ name: 'name',
+ listeners: {
+ onBlur: onBlurMock,
+ onBlurDebounceMs: 300,
+ },
+ })
+
+ field.mount()
+
+ field.handleBlur()
+ field.handleBlur()
+ expect(onBlurMock).not.toHaveBeenCalled()
+
+ await vi.advanceTimersByTimeAsync(300)
+ expect(onBlurMock).toHaveBeenCalledTimes(1)
+ })
})