Skip to content

Commit

Permalink
Merge branch 'main' into pr/ogawa0071/855
Browse files Browse the repository at this point in the history
  • Loading branch information
Balastrong committed Aug 27, 2024
2 parents 7be7568 + 179a323 commit 606e988
Show file tree
Hide file tree
Showing 52 changed files with 2,158 additions and 965 deletions.
103 changes: 103 additions & 0 deletions docs/framework/react/guides/validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,109 @@ export default function App() {
}
```

### Setting field-level errors from the form's validators

You can set errors on the fields from the form's validators. One common use case for this is validating all the fields on submit by calling a single API endpoint in the form's `onSubmitAsync` validator.

```tsx
export default function App() {
const form = useForm({
defaultValues: {
age: 0,
},
validators: {
onSubmitAsync: async ({ value }) => {
// Verify the age on the server
const isOlderThan13 = await verifyAgeOnServer(value.age)
if (!isOlderThan13) {
return {
form: 'Invalid data', // The `form` key is optional
fields: {
age: 'Must be 13 or older to sign',
},
}
}

return null
},
},
})

return (
<div>
<form
onSubmit={(e) => {
e.preventDefault()
e.stopPropagation()
void form.handleSubmit()
}}
>
<form.Field name="age">
{(field) => (
<>
<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 ? (
<em role="alert">{field.state.meta.errors.join(', ')}</em>
) : null}
</>
)}
</form.Field>
<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>
</div>
)
}
```

> Something worth mentioning is that if you have a form validation function that returns an error, that error may be overwritten by the field-specific validation.
>
> This means that:
>
> ```jsx
> const form = useForm({
> defaultValues: {
> age: 0,
> },
> validators: {
> onChange: ({ value }) => {
> return {
> fields: {
> age: value.age < 12 ? 'Too young!' : undefined,
> },
> }
> },
> },
> })
>
> // ...
>
> return <form.Field
> name="age"
> validators={{
> onChange: ({ value }) => value % 2 === 0 ? 'Must be odd!' : undefined,
> }}
> />
> ```
>
> Will only show `'Must be odd!` even if the 'Too young!' error is returned by the form-level validation.
## Asynchronous Functional Validation
While we suspect most validations will be synchronous, there are many instances where a network call or some other async operation would be useful to validate against.
Expand Down
6 changes: 3 additions & 3 deletions examples/angular/array/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
"@angular/platform-browser": "^17.3.12",
"@angular/platform-browser-dynamic": "^17.3.12",
"@angular/router": "^17.3.12",
"@tanstack/angular-form": "^0.29.2",
"@tanstack/angular-form": "^0.30.0",
"rxjs": "^7.8.1",
"tslib": "^2.6.3",
"zone.js": "^0.14.10"
"tslib": "^2.7.0",
"zone.js": "^0.15.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^17.3.8",
Expand Down
6 changes: 3 additions & 3 deletions examples/angular/simple/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
"@angular/platform-browser": "^17.3.12",
"@angular/platform-browser-dynamic": "^17.3.12",
"@angular/router": "^17.3.12",
"@tanstack/angular-form": "^0.29.2",
"@tanstack/angular-form": "^0.30.0",
"rxjs": "^7.8.1",
"tslib": "^2.6.3",
"zone.js": "^0.14.10"
"tslib": "^2.7.0",
"zone.js": "^0.15.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^17.3.8",
Expand Down
10 changes: 5 additions & 5 deletions examples/angular/valibot/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
"@angular/platform-browser": "^17.3.12",
"@angular/platform-browser-dynamic": "^17.3.12",
"@angular/router": "^17.3.12",
"@tanstack/angular-form": "^0.29.2",
"@tanstack/valibot-form-adapter": "^0.29.2",
"@tanstack/angular-form": "^0.30.0",
"@tanstack/valibot-form-adapter": "^0.30.0",
"rxjs": "^7.8.1",
"tslib": "^2.6.3",
"valibot": "^0.37.0",
"zone.js": "^0.14.10"
"tslib": "^2.7.0",
"valibot": "^0.39.0",
"zone.js": "^0.15.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^17.3.8",
Expand Down
8 changes: 4 additions & 4 deletions examples/angular/yup/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
"@angular/platform-browser": "^17.3.12",
"@angular/platform-browser-dynamic": "^17.3.12",
"@angular/router": "^17.3.12",
"@tanstack/angular-form": "^0.29.2",
"@tanstack/yup-form-adapter": "^0.29.2",
"@tanstack/angular-form": "^0.30.0",
"@tanstack/yup-form-adapter": "^0.30.0",
"rxjs": "^7.8.1",
"tslib": "^2.6.3",
"tslib": "^2.7.0",
"yup": "^1.4.0",
"zone.js": "^0.14.10"
"zone.js": "^0.15.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^17.3.8",
Expand Down
8 changes: 4 additions & 4 deletions examples/angular/zod/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
"@angular/platform-browser": "^17.3.12",
"@angular/platform-browser-dynamic": "^17.3.12",
"@angular/router": "^17.3.12",
"@tanstack/angular-form": "^0.29.2",
"@tanstack/zod-form-adapter": "^0.29.2",
"@tanstack/angular-form": "^0.30.0",
"@tanstack/zod-form-adapter": "^0.30.0",
"rxjs": "^7.8.1",
"tslib": "^2.6.3",
"tslib": "^2.7.0",
"zod": "^3.23.8",
"zone.js": "^0.14.10"
"zone.js": "^0.15.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^17.3.8",
Expand Down
4 changes: 2 additions & 2 deletions examples/lit/simple/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
"test:types": "tsc"
},
"dependencies": {
"@tanstack/lit-form": "^0.29.2",
"@tanstack/lit-form": "^0.30.0",
"lit": "^3.2.0"
},
"devDependencies": {
"vite": "^5.4.1"
"vite": "^5.4.2"
},
"browserslist": {
"production": [
Expand Down
4 changes: 2 additions & 2 deletions examples/lit/ui-libraries/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
},
"dependencies": {
"@material/web": "^1.5.1",
"@tanstack/lit-form": "^0.29.2",
"@tanstack/lit-form": "^0.30.0",
"lit": "^3.2.0"
},
"devDependencies": {
"vite": "^5.4.1"
"vite": "^5.4.2"
},
"browserslist": {
"production": [
Expand Down
4 changes: 2 additions & 2 deletions examples/react/array/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@
"test:types": "tsc"
},
"dependencies": {
"@tanstack/react-form": "^0.29.2",
"@tanstack/react-form": "^0.30.0",
"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.1"
"vite": "^5.4.2"
},
"browserslist": {
"production": [
Expand Down
11 changes: 11 additions & 0 deletions examples/react/field-errors-from-form-validators/.eslintrc.cjs
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 examples/react/field-errors-from-form-validators/.gitignore
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*
6 changes: 6 additions & 0 deletions examples/react/field-errors-from-form-validators/README.md
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 examples/react/field-errors-from-form-validators/index.html
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 examples/react/field-errors-from-form-validators/package.json
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.30.0",
"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"
]
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 606e988

Please sign in to comment.