Field
Agrupa rótulo, controle, descrição e mensagem de erro de um campo de formulário, com a amarração de acessibilidade (htmlFor, aria-describedby, aria-invalid) automática.
Instalação
Recebe correções por update de versão. O caminho recomendado.
npm i @trdr/ui
import { Field } from "@trdr/ui/field"Uso
import { Field, FieldControl, FieldDescription, FieldError, FieldGroup, FieldLabel } from "@trdr/ui/field"
export function Exemplo() {
return <Field />
}Props
FieldPropsestende React.HTMLAttributes<HTMLDivElement>| Prop | Tipo | Descrição |
|---|---|---|
| invalid? | boolean | Estado de invalidacao: liga `aria-invalid` no controle e habilita a `FieldError`. |
| disabled? | boolean | Estado desabilitado, refletido no `FieldLabel` (o `Label` nao inspeciona o controle sozinho). |
| id? | string | id do controle. Quando omitido, gera um id estavel via `useId`. |
FieldLabelPropsestende LabelPropsFieldControlPropsestende React.HTMLAttributes<HTMLElement>FieldDescriptionPropsestende React.HTMLAttributes<HTMLParagraphElement>FieldErrorPropsestende React.HTMLAttributes<HTMLParagraphElement>FieldGroupPropsestende React.HTMLAttributes<HTMLDivElement>FieldSetPropsestende React.FieldsetHTMLAttributes<HTMLFieldSetElement>FieldLegendPropsestende React.HTMLAttributes<HTMLLegendElement>Field
Agrupa rótulo, controle, descrição e mensagem de erro de um campo de formulário. É o componente
que existe para que formulário acessível seja o caminho fácil, não o difícil: quem usa Field
não precisa lembrar de gerar um id, escrever htmlFor à mão, montar aria-describedby nem
ligar aria-invalid no controle certo.
Quando usar
- Sempre que um campo (
input,textarea, ou qualquer controle nativo) precisar de rótulo, ajuda ou mensagem de erro no seu formulário.Fieldsubstitui o padrão manual<div className="flex flex-col gap-xs"><Label/><Input/></div>que os componenteslabeleinputjá documentam como composição básica. - Para agrupar vários campos relacionados sob um título semântico, use
FieldSet+FieldLegend+FieldGrouppor cima de váriosField. - Como base de composição de outro componente: o
form(fora de escopo aqui) usa exatamente estas peças para ligar com oreact-hook-form, em vez de duplicar a amarração de acessibilidade.
Quando não usar
- Para um controle isolado sem rótulo visível (ex. busca compacta com ícone): use
aria-labeldireto no controle, semField. - Como substituto do
input/textarea/label:Fieldnão redesenha esses componentes, só os amarra. A cor de borda de validação (tone) continua sendo escolhida no próprioInput/Textarea;Fieldcuida só da semântica (aria-invalid), não do estilo visual.
Anatomia
<FieldSet> <fieldset>, semântica de grupo, sem chrome do navegador
<FieldLegend> <legend>, título do grupo
<FieldGroup> agrupa vários Field com o espaçamento padrão
<Field> <div>, provedor do Context de amarração
<FieldLabel> <label> (usa o componente Label por baixo)
<FieldControl> Slot: repassa id/aria-describedby/aria-invalid ao filho
<Input> ou <Textarea>
<FieldDescription> <p>, texto de ajuda, opcional
<FieldError> <p role="alert">, só quando invalid e há mensagemProps
Field:invalid(ligaaria-invalidno controle e habilitaFieldError),disabled(reflete noFieldLabel),id(gera um automaticamente viauseIdquando omitido).FieldLabel: todas as props deLabel(required,disabled), maishtmlForopcional para sobrescrever o id gerado peloField.FieldControl: envolve um único filho (o controle real) viaSlot, no mesmo mecanismoasChilddoButton.
Acessibilidade
FieldLabelrecebehtmlForautomaticamente doFieldpai, apontando para oiddo controle dentro doFieldControlmais próximo. UmhtmlForexplícito sempre pode sobrescrever.FieldDescriptioneFieldErrorse registram noFieldquando montam. Oaria-describedbydo controle só referencia os ids que realmente existem no DOM: se você não usarFieldDescription, o controle não aponta para um id inexistente.FieldErrorsó renderiza (e só entra noaria-describedby) quandoFieldestáinvalide há conteúdo. Não é um slot de mensagem genérica: para uma dica sempre visível, useFieldDescription.aria-invalidno controle real vem doField, e sempre pode ser sobrescrito por um valor explícito que o consumidor escrever diretamente no controle (oclassName/prop do filho sempre vence, no mesmo espírito docn()).FieldSet/FieldLegendusam<fieldset>/<legend>nativos: o nome acessível do grupo (rolegroup) vem da legenda, sem precisar dearia-labelmanual.
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="field"][data-slot="field-control"][data-slot="field-description"][data-slot="field-error"][data-slot="field-group"][data-slot="field-label"][data-slot="field-legend"][data-slot="field-set"]5 tokens usados
text-b4text-content-errortext-content-secondarytext-content-tertiarytext-l3