---
fonte: 01-canonicos/seed-componentes.md
versao_da_fonte: v1.43
secao: 14
titulo: "Upload — `estável` · validado pelo Rafael em 2026-08-03 (preview v0.13 + suite de 63 testes)"
sequencia: 16 de 98
bytes_do_corpo: 3637
md5_do_corpo: f04573075ca30123c165a97a4cf3d366
gerado_por: 06-validacao/geradores/gen-camada-ia.py
nota: fatia GERADA — o corpo abaixo é byte a byte o trecho do canônico; edite o canônico, nunca esta fatia. Canônico inteiro em https://ds.seed.eng.br/01-canonicos/seed-componentes.md
---
## 14. Upload — `estável` · validado pelo Rafael em 2026-08-03 (preview v0.13 + suite de 63 testes)

> **Base (3 rodadas):** R1 — GOV.UK file upload (input nativo + "Choose file or drop"; JS como enhancement), Scottish (progress + confirmação), Queensland/NSW (erros; WCAG 2.2 redundant entry: erro NÃO força re-upload do que subiu), VA (variantes), Home Office (erros que sugerem correção). R2 — SaaS patterns (constraints ANTES; progresso real POR arquivo; retry individual; item visível com remover), NN/g drag-drop, react-dropzone/Uppy. R3 — W3C ARIA25 (progressbar + live region), Uploadcare/Carbon issues (anúncios nomeando arquivo), 4.1.3 Status Messages, segurança MIME server-side. N1–N7 conferidas no consolidado.

### 14.1 Papel

Anexar arquivo(s): fatura de energia na captação (o caso SEED nº 1), documentos no ERP, fotos de visita técnica no mobile.

### 14.2 Decisões N1–N7

| # | Decisão | Porquê | Descartado |
|---|---|---|---|
| N1 | Base: `<input type="file">` + rótulo; dropzone é ENHANCEMENT com o botão "Escolher arquivo" SEMPRE dentro — a alternativa 2.5.7 vem de fábrica; dropzone com Enter/Space abrindo o picker | GOV.UK; herda F4/L2 | Dropzone-only (falha 2.5.7 e teclado) |
| N2 | Restrições declaradas ANTES e persistentes no help: "PDF, JPG ou PNG · até 10 MB" (nunca só na rejeição); `accept` correto → celular oferece câmera/galeria; drag omitido graciosamente no toque | SaaS/NSW; Baymard teclados | Descobrir o limite no erro |
| N3 | Arquivo aceito = item visível (nome + tamanho + remover 44px); progresso REAL por arquivo (`role="progressbar"` + live region ARIA25); **retry INDIVIDUAL sem re-enviar o que já subiu** (WCAG 2.2 redundant entry); cancelar durante | NSW/W3C; "usuários não re-tentam, abandonam" | Barra única do lote; recomeço total |
| N4 | Canais §1.13: `role="status"` para enviado/concluído NOMEANDO o arquivo ("proposta.pdf enviado"); `role="alert"` para falha | Uploadcare/Carbon issue: silêncio pós-clique é o bug nº 1 | "Sucesso" sem dizer de quê |
| N5 | Erros específicos com correção: tipo ("fatura.docx não é aceito — envie PDF, JPG ou PNG"), tamanho ("fatura.pdf tem 14 MB — o limite é 10 MB"), rede ("Falha na conexão — tente de novo", com botão) | GOV.UK/QLD/Home Office | "Erro no upload" |
| N6 | Segurança/LGPD: accept/MIME no cliente = UX; validação REAL server-side (MIME de conteúdo, nome sanitizado, limite no servidor); fatura = dado pessoal → finalidade declarada no help da captação ("Usamos sua fatura só para dimensionar o sistema") | R3; LGPD §2.8 minimização | Confiar na extensão |
| N7 | Multi: `<ul>` com estado POR item; máximo declarado ("até 5 arquivos"); "Limpar tudo" | Carbon issue/VA | Contador opaco "3 arquivos" |

### 14.3 Anatomia e tokens

Dropzone: borda 2px TRACEJADA `--seed-field-border` radius 8, padding 24, ícone 24 + "Arraste a fatura aqui ou **Escolher arquivo**" (botão secundário §1 real); estado `dragover`: borda sólida `--seed-action-primary-bg` + `--seed-surface-sunken`. Item: linha com ícone do tipo, nome (truncado ao meio se longo), tamanho em mono, progresso 4px, remover/repetir 44px.

### 14.4 Os 7 testes

1. Tracejado 4.74:1; dragover muda borda E fundo. 2. Estados do item por ícone + texto + cor. 3. Grayscale: tracejado→sólido carrega o dragover. 4. Par item enviando × item com erro (barra × ícone+texto). 5. Uma live region para a fila toda (frases nomeadas). 6. Fila visível com estado por item. 7. Toque: dropzone vira botão grande; câmera via accept; remover 44px. ✅

---

