Form
Ponte entre o react-hook-form e o Field: liga cada campo ao estado do formulário mantendo a amarração de acessibilidade automática.
Instalação
Recebe correções por update de versão. O caminho recomendado.
npm i @trdr/ui
import { Form } from "@trdr/ui/form"Uso
import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel } from "@trdr/ui/form"
export function Exemplo() {
return <Form />
}Props
FormItemPropsestende Omit<FieldProps, "id" | "invalid">FormLabelPropsestende FieldLabelPropsFormControlPropsestende FieldControlPropsFormDescriptionPropsestende FieldDescriptionPropsFormMessagePropsestende FieldErrorPropsForm
A ponte entre o react-hook-form e o Field. Liga cada campo ao estado do formulário (valor,
validação, erro) sem duplicar a amarração de acessibilidade que o Field já resolve: FormItem
renderiza um Field por baixo, e FormLabel/FormControl/FormDescription/FormMessage são
FieldLabel/FieldControl/FieldDescription/FieldError com uma camada fina de tradução do
estado do react-hook-form.
Quando usar
- Qualquer formulário com validação: boleta de ordem, cadastro, preferências. O par natural é
react-hook-form(estado e validação) +zod(schema) +@hookform/resolvers(a ponte entre os dois), as três únicas dependências além da base que este componente pode usar. - Quando o formulário precisa mostrar erro por campo, desabilitar o botão de envio durante validação, ou reagir a mudança de valor de um campo para outro.
Quando não usar
- Formulário de um campo só, sem validação (ex. busca): um
Fieldisolado (ou sóInputcomaria-label) já resolve, sem a sobrecarga doreact-hook-form. - Como camada de estilo:
Formnão estiliza nada por conta própria, ele só liga estado a acessibilidade. O visual continua sendo doField/Input/Buttonpor baixo.
Anatomia
<Form {...form}> FormProvider do react-hook-form
<form onSubmit={form.handleSubmit(...)}>
<FormField control={form.control} name="ativo" render={({ field }) => (
<FormItem> Field por baixo: gera id, computa aria-describedby/invalid
<FormLabel> FieldLabel + cor de erro quando invalido
<FormControl> FieldControl (Slot): id/aria-* no <Input {...field}/>
<Input {...field} />
<FormDescription> FieldDescription
<FormMessage /> FieldError, com a mensagem do zod quando ha erro
</FormItem>
)} />
</form>
</Form>O hook useFormField
Usado internamente por FormLabel/FormControl/FormDescription/FormMessage, e também
exportado para quem precisar montar uma parte customizada da UI do formulário sem perder a
amarração: devolve { id, name, formItemId, formDescriptionId, formMessageId, error, ...resto do fieldState }. Só funciona dentro do par <FormField> (dá o nome do campo) + <FormItem> (dá o
id): usado fora de um dos dois, lança um erro explicando qual está faltando.
Acessibilidade
- Toda a amarração (
htmlFor,aria-describedby,aria-invalid) é a mesma doField:Formnão reimplementa nada disso, só alimenta oinvaliddoFielda partir dofieldState.errordoreact-hook-form. FormMessagemostra a mensagem de validação dozodautomaticamente (error.message), comrole="alert"herdado doFieldError.childrenfunciona como texto de reforço quando o erro existe mas não temmessage(caso raro de erro definido manualmente viaform.setError).FormLabelganhadata-errore a cortext-content-errorquando o campo está inválido, reforçando visualmente o que o leitor de tela já anuncia poraria-invalid.
Slots e tokens
Todo elemento renderizado carrega um data-slot para estilizar partes internas sem depender de classe da biblioteca. Os tokens listados são extraídos do código fonte.
[data-slot="form-control"][data-slot="form-description"][data-slot="form-item"][data-slot="form-label"][data-slot="form-message"]1 tokens usados
text-content-error