Skip to content

Commit d7cb9b4

Browse files
committed
fix: react reexports core, sync + async validation, debouncing
1 parent aa92d20 commit d7cb9b4

File tree

7 files changed

+209
-88
lines changed

7 files changed

+209
-88
lines changed

docs/core/reference/fieldApi.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,20 @@ An object type representing the options for a field in a form.
2525
- An optional validation function for the field.
2626
- `validatePristine?: boolean`
2727
- An optional flag indicating whether to validate the field when it is pristine (untouched).
28-
- `filterValue?: (value: TData) => TData`
29-
- An optional function to filter the field value before setting it in the form state.
3028
- `defaultMeta?: Partial<FieldMeta>`
3129
- An optional object with default metadata for the field.
32-
- `validateOn?: 'change' | 'blur' | 'change-blur' | 'change-submit' | 'blur-submit' | 'submit'`
30+
- `validateOn?: ValidationCause`
3331
- An optional string indicating when to perform field validation.
32+
- `validateAsyncOn?: ValidationCause`
33+
- An optional string indicating when to perform async field validation.
34+
- `validateAsyncDebounceMs?: number`
35+
- If set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds.
36+
37+
### `ValidationCause`
38+
39+
A type representing the cause of a validation event.
40+
41+
- 'change' | 'blur' | 'submit'
3442

3543
### `FieldMeta`
3644

docs/core/reference/formApi.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,14 @@ An object representing the options for a form.
2727
- A function for custom validation logic for the form.
2828
- `debugForm?: boolean`
2929
- A boolean flag to enable or disable form debugging.
30-
- `validatePristine?: boolean`
30+
- `defaultValidatePristine?: boolean`
3131
- A boolean flag to enable or disable validation for pristine fields.
32+
- `defaultValidateOn?: ValidationCause`
33+
- The default minimum cause for a field to be synchronously validated
34+
- `defaultValidateAsyncOn?: ValidationCause`
35+
- The default minimum cause for a field to be asynchronously validated
36+
- `defaultValidateAsyncDebounceMs?: number`
37+
- 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.
3238

3339
### `FormApi<TFormData>`
3440

examples/react/simple/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@
1111
<body>
1212
<noscript>You need to enable JavaScript to run this app.</noscript>
1313
<div id="root"></div>
14-
<script type="module" src="/src/index.jsx"></script>
14+
<script type="module" src="/src/index.tsx"></script>
1515
</body>
1616
</html>

examples/react/simple/src/index.jsx renamed to examples/react/simple/src/index.tsx

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
import React from "react";
22
import ReactDOM from "react-dom/client";
3-
import { useForm } from "@tanstack/react-form";
3+
import { useForm, FieldApi } from "@tanstack/react-form";
4+
5+
function FieldInfo({ field }: { field: FieldApi<any, any> }) {
6+
return (
7+
<>
8+
{field.state.meta.touchedError ? (
9+
<em>{field.state.meta.touchedError}</em>
10+
) : null}{" "}
11+
{field.state.meta.isValidating ? "Validating..." : null}
12+
</>
13+
);
14+
}
415

516
export default function App() {
617
const form = useForm({
@@ -12,8 +23,9 @@ export default function App() {
1223
}),
1324
[]
1425
),
15-
onSubmit: (values) => {
26+
onSubmit: async (values) => {
1627
// Do something with form data
28+
console.log(values);
1729
},
1830
});
1931

@@ -27,14 +39,20 @@ export default function App() {
2739
<form.Field
2840
name="firstName"
2941
validate={(value) => !value && "A first name is required"}
42+
validateAsyncOn="change"
43+
validateAsyncDebounceMs={500}
44+
validateAsync={async (value) => {
45+
await new Promise((resolve) => setTimeout(resolve, 1000));
46+
return (
47+
value.includes("error") && 'No "error" allowed in first name'
48+
);
49+
}}
3050
children={(field) => (
3151
// Avoid hasty abstractions. Render props are great!
3252
<>
3353
<label htmlFor={field.name}>First Name:</label>
3454
<input name={field.name} {...field.getInputProps()} />
35-
{field.state.meta.touchedError && (
36-
<em>{field.state.meta.touchedError}</em>
37-
)}
55+
<FieldInfo field={field} />
3856
</>
3957
)}
4058
/>
@@ -46,9 +64,7 @@ export default function App() {
4664
<>
4765
<label htmlFor={field.name}>Last Name:</label>
4866
<input name={field.name} {...field.getInputProps()} />
49-
{field.state.meta.touchedError && (
50-
<em>{field.state.meta.touchedError}</em>
51-
)}
67+
<FieldInfo field={field} />
5268
</>
5369
)}
5470
/>
@@ -66,5 +82,5 @@ export default function App() {
6682
);
6783
}
6884

69-
const rootElement = document.getElementById("root");
85+
const rootElement = document.getElementById("root")!;
7086
ReactDOM.createRoot(rootElement).render(<App />);

0 commit comments

Comments
 (0)