Forms with react-hook-form + zod
Combine Yugen's Field, Input, Select, Checkbox, DatePicker and Button with react-hook-form + zod for fully validated, accessible forms.
react-hook-form, zod and @hookform/resolvers are optional peers. Yugen doesn't depend on them; install them yourself with npm i react-hook-form zod @hookform/resolvers. Input / Select take register(name) directly (the ref points to the native element). Controls that aren't native form elements (DatePicker, Checkbox) use Controller. Map errors to Field with validationState="error" + validationMessage, and Field sets aria-invalid, aria-describedby and role="alert". Put noValidate on the <form> so the browser's own error bubbles don't get in the way; the submit button uses loading={isSubmitting}.
Import
Install from npm, copy the source into your project with @yugen-ui/cli or the shadcn CLI, or import directly when working in this repo.
TSX
// npm install yugen-ui// Tuỳ chọn — tự cài: npm i react-hook-form zod @hookform/resolversimport { Controller, useForm } from "react-hook-form";import { zodResolver } from "@hookform/resolvers/zod";import { z } from "zod";import { Button, Checkbox, DatePicker, Field, Input, Select } from "yugen-ui";Variants
Each tile is a standalone example: hover to copy, or press Code to see the source.
Server errors with setError
Errors the client can't predict (the email already exists) are set with setError(..., { shouldFocus: true }) and show up in the Field right away.
Step 1 of 3 · Sign in
Step 1 of 3: Sign in
Step-by-step validation with Wizard
Each step's validate calls trigger([...the step's fields]), which returns Promise<boolean>. On false, Wizard blocks the step and shows the error.
Usage
Do
- Write the error messages in the zod schema in your users' language and say how to fix the problem (“Password must be at least 8 characters.”).
- Use Controller for DatePicker, Checkbox, Combobox… and pass field.ref so the invalid field can receive focus.
- Validate again on the server, and show server errors with setError on the right field.
Don't
- Don't import react-hook-form / zod into library components. They are a choice made at the app level.
- Don't show errors before people leave a field for the first time (mode "onChange" from the start is annoying).
- Don't disable the submit button while the form is invalid. Let people click it and see the specific errors.
Props
| Prop · Type | Default | Description |
|---|---|---|
| register | Default: — | Spread onto Yugen's Input / Select / Textarea: {...register("email")}. |
| Controllerreact-hook-form | Default: — | For DatePicker (value + onValueChange), Checkbox / Switch (checked + onCheckedChange), Combobox… |
| Field | Default: — | "error" when errors.<name> is set, which puts aria-invalid on the control. |
| Field | Default: — | errors.<name>?.message, shown with role="alert" and linked through aria-describedby. |
| zodResolver | Default: — | Uses the zod schema for validation; z.infer<typeof schema> gives the form value type. |
| trigger | Default: — | Validates part of the form. Use it as WizardStep.validate. |
| Button | Default: — | loading={isSubmitting}: a Spinner replaces the icon, the width stays the same, and aria-busy is set. |