Skip to content

Commit

Permalink
Merge pull request #1 from TanStack/main
Browse files Browse the repository at this point in the history
feat: add docs
  • Loading branch information
tobySolutions authored Dec 30, 2024
2 parents 469713d + 3e88918 commit 72dbdd1
Show file tree
Hide file tree
Showing 193 changed files with 13,120 additions and 7,698 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/autofix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/[email protected].1
uses: actions/[email protected].2
- name: Setup Tools
uses: tanstack/config/.github/setup@main
- name: Fix formatting
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20.15.1
22.12.0
2 changes: 1 addition & 1 deletion codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ coverage:
status:
project:
default:
target: 90%
target: auto
threshold: 1%
27 changes: 27 additions & 0 deletions docs/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@
"label": "Linked Fields",
"to": "framework/react/guides/linked-fields"
},
{
"label": "Listeners",
"to": "framework/react/guides/listeners"
},
{
"label": "UI Libraries",
"to": "framework/react/guides/ui-libraries"
Expand Down Expand Up @@ -433,6 +437,21 @@
}
]
},
{
"label": "Community Resources",
"children": [],
"frameworks": [
{
"label": "react",
"children": [
{
"label": "Balastrong's Tutorial",
"to": "framework/react/community/balastrong-tutorial"
}
]
}
]
},
{
"label": "Examples",
"children": [],
Expand All @@ -452,6 +471,10 @@
"label": "TanStack Query Integration",
"to": "framework/react/examples/query-integration"
},
{
"label": "Standard Schema",
"to": "framework/react/examples/standard-schema"
},
{
"label": "Yup",
"to": "framework/react/examples/yup"
Expand All @@ -472,6 +495,10 @@
"label": "Next Server Actions",
"to": "framework/react/examples/next-server-actions"
},
{
"label": "Remix",
"to": "framework/react/examples/remix"
},
{
"label": "UI Libraries",
"to": "framework/react/examples/ui-libraries"
Expand Down
50 changes: 45 additions & 5 deletions docs/framework/angular/guides/basic-concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,21 @@ export class AppComponent {
}
```

## Validation Adapters
## Validation with Standard Schema Libraries

In addition to hand-rolled validation options, we also provide adapters like `@tanstack/zod-form-adapter`, `@tanstack/yup-form-adapter`, and `@tanstack/valibot-form-adapter` to enable usage with common schema validation tools like [Zod](https://zod.dev/), [Yup](https://github.com/jquense/yup), and [Valibot](https://valibot.dev/).
In addition to hand-rolled validation options, we also support the [Standard Schema](https://github.com/standard-schema/standard-schema) specification.

You can define a schema using any of the libraries implementing the specification and pass it to a form or field validator.

Supported libraries include:

- [Zod](https://zod.dev/)
- [Valibot](https://valibot.dev/)
- [ArkType](https://arktype.io/)

Example:

```angular-ts
import { zodValidator } from '@tanstack/zod-form-adapter'
import { z } from 'zod'
@Component({
Expand All @@ -132,7 +139,6 @@ import { z } from 'zod'
<ng-container
[tanstackField]="form"
name="firstName"
[validatorAdapter]="zodValidator()"
[validators]="{
onChange: z.string().min(3, 'First name must be at least 3 characters'),
onChangeAsyncDebounceMs: 500,
Expand Down Expand Up @@ -166,7 +172,6 @@ export class AppComponent {
})
z = z
zodValidator = zodValidator
}
```

Expand All @@ -187,6 +192,41 @@ class AppComponent {
}
```

## Listeners

`@tanstack/angular-form` allows you to react to specific triggers and "listen" to them to dispatch side effects.

Example:

```angular-ts
@Component({
selector: 'app-root',
standalone: true,
imports: [TanStackField],
template: `
<ng-container
[tanstackField]="form"
name="country"
[listeners]="{
onChange: onCountryChange
}"
#country="field"
></ng-container>
`,
})
...
onCountryChange: FieldListenerFn<any, any, any, any, string> = ({
value,
}) => {
console.log(`Country changed to: ${value}, resetting province`)
this.form.setFieldValue('province', '')
}
```

More information can be found at [Listeners](./listeners.md)

## Array Fields

Array fields allow you to manage a list of values within a form, such as a list of hobbies. You can create an array field using the `tanstackField` directive.
Expand Down
61 changes: 61 additions & 0 deletions docs/framework/angular/guides/listeners.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
id: listeners
title: Side effects for event triggers
---

For situations where you want to "affect" or "react" to triggers, there's the listener API. For example, if you, as the developer, want to reset a form field as a result of another field changing, you would use the listener API.

Imagine the following user flow:

- User selects a country from a drop-down.
- User then selects a province from another drop-down.
- User changes the selected country to a different one.

In this example, when the user changes the country, the selected province needs to be reset as it's no longer valid. With the listener API, we can subscribe to the onChange event and dispatch a reset to the field "province" when the listener is fired.

Events that can be "listened" to are:

- onChange
- onBlur
- onMount
- onSubmit

```angular-ts
@Component({
selector: 'app-root',
standalone: true,
imports: [TanStackField],
template: `
<ng-container
[tanstackField]="form"
name="country"
[listeners]="{
onChange: onCountryChange
}"
#country="field"
></ng-container>
<ng-container
[tanstackField]="form"
name="province"
#province="field"
></ng-container>
`,
})
export class AppComponent {
form = injectForm({
defaultValues: {
country: '',
province: '',
},
})
onCountryChange: FieldListenerFn<any, any, any, any, string> = ({
value,
}) => {
console.log(`Country changed to: ${value}, resetting province`)
this.form.setFieldValue('province', '')
}
}
```
88 changes: 49 additions & 39 deletions docs/framework/angular/guides/validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -382,24 +382,22 @@ This will debounce every async call with a 500ms delay. You can even override th

> This will run `onChangeAsync` every 1500ms while `onBlurAsync` will run every 500ms.
## Adapter-Based Validation (Zod, Yup, Valibot)
## Validation through Schema Libraries

While functions provide more flexibility and customization over your validation, they can be a bit verbose. To help solve this, there are libraries like [Valibot](https://valibot.dev/), [Yup](https://github.com/jquense/yup), and [Zod](https://zod.dev/) that provide schema-based validation to make shorthand and type-strict validation substantially easier.
While functions provide more flexibility and customization over your validation, they can be a bit verbose. To help solve this, there are libraries that provide schema-based validation to make shorthand and type-strict validation substantially easier. You can also define a single schema for your entire form and pass it to the form level, errors will be automatically propagated to the fields.

Luckily, we support all of these libraries through official adapters:
### Standard Schema Libraries

```bash
$ npm install @tanstack/zod-form-adapter zod
# or
$ npm install @tanstack/yup-form-adapter yup
# or
$ npm install @tanstack/valibot-form-adapter valibot
```
TanStack Form natively supports all libraries following the [Standard Schema specification](https://github.com/standard-schema/standard-schema), most notably:
- [Zod](https://zod.dev/)
- [Valibot](https://valibot.dev/)
- [ArkType](https://arktype.io/)

Once done, we can add the adapter to the `validator` property on the form or field:
*Note:* make sure to use the latest version of the schema libraries as older versions might not support Standard Schema yet.

To use schemas from these libraries you can pass them to the `validators` props as you would do with a custom function:

```angular-ts
import { zodValidator } from '@tanstack/zod-form-adapter'
import { z } from 'zod'
@Component({
Expand All @@ -420,19 +418,18 @@ import { z } from 'zod'
`,
})
export class AppComponent {
form = injectForm({
// Either add the validator here or on `Field`
validatorAdapter: zodValidator(),
form = injectForm({
// ...
})
})
z = z
// ...
}
```

These adapters also support async operations using the proper property names:
Async validations on form and field level are supported as well:


```angular-ts
@Component({
Expand Down Expand Up @@ -469,37 +466,50 @@ export class AppComponent {
}
```

### Form Level Adapter Validation
### Other Schema Libraries

You can also use the adapter at the form level:
We also support [Yup](https://github.com/jquense/yup) through an official adapter:

```typescript
import { zodValidator } from '@tanstack/zod-form-adapter'
import { z } from 'zod'
```bash
$ npm install @tanstack/yup-form-adapter yup
```

// ...
Once done, we can add the adapter to the `validator` property on the form or field:

const form = injectForm({
validatorAdapter: zodValidator(),
validators: {
onChange: z.object({
age: z.number().gte(13, 'You must be 13 to make an account'),
}),
},
})
```
```angular-ts
import { yupValidator } from '@tanstack/yup-form-adapter'
import * as yup from 'yup'
If you use the adapter at the form level, it will pass the validation to the fields of the same name.
@Component({
selector: 'app-root',
standalone: true,
imports: [TanStackField],
template: `
<ng-container
[tanstackField]="form"
name="age"
[validators]="{
onChange: yup.number().moreThan(13, 'You must be 13 to make an account'),
}"
#age="field"
>
<!-- ... -->
</ng-container>
`,
})
export class AppComponent {
form = injectForm({
// Either add the validator here or on `Field`
validatorAdapter: yupValidator(),
// ...
})
This means that:
yup = yup
```html
<ng-container [tanstackField]="form" name="age" #age="field">
<!-- ... -->
</ng-container>
// ...
}
```

Will still display the error message from the form-level validation.

## Preventing invalid forms from being submitted

Expand Down
Loading

0 comments on commit 72dbdd1

Please sign in to comment.