Form
Padrão de formulário composto via Field (sem form.tsx).
Campos e formulárioscomposição
Carregando demonstração…
Código da demo
"use client";
import * as React from "react";
import { Button } from "@/components/ui/button";
import {
Field,
FieldDescription,
FieldError,
FieldGroup,
FieldLabel,
FieldLegend,
FieldSet,
} from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
export function Demo() {
const [name, setName] = React.useState("");
const [bio, setBio] = React.useState("");
const [saved, setSaved] = React.useState(false);
const [error, setError] = React.useState<string | null>(null);
return (
<form
className="w-full max-w-md"
noValidate
onSubmit={(e) => {
e.preventDefault();
if (!name.trim()) {
setError("Informe um nome.");
setSaved(false);
return;
}
setError(null);
setSaved(true);
}}
>
<FieldSet>
<FieldLegend>Perfil</FieldLegend>
<FieldDescription>Estado local — sem backend.</FieldDescription>
<FieldGroup>
<Field data-invalid={error ? true : undefined}>
<FieldLabel htmlFor="form-name" required>
Nome
</FieldLabel>
<Input
id="form-name"
required
value={name}
aria-invalid={error ? true : undefined}
aria-describedby={error ? "form-name-error" : undefined}
onChange={(e) => {
setName(e.target.value);
setSaved(false);
if (error) setError(null);
}}
/>
{error ? (
<FieldError id="form-name-error">{error}</FieldError>
) : (
<FieldDescription>Como você quer ser chamado.</FieldDescription>
)}
</Field>
<Field>
<FieldLabel htmlFor="form-bio">Bio</FieldLabel>
<Textarea
id="form-bio"
value={bio}
onChange={(e) => {
setBio(e.target.value);
setSaved(false);
}}
/>
</Field>
<Button type="submit">Salvar</Button>
{saved ? (
<p className="fe-caption text-success">Salvo localmente.</p>
) : null}
</FieldGroup>
</FieldSet>
</form>
);
}Use
- FieldSet e FieldLegend para agrupar; uma coluna em tela estreita.
- Um único botão de envio primário, no fim.
- Diga o que falta quando o envio não é possível.
Não use
- Não desabilite o envio sem explicar o motivo.
- Não peça dado que o produto não usa.
- Acessibilidade
- Labels, erros e agrupamento semântico com FieldSet.
- Importar
Composição do app — não é exportada pelo pacote.
Neste repositório:
import { Field, FieldLabel, FieldGroup } from "@/components/ui/field"