diff --git a/packages/dev/s2-docs/pages/react-aria/forms.mdx b/packages/dev/s2-docs/pages/react-aria/forms.mdx index a98a8385ee1..465d7c9a560 100644 --- a/packages/dev/s2-docs/pages/react-aria/forms.mdx +++ b/packages/dev/s2-docs/pages/react-aria/forms.mdx @@ -443,7 +443,7 @@ export async function action({request}: Route.ActionArgs) { ## Form libraries -In most cases, uncontrolled forms with the builtin validation features are sufficient. However, if you are building a truly complex form, or integrating React Aria components into an existing form, a separate form library such as [React Hook Form](https://react-hook-form.com/) or [Formik](https://formik.org/) may be helpful. +In most cases, uncontrolled forms with the builtin validation features are sufficient. However, if you are building a truly complex form, or integrating React Aria components into an existing form, a separate form library such as [React Hook Form](https://react-hook-form.com/), [Formik](https://formik.org/), or [Formisch](https://formisch.dev/) may be helpful. ### React Hook Form @@ -496,3 +496,51 @@ function App() { } ``` +### Formisch + +[Formisch](https://formisch.dev/) is a schema-based, headless form library for React. It validates with a [Valibot](https://valibot.dev/) schema and infers all input and output types directly from it. + +Use the `Field` component from Formisch to integrate React Aria components. The render prop provides the current value, error messages, and props for the field. Instead of spreading `field.props`, pass them individually: the ref goes to `inputRef` so Formisch registers the native input element, and `field.onChange` replaces the native change handler because React Aria passes the value instead of the event. The `Form` component from Formisch wraps a native `
` element and calls `onSubmit` with the validated values. + +```tsx +import {Field, Form, useForm} from '@formisch/react'; +import * as v from 'valibot'; +import {TextField} from 'vanilla-starter/TextField'; +import {Button} from 'vanilla-starter/Button'; + +const FormSchema = v.object({ + name: v.pipe(v.string(), v.nonEmpty('Name is required.')) +}); + +function App() { + let form = useForm({schema: FormSchema}); + let onSubmit = (output) => { + // Call your API here... + }; + + return ( + + + {(field) => ( + + )} + + +
+ ); +} +``` +