componentes / upload
Upload
Área para escolher arquivos clicando ou arrastando, com filtro de tipos aceitos.
Como usar
O Upload só **captura** os arquivos: listar, validar o tamanho e enviar para um servidor ficam com você. `onFilesChange` recebe `File[]` puro com os arquivos recém-escolhidos, não a soma com os anteriores, então junte-os no seu próprio estado para acumular. É um `<input type="file">` de verdade escondido só visualmente (Tab para focar, Enter ou Espaço para abrir), e o `accept` também filtra arquivos arrastados, o que o navegador não faz sozinho. Sem `multiple`, só o primeiro arquivo da seleção é mantido. Valide sempre de novo no servidor.
preview
- Nenhum arquivo ainda
Upload.tsx
import { Upload } from "vaiperui"; const [files, setFiles] = useState<File[]>([]); <Upload multiple accept=".pdf,image/*" label="Anexos" description="PDF ou imagem, até 5 MB" onFilesChange={(chosen) => setFiles((current) => [...current, ...chosen])}/>Tamanhos
preview
tamanhos.tsx
<Upload size="sm" onFilesChange={...} /><Upload size="md" onFilesChange={...} /><Upload size="lg" onFilesChange={...} />Cores
A cor aparece ao passar o mouse, ao arrastar e no foco do teclado.
preview
cores.tsx
<Upload variantColor="primary" onFilesChange={...} /><Upload variantColor="success" onFilesChange={...} /><Upload variantColor="warning" onFilesChange={...} /><Upload variantColor="danger" onFilesChange={...} />Tipos aceitos
preview
aceitos.tsx
<Upload accept=".pdf" description="PDF" /><Upload accept="image/*" multiple description="Images" />Estados
preview
Detalhe extra
O arquivo precisa ser um PDF
estados.tsx
<Upload label="..." helperText="..." /><Upload label="..." errorMessage="..." /><Upload label="..." disabled />Cor personalizada
preview
cor-personalizada.tsx
<Upload customColor="#ff6600" onFilesChange={...} />Props
| Prop | Valores | Padrão | Descrição |
|---|---|---|---|
| onFilesChange | (files: File[]) => void | obrigatório | Chamado com os arquivos recém-escolhidos (não a soma com os anteriores) |
| title | ReactNode | "Drag files here or click to choose" | Texto principal da área |
| description | ReactNode | nenhum | Texto de apoio, ex.: formatos aceitos e tamanho |
| accept | string | nenhum | Tipos aceitos: .pdf, image/*, image/png, separados por vírgula. Também filtra arquivos arrastados |
| multiple | boolean | false | Aceita vários arquivos. Sem ele, só o primeiro da seleção é mantido |
| label / helperText | string | nenhum | Rótulo acima da área e texto de ajuda abaixo |
| errorMessage | string | nenhum | Texto de erro; só a presença dele já força o estado de erro (borda vermelha, aria-invalid) |
| disabled | boolean | false | Bloqueia clique e arraste |
| name | string | nenhum | Nome do campo para um <form> nativo (arquivos soltos são copiados para o input) |
| variantColor | primary | success | warning | danger | primary | Cor do estado marcado e do anel de foco |
| customColor | string | { light, dark } | nenhum | Qualquer cor CSS (ou um par por tema). Substitui o variantColor |
| size | sm | md | lg | md | Tamanho do controle e do texto |
| animation | none | smooth | fast | bounce | smooth | Transição ao alternar |
| radius | none | sm | md | lg | full | lg | Arredondamento dos cantos da área |
| (nativas) | InputHTMLAttributes<HTMLInputElement> | nenhum | checked, defaultChecked, onChange, name, value, disabled, required, aria-*, className, ref etc. |
Acessibilidade
- Um `<input type="file">` nativo (oculto visualmente) é o controle real; a área tracejada é um `<label htmlFor>` dele.
- O input recebe foco e o anel de foco aparece na área de soltar (`peer-focus-visible`), então o foco por teclado fica visível.
- O nome acessível é o texto de `title` dentro da área, mais o `label` quando você passa um (o input tem os dois rótulos).
- `errorMessage` define `aria-invalid="true"`; `aria-describedby` aponta para o erro, ou para o `helperText` quando não há erro.
- Arrastar e soltar é um caminho extra: usuários de teclado e leitor de tela abrem o seletor do sistema pelo input nativo. O ícone de upload é `aria-hidden`.
Teclado
| Tecla | Ação |
|---|---|
| Tab | Foca o input de arquivo. |
| Enter / Space | Abre o seletor de arquivos do sistema (comportamento nativo do input). |
Tenha em mente
- Arquivos recusados por `accept` são descartados em silêncio, sem mensagem nem live region; valide e avise o usuário via `errorMessage`.
- Os arquivos escolhidos não são listados pelo componente; renderize a lista você mesmo e deixe-a acessível a tecnologias assistivas.