-
-
Notifications
You must be signed in to change notification settings - Fork 359
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: set field errors from the form validators (#656)
* Set field errors from the form's validators * Fix some failing tests * Fix a test (comment to be added later) * Fix another test * Shameful new line * Update "pnpm-lock.yaml" after the rebase again * ci: apply automated fixes * Fix the sherif tests * Update "pnpm-lock.yaml" after the rebase again * Fix some type errors * Fix a failing test after the rebase * Update the field-errors-from-form-validators examples * Reorganize the code a bit * Update the docs * Update pnpm-lock.yaml * Rebase again * ci: apply automated fixes * Remove the doc pages that will be autogenerated * Clean up the code * Clean up the code around fake timers * Clean up the tests * Update the FieldApi tests * Update the field-errors-from-form-validators example * Fix an example in the docs * chore: fix minor issues with demo * docs: update docs * chore: fix pnpm * ci: apply automated fixes * chore: fix sherif --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Corbin Crutchley <[email protected]>
- Loading branch information
1 parent
7c1d2a8
commit de60d5d
Showing
16 changed files
with
1,235 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
examples/react/field-errors-from-form-validators/.eslintrc.cjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// @ts-check | ||
|
||
/** @type {import('eslint').Linter.Config} */ | ||
const config = { | ||
extends: ['plugin:react/recommended', 'plugin:react-hooks/recommended'], | ||
rules: { | ||
'react/no-children-prop': 'off', | ||
}, | ||
} | ||
|
||
module.exports = config |
27 changes: 27 additions & 0 deletions
27
examples/react/field-errors-from-form-validators/.gitignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# production | ||
/build | ||
|
||
pnpm-lock.yaml | ||
yarn.lock | ||
package-lock.json | ||
|
||
# misc | ||
.DS_Store | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
|
||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Example | ||
|
||
To run this example: | ||
|
||
- `npm install` | ||
- `npm run dev` |
18 changes: 18 additions & 0 deletions
18
examples/react/field-errors-from-form-validators/index.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<link rel="icon" type="image/svg+xml" href="/emblem-light.svg" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
<meta name="theme-color" content="#000000" /> | ||
|
||
<title> | ||
TanStack Form React Field Errors From Form Validators Example App | ||
</title> | ||
</head> | ||
<body> | ||
<noscript>You need to enable JavaScript to run this app.</noscript> | ||
<div id="root"></div> | ||
<script type="module" src="/src/index.tsx"></script> | ||
</body> | ||
</html> |
34 changes: 34 additions & 0 deletions
34
examples/react/field-errors-from-form-validators/package.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
{ | ||
"name": "@tanstack/field-errors-from-form-validators", | ||
"private": true, | ||
"type": "module", | ||
"scripts": { | ||
"dev": "vite --port=3001", | ||
"build": "vite build", | ||
"preview": "vite preview", | ||
"test:types": "tsc" | ||
}, | ||
"dependencies": { | ||
"@tanstack/react-form": "^0.29.2", | ||
"react": "^18.3.1", | ||
"react-dom": "^18.3.1" | ||
}, | ||
"devDependencies": { | ||
"@types/react": "^18.3.3", | ||
"@types/react-dom": "^18.3.0", | ||
"@vitejs/plugin-react": "^4.3.1", | ||
"vite": "^5.4.2" | ||
}, | ||
"browserslist": { | ||
"production": [ | ||
">0.2%", | ||
"not dead", | ||
"not op_mini all" | ||
], | ||
"development": [ | ||
"last 1 chrome version", | ||
"last 1 firefox version", | ||
"last 1 safari version" | ||
] | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
examples/react/field-errors-from-form-validators/public/emblem-light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
134 changes: 134 additions & 0 deletions
134
examples/react/field-errors-from-form-validators/src/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
import { useForm } from '@tanstack/react-form' | ||
import * as React from 'react' | ||
import { createRoot } from 'react-dom/client' | ||
|
||
async function sleep(ms: number) { | ||
return new Promise((resolve) => { | ||
setTimeout(resolve, ms) | ||
}) | ||
} | ||
|
||
async function verifyAgeOnServer(age: number) { | ||
await sleep(Math.floor(Math.random() * 1000)) | ||
return age <= 13 | ||
} | ||
|
||
async function checkIfUsernameIsTaken(name: string) { | ||
await sleep(Math.floor(Math.random() * 500)) | ||
const usernames = ['user-1', 'user-2', 'user-3'] | ||
return !usernames.includes(name) | ||
} | ||
|
||
export default function App() { | ||
const form = useForm({ | ||
defaultValues: { | ||
username: '', | ||
age: 0, | ||
}, | ||
validators: { | ||
onSubmitAsync: async ({ value }) => { | ||
const [isRightAge, isUsernameAvailable] = await Promise.all([ | ||
// Verify the age on the server | ||
verifyAgeOnServer(value.age), | ||
// Verify the availability of the username on the server | ||
checkIfUsernameIsTaken(value.username), | ||
]) | ||
|
||
if (!isRightAge || !isUsernameAvailable) { | ||
return { | ||
// The `form` key is optional | ||
form: 'Invalid data', | ||
fields: { | ||
...(!isRightAge ? { age: 'Must be 13 or older to sign' } : {}), | ||
...(!isUsernameAvailable | ||
? { username: 'Username is taken' } | ||
: {}), | ||
}, | ||
} | ||
} | ||
|
||
return null | ||
}, | ||
}, | ||
}) | ||
|
||
return ( | ||
<div> | ||
<h1>Field Errors From The Form's validators Example</h1> | ||
<form | ||
onSubmit={(e) => { | ||
e.preventDefault() | ||
e.stopPropagation() | ||
void form.handleSubmit() | ||
}} | ||
> | ||
<form.Field | ||
name="username" | ||
validators={{ | ||
onSubmit: ({ value }) => (!value ? 'Required field' : null), | ||
}} | ||
children={(field) => ( | ||
<div> | ||
<label htmlFor={field.name}>Username:</label> | ||
<input | ||
id={field.name} | ||
name={field.name} | ||
value={field.state.value} | ||
onChange={(e) => { | ||
field.handleChange(e.target.value) | ||
}} | ||
/> | ||
{field.state.meta.errors.length > 0 ? ( | ||
<em role="alert">{field.state.meta.errors.join(', ')}</em> | ||
) : null} | ||
</div> | ||
)} | ||
/> | ||
|
||
<form.Field | ||
name="age" | ||
validators={{ | ||
onSubmit: ({ value }) => (!value ? 'Required field' : null), | ||
}} | ||
children={(field) => ( | ||
<div> | ||
<label htmlFor={field.name}>Age:</label> | ||
<input | ||
id={field.name} | ||
name={field.name} | ||
value={field.state.value} | ||
type="number" | ||
onChange={(e) => field.handleChange(e.target.valueAsNumber)} | ||
/> | ||
{field.state.meta.errors.length > 0 ? ( | ||
<em role="alert">{field.state.meta.errors.join(', ')}</em> | ||
) : null} | ||
</div> | ||
)} | ||
/> | ||
<form.Subscribe | ||
selector={(state) => [state.errorMap]} | ||
children={([errorMap]) => | ||
errorMap.onSubmit ? ( | ||
<div> | ||
<em>There was an error on the form: {errorMap.onSubmit}</em> | ||
</div> | ||
) : null | ||
} | ||
/> | ||
<form.Subscribe | ||
selector={(state) => [state.canSubmit, state.isSubmitting]} | ||
children={([canSubmit, isSubmitting]) => ( | ||
<button type="submit" disabled={!canSubmit}> | ||
{isSubmitting ? '...' : 'Submit'} | ||
</button> | ||
)} | ||
/> | ||
</form> | ||
</div> | ||
) | ||
} | ||
|
||
const rootElement = document.getElementById('root')! | ||
|
||
createRoot(rootElement).render(<App />) |
9 changes: 9 additions & 0 deletions
9
examples/react/field-errors-from-form-validators/tsconfig.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"compilerOptions": { | ||
"jsx": "react", | ||
"noEmit": true, | ||
"strict": true, | ||
"esModuleInterop": true, | ||
"lib": ["DOM", "DOM.Iterable", "ES2020"] | ||
} | ||
} |
Oops, something went wrong.