Skip to content

Commit

Permalink
fix: react reexports core, sync + async validation, debouncing
Browse files Browse the repository at this point in the history
  • Loading branch information
tannerlinsley committed Apr 26, 2023
1 parent aa92d20 commit d7cb9b4
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 88 deletions.
14 changes: 11 additions & 3 deletions docs/core/reference/fieldApi.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,20 @@ An object type representing the options for a field in a form.
- An optional validation function for the field.
- `validatePristine?: boolean`
- An optional flag indicating whether to validate the field when it is pristine (untouched).
- `filterValue?: (value: TData) => TData`
- An optional function to filter the field value before setting it in the form state.
- `defaultMeta?: Partial<FieldMeta>`
- An optional object with default metadata for the field.
- `validateOn?: 'change' | 'blur' | 'change-blur' | 'change-submit' | 'blur-submit' | 'submit'`
- `validateOn?: ValidationCause`
- An optional string indicating when to perform field validation.
- `validateAsyncOn?: ValidationCause`
- An optional string indicating when to perform async field validation.
- `validateAsyncDebounceMs?: number`
- If set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds.

### `ValidationCause`

A type representing the cause of a validation event.

- 'change' | 'blur' | 'submit'

### `FieldMeta`

Expand Down
8 changes: 7 additions & 1 deletion docs/core/reference/formApi.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,14 @@ An object representing the options for a form.
- A function for custom validation logic for the form.
- `debugForm?: boolean`
- A boolean flag to enable or disable form debugging.
- `validatePristine?: boolean`
- `defaultValidatePristine?: boolean`
- A boolean flag to enable or disable validation for pristine fields.
- `defaultValidateOn?: ValidationCause`
- The default minimum cause for a field to be synchronously validated
- `defaultValidateAsyncOn?: ValidationCause`
- The default minimum cause for a field to be asynchronously validated
- `defaultValidateAsyncDebounceMs?: number`
- 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.

### `FormApi<TFormData>`

Expand Down
2 changes: 1 addition & 1 deletion examples/react/simple/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="/src/index.jsx"></script>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import React from "react";
import ReactDOM from "react-dom/client";
import { useForm } from "@tanstack/react-form";
import { useForm, FieldApi } from "@tanstack/react-form";

function FieldInfo({ field }: { field: FieldApi<any, any> }) {
return (
<>
{field.state.meta.touchedError ? (
<em>{field.state.meta.touchedError}</em>
) : null}{" "}
{field.state.meta.isValidating ? "Validating..." : null}
</>
);
}

export default function App() {
const form = useForm({
Expand All @@ -12,8 +23,9 @@ export default function App() {
}),
[]
),
onSubmit: (values) => {
onSubmit: async (values) => {
// Do something with form data
console.log(values);
},
});

Expand All @@ -27,14 +39,20 @@ export default function App() {
<form.Field
name="firstName"
validate={(value) => !value && "A first name is required"}
validateAsyncOn="change"
validateAsyncDebounceMs={500}
validateAsync={async (value) => {
await new Promise((resolve) => setTimeout(resolve, 1000));
return (
value.includes("error") && 'No "error" allowed in first name'
);
}}
children={(field) => (
// Avoid hasty abstractions. Render props are great!
<>
<label htmlFor={field.name}>First Name:</label>
<input name={field.name} {...field.getInputProps()} />
{field.state.meta.touchedError && (
<em>{field.state.meta.touchedError}</em>
)}
<FieldInfo field={field} />
</>
)}
/>
Expand All @@ -46,9 +64,7 @@ export default function App() {
<>
<label htmlFor={field.name}>Last Name:</label>
<input name={field.name} {...field.getInputProps()} />
{field.state.meta.touchedError && (
<em>{field.state.meta.touchedError}</em>
)}
<FieldInfo field={field} />
</>
)}
/>
Expand All @@ -66,5 +82,5 @@ export default function App() {
);
}

const rootElement = document.getElementById("root");
const rootElement = document.getElementById("root")!;
ReactDOM.createRoot(rootElement).render(<App />);
Loading

0 comments on commit d7cb9b4

Please sign in to comment.