Form
React Hook Form + Zod, with labels, help text and errors wired for you.
React Hook Form + Zod, with labels, help text and errors wired for you.
The same component at all four levels. Pick the one that fits your project; they share tokens, so they mix.
npm i junco @junco/tailwind react-hook-form zod @hookform/resolversimport { Form, FormField, FormSubmit, FormRootError, useForm } from "junco/form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { Input } from "junco";
const schema = z.object({ email: z.email("Enter a valid email") });
function Signup() {
const form = useForm({ resolver: zodResolver(schema), defaultValues: { email: "" } });
return (
<Form form={form} onSubmit={save}>
<FormField name="email" label="Email" description="We never share it.">
<Input type="email" />
</FormField>
<FormSubmit>Save</FormSubmit>
</Form>
);
}Submit it empty to see the errors. Every Junco control is wired automatically: labels, help text, errors and aria.
Form#A <form> bound to react-hook-form. Also takes every <form> attribute.
formonSubmitonError| Prop | Type | Default |
|---|---|---|
formRequired. The object from useForm(). | UseFormReturn | – |
onSubmitRequired. Runs with valid values. FormSubmit shows a spinner while it's pending. | (values) => void | Promise | – |
onErrorRuns when validation fails. | (errors) => void | – |
FormField#Renders Junco's Field (label, help text, error) around one control and binds it to the form.
namelabeldescriptionisRequired / isDisabledchildrenrenderlayout| Prop | Type | Default |
|---|---|---|
nameRequired. Field name in the form values (typed). | string | – |
labelThe label. | ReactNode | – |
descriptionHelp text under the control. | ReactNode | – |
isRequired / isDisabledRequired marker and disabled state. | boolean | – |
childrenOne Junco control: Input, Textarea, Select, Checkbox, Switch or RadioGroup. | ReactElement | – |
renderFor any other control. Spread groupProps on custom groups so the label names them. | ({ field, fieldState, groupProps }) => ReactElement | – |
layoutLabel above, or beside the control. | "stacked" | "inline" | inline for Checkbox and Switch |
FormSubmit#A Junco Button with type="submit". Takes every Button prop.
isLoading| Prop | Type | Default |
|---|---|---|
isLoadingOverride the automatic loading state. | boolean | while submitting |
FormRootError#Shows the error set with form.setError("root", { message }), e.g. a failed request. Announced when it appears.
className| Prop | Type | Default |
|---|---|---|
classNameExtra classes. | string | – |
| Key | Action |
|---|---|
| Enter | Submits the form from a text field. |
| Tab | Moves between fields in order. After a failed submit, focus moves to the first invalid text field. |