Componentes
14. Upload
seed-componentes.md v1.43 · §14seção 16 de 9814-upload-estavel-validado-pelo-rafael-em-2026-08.md · MD5 f0457307Título completo no canon: 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#
- 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. ✅