Tema
BaseFileItem
Mostra um arquivo anexado: memória de cálculo, planilha, fotos da obra. Diz o tipo, o nome e o tamanho, acompanha o envio e deixa remover.
planilha-vencedora-cf001.xlsx
fotos-pavimento-2.jpg
Envio de fotos-pavimento-2.jpg
Uso
- Use numa lista de anexos, abaixo da área de envio ou na aba de anexos de uma medição.
- O nome é o do arquivo, com a extensão. Não encurte: nomes longos quebram linha.
metacompleta o tamanho com quem enviou e quando: "Paulo Ramos · 20/10".- Com
href, o nome vira um link que abre o arquivo. Enquanto envia, com erro ou desabilitado, o nome é só texto. - Com
removable, aparece o botão de remover. Ele emiteremove; quem tira o arquivo da lista é a tela. Durante o envio, a tela também cancela a requisição ao receberremove; o botão continua se chamando "Remover" e o nome do arquivo. - Vários arquivos ficam numa lista (
<ul>), umBaseFileItempor<li>. - Solta na tela, como a lista abaixo da área de envio, a linha tem borda: ela mesma é o bloco.
- Dentro de um cartão, de uma célula de tabela ou de outro bloco com borda, use
flush. A linha perde a borda, o fundo e o espaço interno e passa a ser uma linha do cartão, que fica com a única borda. Ícone, nome, tamanho e botões continuam iguais.
Anatomia
- Ícone do tipo: escolhido pela extensão de
name. - Nome do arquivo: texto, ou link quando há
hrefe o envio terminou. - Tamanho e meta:
bytesem KB ou MB, seguido demeta. - Barra de envio: só com
uploading, com o percentual deprogress. - Mensagem de erro: só com
invalid, com o texto deinvalid-text. - Botão de remover: só com
removable.
Tipos de arquivo
memoria-calculo.pdf
fachada-norte.jpg
cronograma-fisico-financeiro.xlsx
relatorio-fiscalizacao.docx
planta-baixa-pavimento-2.dwg
projeto-completo.zip
LEIAME
| Extensões | Ícone e cor |
|---|---|
pdf | PDF, vermelho |
jpg, jpeg, png, gif, webp, heic, heif, bmp, tif, tiff, svg | Imagem, azul |
xls, xlsx, xlsm, ods, csv | Planilha, verde |
doc, docx, odt, rtf; txt, md, xml, json; ppt, pptx, odp | Documento, texto ou apresentação, azul de seleção |
dwg, dxf, dwf, rvt, ifc, skp | Projeto, neutro |
zip, rar, 7z, tar, gz | Compactado, neutro |
mp4, mov, avi, mkv, webm | Vídeo, neutro |
| Outras ou sem extensão | Arquivo genérico, neutro |
A cor nunca vem sozinha: cada tipo tem um ícone de forma diferente, e a extensão está no nome.
Situações
fotos-pavimento-2.jpg
Envio de fotos-pavimento-2.jpg
fotos-pavimento-3.jpg
Envio de fotos-pavimento-3.jpg
memoria-calculo-completa.pdf
Erro: O arquivo passa de 20 MB. Divida em partes menores.
memoria-calculo-28.pdf
| Situação | Como |
|---|---|
| Enviado | Padrão. Nome, tamanho e, com href, link para abrir |
| Enviando | uploading com progress de 0 a 100. Sem progress, a barra anima e diz "Enviando" |
| Erro | invalid com invalid-text, que diz o que deu errado e o que fazer. Sem texto, aparece "Não foi possível enviar o arquivo." O erro vence o envio |
| Desabilitado | disabled: o botão de remover não responde e o nome perde o link, como num formulário já enviado |
Sem borda, dentro de um cartão
Planta baixa do 2º pavimento
| Onde a linha fica | Variante |
|---|---|
| Solta na tela, na aba de anexos ou abaixo da área de envio | Padrão, com borda |
Dentro de um BaseCard, de uma célula de BaseDataTable ou de outro bloco com borda | flush, sem borda |
Com flush, a linha não tem borda, fundo nem espaço interno em nenhuma situação. O ícone do tipo, a barra de envio e a mensagem de erro continuam, então a situação do arquivo continua à vista.
Tamanhos
memoria-calculo-29.pdf
memoria-calculo-29.pdf
Use sm em painéis laterais e tabelas, onde a lista divide espaço com outros dados.
Tamanho do arquivo
O tamanho vem em bytes (bytes) e aparece em português, na base 1024, como os limites de envio costumam ser escritos: 120 B, 812 KB, 2,4 MB, 3,3 GB. KB não tem casa decimal; MB e acima têm uma.
Faça e não faça
| Faça | Não faça |
|---|---|
| Mostrar o nome inteiro do arquivo, com a extensão: "memoria-calculo-medicao-29.pdf". | Encurtar o nome com reticências. |
Usar flush dentro de um cartão ou de uma tabela: a borda do cartão é a única. | Pôr a linha com borda dentro de um cartão, caixa dentro de caixa, ou trocar a linha por texto e perder o ícone e o tamanho. |
| Dizer no erro o que fazer: "O arquivo passa de 20 MB. Envie um PDF menor." | Deixar só "Erro" na linha do anexo. |
| Levar o foco para o próximo anexo depois de remover um. | Deixar o foco sumir quando a linha sai da lista. |
Estilo
| Propriedade | Token |
|---|---|
| Fundo | --tj-layer-01; enviando --tj-layer-02; desabilitado --tj-field-disabled; flush sem fundo, sobre o do cartão |
| Borda | --tj-border-subtle-02 (1 px); erro --tj-support-error-text; flush sem borda |
| Raio | --tj-radius-md (8 px); ícone sm com --tj-radius-sm; a linha flush sem raio |
| Espaço interno | --tj-space-3 (12 px); sm com --tj-space-2 (8 px); flush sem espaço interno |
| Ícone do tipo | Caixa de 36 px (sm: --tj-icon-lg, 24 px) com glifo --tj-icon-md, 20 px (sm: --tj-icon-sm). O protótipo v3 usa 18 px; aqui o glifo segue a escala de ícones do sistema. PDF --tj-support-error-subtle e -text; imagem --tj-support-info-*; planilha --tj-support-success-*; documentos --tj-layer-selected-01 com --tj-link-primary; os demais --tj-layer-accent-01 com --tj-text-secondary |
| Nome | --tj-text-md (o protótipo herda o tamanho do texto; aqui ele é fixo para a linha não mudar com o contêiner), --tj-weight-medium, --tj-text-primary; link --tj-link-primary, hover e pressionado --tj-link-primary-hover; sm com --tj-text-sm |
| Tamanho e meta | --tj-text-xs, --tj-text-helper, números tabulares |
| Erro | --tj-support-error-text, --tj-text-xs, --tj-weight-medium, com ícone |
| Barra de envio | BaseProgress sm |
| Foco | Contorno sólido de 2 px --tj-border-interactive, afastado 2 px, no link e no botão. O --tj-ring translúcido fica abaixo de 3:1 sobre o fundo branco da linha |
| Movimento | Borda com --tj-duration-fast-02 e --tj-easing-standard; sem transição com movimento reduzido |
| Alto contraste | Borda CanvasText; com erro, um contorno interno de 1 px reforça a borda sem mover a linha. Com flush, nem borda nem contorno. Foco com contorno Highlight |
Código
vue
<ul class="list-unstyled d-grid gap-2">
<li v-for="attachment in attachments" :key="attachment.id">
<BaseFileItem
:name="attachment.name"
:bytes="attachment.bytes"
:href="attachment.url"
:uploading="attachment.uploading"
:progress="attachment.progress"
:invalid="Boolean(attachment.error)"
:invalid-text="attachment.error"
removable
@remove="removeAttachment(attachment)"
/>
</li>
</ul>Propriedades
| Propriedade | Tipo | Padrão | Descrição |
|---|---|---|---|
name | string | obrigatória | Nome do arquivo com a extensão. A extensão escolhe o ícone |
bytes | number | — | Tamanho em bytes, mostrado como "812 KB" ou "2,4 MB" |
meta | string | — | Texto depois do tamanho, como "Paulo Ramos · 20/10" |
href | string | — | Transforma o nome em link para abrir o arquivo; ignorado enviando, com erro ou desabilitado |
removable | boolean | false | Mostra o botão de remover |
disabled | boolean | false | Desabilita o botão de remover e tira o link |
uploading | boolean | false | Mostra a barra de envio |
progress | number | — | Percentual do envio, de 0 a 100; sem ele, a barra é indeterminada |
invalid | boolean | false | O envio ou a validação falhou |
invalidText | string | — | O que deu errado e o que fazer. Padrão: "Não foi possível enviar o arquivo." |
size | 'sm' | 'md' | 'md' | Densidade da linha |
flush | boolean | false | Tira a borda, o fundo e o espaço interno, para a linha ficar dentro de um cartão, de uma célula de tabela ou de outro bloco com borda |
Evento: remove, sem dados, ao clicar no botão de remover.
Acessibilidade
- Não há padrão do WAI-ARIA APG para a linha de um arquivo. Ela junta um link, um botão e uma região que anuncia mudanças.
- Teclado:
| Tecla | O que faz |
|---|---|
| Tab | Vai para o link do nome, quando existe, e depois para o botão de remover |
| Enter | No link, abre o arquivo; no botão, remove |
| Espaço | No botão, remove |
Desabilitado, o nome perde o link e o botão de remover sai da ordem do Tab, como um botão nativo desabilitado.
- O botão de remover é um
<button>nativo comaria-label"Remover " e o nome do arquivo, para cada botão de uma lista ter um nome diferente. Enter e Espaço acionam. - Com erro, o botão de remover é descrito pela mensagem de erro (
aria-describedby): quem chega nele pelo Tab ouve o que deu errado. - Depois de remover, a linha some e o foco se perderia. A tela deve levar o foco para o próximo arquivo, para o anterior ou, se a lista ficar vazia, para o botão de enviar.
- O ícone do tipo é decorativo (
aria-hidden); o tipo está na extensão do nome. - A barra de envio é um
BaseProgresscom o nome "Envio de " e o arquivo, escondido na tela e lido pelo leitor de tela, com valor emaria-valuenow. Semprogress, não há valor e o leitor de tela ouve "Enviando". - Uma região
aria-live="polite"anuncia só as mudanças de situação de uma linha que já está na tela, com o nome do arquivo: "fotos-pavimento-2.jpg: envio concluído", "memoria.pdf: Erro. O arquivo passa de 20 MB." Uma nova mensagem de erro na mesma linha também é anunciada. Linhas que já nascem enviadas não são lidas; linhas que já nascem com erro (um arquivo recusado ao ser solto) são anunciadas logo depois de aparecer. O avanço do percentual não é anunciado, para não interromper. - O erro tem ícone, texto e borda; a cor nunca é o único sinal. Com
flush, sem a borda, o ícone e o texto continuam dizendo o erro. A mensagem começa com "Erro: " escondido na tela, para quem lê a página com o leitor de tela e para a descrição do botão de remover. - O link e o botão mostram um contorno de foco sólido, com 3:1 sobre o fundo da linha, que continua visível no alto contraste do Windows. O link tem sublinhado, além da cor.
- Nomes longos quebram linha em vez de serem cortados, então o nome inteiro continua legível com zoom de 400%.
- Testado com axe nas situações e combinações listadas no teste: enviado, com link e botão, enviando, com erro, desabilitado (também com erro e enviando), nos dois tamanhos, com
flushdentro de um cartão, e depois de um anúncio. O contraste vem dos tokens de função, que mantêm AA nos dois temas; o jsdom não calcula cores.