SWCore
SWCore / Componentes / Upload de arquivo

Upload de arquivo Componentes

Área de arrastar o arquivo ou clicar, com miniatura das fotos, limite de quantidade e de tamanho. <div sw-upload sw-upload-accept='image/*'>.

O que é

É o campo de anexar arquivo, só que bonito e fácil: em vez do botão cinza "Escolher arquivo" do navegador, aparece uma área tracejada onde a pessoa arrasta as fotos/documentos ou clica para escolher. As fotos escolhidas aparecem em miniatura, cada uma com um × para tirar. Você coloca sw-upload numa <div> e diz, em atributos, que tipo de arquivo aceita, quantos e de que tamanho.

O JavaScript do núcleo esconde o <input type="file"> de dentro da div (ou cria um, se não houver) e monta no lugar a área de arraste, a fila de miniaturas e a linha de erro. Arquivo de tipo fora do sw-upload-accept (escolhido ou arrastado), maior que o permitido, ou além da quantidade máxima, é recusado com uma mensagem em vermelho. Ele não envia nada para o servidor sozinho: ele guarda a lista e você pega com SW.Upload.getFiles() na hora de enviar.

Quando usar

  • Formulário de contato / orçamento com anexo (planta, foto do problema, currículo).
  • Painel admin: fotos do produto, galeria do imóvel, imagens do post.
  • Cadastro: foto de perfil, documento, comprovante — um arquivo só.
  • Área do cliente: mandar arquivos para aprovação (artes, contratos em PDF).

Comece aqui

  1. 1

    Coloque o SWCore na página: CSS no <head> e JS no fim do <body>. O segundo CSS traz os ícones — sem ele o desenho da imagem no meio da área não aparece.

    <link rel="stylesheet" href="https://swcore.sanweb.com.br/dist/2.1.0/swcore.min.css">
    <link rel="stylesheet" href="https://swcore.sanweb.com.br/dist/2.1.0/swcore.compl.min.css">
    
    <!-- fim do <body> -->
    <script src="https://swcore.sanweb.com.br/dist/2.1.0/swcore.min.js"></script>
  2. 2

    Escreva a div com sw-upload e um <input type="file"> dentro. Arraste uma foto do seu computador para a área abaixo, ou clique nela.

    <div sw-upload sw-upload-accept="image/*">
      <input type="file">
    </div>
  3. 3

    Na hora de enviar, pegue os arquivos com SW.Upload.getFiles() e mande com fetch.

    const zona = document.querySelector('[sw-upload]');
    const dados = new FormData();
    SW.Upload.getFiles(zona).forEach((arq) => dados.append('fotos[]', arq));
    await fetch('/enviar-fotos', { method: 'POST', body: dados });

Todas as variações

Cada quadro abaixo é o componente de verdade, rodando. O código embaixo é exatamente o que está no quadro: copie e cole.

1. Tipo de arquivo

sw-upload-accept diz o que a janela "Escolher arquivo" mostra. Use o mesmo formato do accept do HTML: image/* (qualquer imagem), .pdf, .pdf,.docx… Sem ele, aceita qualquer arquivo. Foto vira miniatura; outros arquivos viram um quadrinho com o nome.

Só imagens — image/* <div sw-upload sw-upload-accept="image/*"><input type="file"></div>
Só PDF e Word <div sw-upload sw-upload-accept=".pdf,.doc,.docx"><input type="file"></div>
Imagens JPG e PNG <div sw-upload sw-upload-accept=".jpg,.jpeg,.png"><input type="file"></div>
Qualquer arquivo (sem accept) <div sw-upload><input type="file"></div>

2. Quantidade

sw-upload-max é o número máximo de arquivos. Com 1, a janela só deixa escolher um. Sem ele, não tem limite de quantidade.

Um arquivo só — sw-upload-max="1" <div sw-upload sw-upload-max="1" sw-upload-accept="image/*"><input type="file"></div>
Até 3 arquivos <div sw-upload sw-upload-max="3" sw-upload-accept="image/*"><input type="file"></div>
Até 10 arquivos <div sw-upload sw-upload-max="10" sw-upload-accept="image/*"><input type="file"></div>
Sem limite (sem max) <div sw-upload sw-upload-accept="image/*"><input type="file"></div>

3. Tamanho máximo de cada arquivo

sw-upload-size é o tamanho máximo em bytes (1 MB = 1048576). O valor aparece escrito embaixo do texto da área. Sem ele, o máximo é 10 MB. Tente soltar um arquivo grande aqui para ver a mensagem de erro.

1 MB — sw-upload-size="1048576" <div sw-upload sw-upload-size="1048576"><input type="file"></div>
5 MB — sw-upload-size="5242880" <div sw-upload sw-upload-size="5242880"><input type="file"></div>
Padrão — 10 MB <div sw-upload><input type="file"></div>
50 MB — vídeos <div sw-upload sw-upload-size="52428800" sw-upload-accept="video/*"><input type="file"></div>

4. Texto da área

sw-upload-txt troca a frase do meio. Pode usar <strong> para destacar uma parte. Sem ele, aparece "Arraste ou clique aqui".

Padrão <div sw-upload><input type="file"></div>
Texto próprio <div sw-upload sw-upload-txt="Solte as fotos do imóvel aqui"><input type="file"></div>
Texto com destaque <div sw-upload sw-upload-txt="Anexe seu currículo <strong>em PDF</strong>" sw-upload-accept=".pdf"> <input type="file"> </div>
Sem o input dentro (ele cria sozinho) <div sw-upload sw-upload-txt="Clique para anexar"></div>

Tabela de opções

PalavraO que fazExemplo
Ligar
sw-uploadNa <div> que vira a área de upload. Dentro, um <input type="file"> (opcional — se faltar, ele cria).<div sw-upload><input type="file"></div>
Regras
sw-upload-acceptTipos aceitos na janela de escolher arquivo. Mesmo formato do accept do HTML. Padrão: qualquer um (ou o accept que já estiver no input).sw-upload-accept="image/*"
sw-upload-maxQuantidade máxima de arquivos. 1 = um só. Padrão: sem limite.sw-upload-max="3"
sw-upload-sizeTamanho máximo de cada arquivo, em bytes. Padrão: 10 MB (10485760).sw-upload-size="5242880"
Texto
sw-upload-txtA frase no meio da área. Aceita <strong>. Padrão: "Arraste ou clique aqui".sw-upload-txt="Solte as fotos aqui"
Visual (automático)
is-ovClasse que a área ganha enquanto um arquivo está sendo arrastado por cima: borda e fundo na cor primária.

Receitas prontas — usos reais

Situações que aparecem em quase todo site. Copie a que servir.

Formulário de orçamento com anexo Ao vivo
<form sw-frm id="orcamento">
  <div sw-fld>
    <label for="nome">Seu nome</label>
    <input sw-inp id="nome" name="nome">
  </div>
  <div sw-fld>
    <label>Fotos do ambiente (até 5)</label>
    <div sw-upload sw-upload-accept="image/*" sw-upload-max="5" sw-upload-size="5242880"
         sw-upload-txt="Arraste as fotos do cômodo ou <strong>clique aqui</strong>">
      <input type="file">
    </div>
  </div>
  <button type="submit" sw-btn="pri">Pedir orçamento</button>
</form>

<script>
  const form = document.getElementById('orcamento');
  form.addEventListener('submit', async (e) => {
    e.preventDefault();
    const dados = new FormData(form);
    SW.Upload.getFiles(form.querySelector('[sw-upload]'))
      .forEach((foto) => dados.append('fotos[]', foto));
    await fetch('/orcamento', { method: 'POST', body: dados });
  });
</script>
Foto de perfil (um arquivo só, até 2 MB) Ao vivo
<div sw-fld>
  <label>Sua foto</label>
  <div sw-upload sw-upload-max="1" sw-upload-accept=".jpg,.jpeg,.png,.webp"
       sw-upload-size="2097152" sw-upload-txt="Escolha uma foto de rosto">
    <input type="file">
  </div>
</div>
Contando os arquivos com os eventos Ao vivo

Nenhuma foto ainda.

<div sw-upload id="fotos-produto" sw-upload-accept="image/*" sw-upload-txt="Fotos do produto">
  <input type="file">
</div>
<p id="info">Nenhuma foto ainda.</p>

<script>
  const zona = document.getElementById('fotos-produto');
  const info = document.getElementById('info');
  function contar() {
    const total = SW.Upload.getFiles(zona).length;
    info.textContent = total ? total + ' foto(s) na fila.' : 'Nenhuma foto ainda.';
  }
  zona.addEventListener('sw:upload:add', contar);
  zona.addEventListener('sw:upload:remove', contar);
</script>
Envio de documentos (PDF) na área do cliente Ao vivo
<div sw-upload sw-upload-accept=".pdf" sw-upload-max="3" sw-upload-size="10485760"
     sw-upload-txt="Solte aqui o contrato assinado <strong>(PDF)</strong>">
  <input type="file">
</div>

Eventos

sw:upload:add
Disparado na div [sw-upload] depois que a pessoa escolhe ou solta arquivos. e.detail.files traz a lista inteira que está na fila (não só os novos). Só dispara quando pelo menos um arquivo entrou; se todos foram recusados, aparece só a mensagem de erro.
sw:upload:remove
Disparado quando a pessoa clica no × de um arquivo. e.detail.index é a posição (começando em 0) do que saiu.

API (JavaScript)

SW.Upload.getFiles(el)
Devolve a lista de arquivos na fila (objetos File, prontos para FormData). el pode ser o elemento ou um seletor como "#fotos". Sem arquivos, devolve lista vazia.
SW.Upload.initAll(raiz)
Monta as áreas [sw-upload] dentro de raiz que ainda não foram montadas. O núcleo já faz isso sozinho.

Precisa de quê

  • swcore.min.css + swcore.min.js — a área, a fila e as regras.
  • swcore.compl.min.css — o ícone de imagem no meio da área (sem ele, só o texto aparece).
  • Um servidor que receba os arquivos (PHP, Node…). O componente só escolhe e mostra.

Cuidados — erros comuns

  • Enviar o formulário do jeito comum e esperar que os arquivos vão juntos: arquivos arrastados não entram no <input>. Sempre monte o envio com SW.Upload.getFiles() + FormData, como na receita.
  • Escrever o tamanho em MB (sw-upload-size="5"): o número é em bytes. 5 MB = 5242880.
  • Confiar no sw-upload-accept como segurança: ele recusa na tela (também o arquivo arrastado), mas quem garante mesmo é o servidor. Confira o tipo lá também.
  • Colocar o sw-upload direto no <input>: ele vai na div em volta.

O que ele não faz

  • Não envia os arquivos, não mostra barra de progresso de envio e não redimensiona fotos — isso é com o seu código/servidor.
  • Não tem função pública para limpar a fila; recarregar o formulário ou recriar a div resolve.
  • Não mostra o tamanho nem o ícone do tipo de arquivo no quadrinho de documentos — só o nome.