componentes / formulário
Form
Passe um schema do Zod e valide os campos sem adicionar outra biblioteca de formulário.
553 B gzip client componentbase ui · form
form-zod.tsx
"use client";
import { useState } from "react";
import { z } from "zod";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Field, FieldError, FieldLabel } from "@/components/ui/field";
import { Form } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
const schema = z.object({
name: z.string().trim().min(2, "enter at least 2 letters."),
email: z.email("that email doesn't look valid."),
password: z.string().min(8, "the password needs 8 characters or more."),
terms: z.literal(true, "accept the terms to continue."),
});
export default function FormZod() {
const [created, setCreated] = useState<string | null>(null);
return (
<Form
className="w-full max-w-sm"
onSubmit={async (values) => {
// `values` is already validated and typed: { name: string; email: string; password: string; terms: true }
await new Promise((r) => setTimeout(r, 800));
setCreated(values.name);
}}
schema={schema}
>
<Field name="name">
<FieldLabel>name</FieldLabel>
<Input autoComplete="name" />
<FieldError />
</Field>
<Field name="email">
<FieldLabel>email</FieldLabel>
<Input autoComplete="email" inputMode="email" />
<FieldError />
</Field>
<Field name="password">
<FieldLabel>password</FieldLabel>
<Input autoComplete="new-password" type="password" />
<FieldError />
</Field>
<Field name="terms">
<FieldLabel className="flex items-center gap-2 font-normal">
<Checkbox /> I accept the terms of use
</FieldLabel>
<FieldError />
</Field>
<Button type="submit" variant="brand">
create account
</Button>
{created && (
<p aria-live="polite" className="text-sm">
account created, {created}!
</p>
)}
</Form>
);
}Instalação
$ npx shadcn@latest add https://cd-ui.vercel.app/r/form.jsonprimeira vez? configure o components.json e o tema antes: veja instalação.
Uso
import { z } from "zod"
import { Form } from "@/components/ui/form"
import { Field, FieldError, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
const schema = z.object({ email: z.email("invalid email") })
<Form schema={schema} onSubmit={(values) => save(values)}>
<Field name="email">
<FieldLabel>email</FieldLabel>
<Input inputMode="email" />
<FieldError />
</Field>
</Form>API
Form
Base UI · Form<form> com validação por schema. Usa só o núcleo do Zod (zod/v4/core), então aceita schemas de zod e de zod/mini.
| prop | tipo | padrão |
|---|---|---|
schemaSchema do Zod. Cada | ZodObject | - |
onSubmitSó roda com dados válidos, já convertidos e tipados. | (values: z.output<schema>) => void | Promise<void> | - |
validationModeQuando cada campo valida. | "onSubmit" | "onBlur" | "onChange" | "onBlur" |
errorsErros vindos de fora (ex.: resposta do servidor). | Record<string, string | string[]> | - |
classNameClasses extras, mescladas com | string | - |
Acessibilidade
- Erros aparecem no
FieldErrorde cada campo e ficam ligados ao controle poraria-describedby. - Ao enviar com erro, o foco vai para o primeiro campo inválido (comportamento do Base UI).
- Com schema, prefira
inputMode="email"atype="email": o tipo nativo faz o navegador mostrar a mensagem dele (no idioma do sistema) no lugar da do schema.