Panel (drawer) Componentes
Painel que desliza da borda da tela — carrinho, filtros, menu no celular, detalhes de um item — pela direita, esquerda, topo ou de baixo.
O que é
Sabe o carrinho que entra pela direita quando você clica em "Ver carrinho", ou os filtros que abrem pela esquerda na loja pelo celular? Isso é o painel (também chamado de "drawer"). Ele aparece por cima da página, escurece o fundo e fecha com o × , com a tecla Esc ou clicando fora. Você escreve o painel uma vez com sw-panel e um id, e coloca sw-panel-open="#id" no botão que abre. Para escolher de onde ele vem e o tamanho, escreva palavras no atributo: sw-panel="lft", sw-panel="bot sm"…
Precisa do CSS e do JavaScript do SWCore (os dois arquivos principais). Ao abrir, o painel trava a rolagem da página de trás, põe o foco dentro dele (quem usa teclado já cai no primeiro botão) e, ao fechar, devolve o foco para o botão que abriu. Em telas com menos de 640 px (celular), ele ocupa sempre a tela toda. Uma página pode ter vários painéis; cada um com seu id.
Quando usar
- Carrinho de compras que abre pela direita sem sair da página —
sw-panel. - Filtros de uma lista (preço, tamanho, cor) no celular —
sw-panel="lft". - Menu do site no celular —
sw-panel="lft sm". - Detalhes de uma linha da tabela no painel admin, sem perder a lista —
sw-panel="lg". - Opções rápidas que sobem de baixo, como "Compartilhar" no celular —
sw-panel="bot". - Para uma pergunta curta que pede resposta ("Excluir mesmo?"), use o Modal, que aparece no centro.
Comece aqui
-
1
Coloque o SWCore na página: o CSS no
<head>e o JavaScript antes de fechar o</body>. O painel precisa dos dois.<link rel="stylesheet" href="https://swcore.sanweb.com.br/dist/2.1.0/swcore.min.css"> <!-- … sua página … --> <script src="https://swcore.sanweb.com.br/dist/2.1.0/swcore.min.js"></script> -
2
Escreva o botão com
sw-panel-open="#id-do-painel"e o painel com o mesmoid. O × precisa desw-panel-closepara fechar.Seu carrinho
2 itens — R$ 348,00
<button sw-btn="pri" sw-panel-open="#carrinho">Ver carrinho</button> <div sw-panel id="carrinho"> <div sw-panel-hdr> <h3>Seu carrinho</h3> <button sw-panel-cls sw-panel-close aria-label="Fechar"></button> </div> <div sw-panel-bdy> <p>2 itens — R$ 348,00</p> </div> </div> -
3
Quer mudar de onde ele vem ou o tamanho? Acrescente palavras: aqui, pela esquerda e estreito.
Menu
Início · Serviços · Contato
<div sw-panel="lft sm" id="menu">…</div>
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. De onde ele vem
Sem palavra de posição ele entra pela direita. Clique para ver cada um.
Direita
<button sw-btn="out" sw-panel-open="#pnl-pos-r">Direita</button>
<div sw-panel id="pnl-pos-r">…</div>
Esquerda
<button sw-btn="out" sw-panel-open="#pnl-pos-l">Esquerda</button>
<div sw-panel="lft" id="pnl-pos-l">…</div>
Topo
<button sw-btn="out" sw-panel-open="#pnl-pos-t">Topo</button>
<div sw-panel="top" id="pnl-pos-t">…</div>
Baixo
<button sw-btn="out" sw-panel-open="#pnl-pos-b">Baixo</button>
<div sw-panel="bot" id="pnl-pos-b">…</div>
2. Tamanhos
O tamanho é a largura (nos painéis da direita/esquerda) ou a altura (topo/baixo). Sem palavra: 450 px. No celular (menos de 640 px) ele ocupa a tela toda, qualquer que seja o tamanho.
sm
<button sw-btn="out" sw-panel-open="#pnl-tam-sm">sm</button>
<div sw-panel="sm" id="pnl-tam-sm">…</div>
Padrão
<button sw-btn="out" sw-panel-open="#pnl-tam-md">Padrão</button>
<div sw-panel id="pnl-tam-md">…</div>
lg
<button sw-btn="out" sw-panel-open="#pnl-tam-lg">lg</button>
<div sw-panel="lg" id="pnl-tam-lg">…</div>
fl
<button sw-btn="out" sw-panel-open="#pnl-tam-fl">fl</button>
<div sw-panel="fl" id="pnl-tam-fl">…</div>
3. Combinando posição e tamanho
Uma palavra de posição + uma de tamanho, na ordem que quiser.
Menu
Serviços
Contato
<button sw-btn="out" sw-panel-open="#pnl-cmb-1">lft sm</button>
<div sw-panel="lft sm" id="pnl-cmb-1">…</div>
Tela cheia
<button sw-btn="out" sw-panel-open="#pnl-cmb-2">bot fl</button>
<div sw-panel="bot fl" id="pnl-cmb-2">…</div>
4. Partes do painel
Todas opcionais. Com cabeçalho e rodapé, só o corpo rola quando o conteúdo é alto — o título e os botões ficam sempre à vista.
Seu carrinho
Camiseta básica — R$ 59,90
Boné — R$ 39,90
Este corpo rola por dentro quando tem muita coisa.
<button sw-btn="pri" sw-panel-open="#carrinho">Abrir painel completo</button>
<div sw-panel id="carrinho">
<div sw-panel-hdr> <!-- cabeçalho: fica fixo em cima -->
<h3>Seu carrinho</h3>
<button sw-panel-cls sw-panel-close aria-label="Fechar"></button>
</div>
<div sw-panel-bdy> <!-- corpo: rola por dentro -->
<p>Camiseta básica — R$ 59,90</p>
<p>Boné — R$ 39,90</p>
</div>
<div sw-panel-ftr> <!-- rodapé: fica fixo embaixo -->
<button sw-btn="pri" sw-panel-close>Finalizar compra</button>
<button sw-btn="ghost sec" sw-panel-close>Continuar comprando</button>
</div>
</div>
Tabela de opções
| Palavra | O que faz | Exemplo |
|---|---|---|
| Posição (valor de sw-panel) | ||
(nenhuma) | Entra pela direita. | <div sw-panel id="x"> |
lft | Entra pela esquerda. | <div sw-panel="lft" id="x"> |
top | Desce do topo, na largura toda. Altura máxima: 85% da tela. | <div sw-panel="top" id="x"> |
bot | Sobe de baixo, na largura toda. Altura máxima: 85% da tela. | <div sw-panel="bot" id="x"> |
| Tamanho (valor de sw-panel) | ||
sm | 240 px. | <div sw-panel="sm" id="x"> |
(nenhum) | 450 px. | |
lg | 640 px. | <div sw-panel="lg" id="x"> |
fl | 100% (tela toda naquela direção). | <div sw-panel="fl" id="x"> |
| Abrir e fechar | ||
sw-panel-open="#id" | No botão ou link de fora: abre o painel daquele id (tem que começar com #). | <button sw-panel-open="#carrinho"> |
sw-panel-close | Em qualquer coisa dentro do painel: clicar fecha. | <button sw-panel-close>Fechar</button> |
Tecla Esc | Fecha o painel aberto. | |
Clique fora | Clicar no fundo escuro (ou fora do painel) fecha. | |
| Partes (atributos dentro do painel) | ||
sw-panel-hdr | Cabeçalho: título à esquerda, × à direita. Fica fixo em cima. | <div sw-panel-hdr> |
sw-panel-bdy | Corpo: ocupa o espaço que sobra e rola por dentro. | <div sw-panel-bdy> |
sw-panel-ftr | Rodapé: botões de ação lado a lado. Fica fixo embaixo. | <div sw-panel-ftr> |
sw-panel-cls | Desenha o × (botão redondo). Junte com sw-panel-close para ele fechar. | <button sw-panel-cls sw-panel-close aria-label="Fechar"></button> |
| Ajuste fino (no CSS da sua página) | ||
--sw-panel-sz | Largura (ou altura, em topo/baixo) exata, em px, rem ou %. | .pnl-filtros { --sw-panel-sz: 360px; } |
--sw-panel-spd | Duração da animação de abrir/fechar. Padrão: 0.35s. | .pnl-filtros { --sw-panel-spd: .6s; } |
Receitas prontas — usos reais
Situações que aparecem em quase todo site. Copie a que servir.
<button sw-btn="suc" sw-panel-open="#carrinho"><i class="swi-cart"></i> Carrinho (2)</button>
<div sw-panel id="carrinho">
<div sw-panel-hdr>
<h3>Carrinho</h3>
<button sw-panel-cls sw-panel-close aria-label="Fechar"></button>
</div>
<div sw-panel-bdy>
<div class="flx j-sb"><span>Camiseta básica (M)</span><span>R$ 59,90</span></div>
<hr sw-div="dsh">
<div class="flx j-sb"><span>Boné preto</span><span>R$ 39,90</span></div>
<hr sw-div>
<div class="flx j-sb"><strong>Total</strong><strong>R$ 99,80</strong></div>
</div>
<div sw-panel-ftr>
<a href="/checkout" sw-btn="suc">Finalizar compra</a>
<button sw-btn="ghost sec" sw-panel-close>Continuar comprando</button>
</div>
</div>
Filtrar produtos
<button sw-btn="out" sw-panel-open="#filtros"><i class="swi-filter"></i> Filtrar</button>
<div sw-panel="lft" id="filtros">
<div sw-panel-hdr>
<h3>Filtrar produtos</h3>
<button sw-panel-cls sw-panel-close aria-label="Fechar"></button>
</div>
<div sw-panel-bdy>
<div sw-fld>
<label for="cat">Categoria</label>
<select sw-inp id="cat"><option>Todas</option><option>Camisetas</option></select>
</div>
<div class="sw-chk-grp">
<label sw-chk><input type="checkbox" checked> Só com frete grátis</label>
<label sw-chk><input type="checkbox"> Só em promoção</label>
</div>
</div>
<div sw-panel-ftr>
<button sw-btn="pri" sw-panel-close>Ver resultados</button>
</div>
</div>
Pedido
Cliente: Maria Souza
Status: pago
<div sw-panel="lg" id="detalhe">
<div sw-panel-hdr>
<h3 id="detalhe-titulo">Pedido</h3>
<button sw-panel-cls sw-panel-close aria-label="Fechar"></button>
</div>
<div sw-panel-bdy id="detalhe-corpo"></div>
</div>
<script>
// chamado ao clicar numa linha da tabela
function abrirPedido(numero) {
document.getElementById('detalhe-titulo').textContent = 'Pedido #' + numero;
SW.Panel.show('#detalhe');
}
// avisa quando fechou (ex.: atualizar a tabela)
document.getElementById('detalhe').addEventListener('sw:panel:close', () => {
console.log('painel fechado');
});
</script>
<button sw-btn="out" sw-panel-open="#compartilhar">Compartilhar</button>
<div sw-panel="bot" id="compartilhar">
<div sw-panel-hdr>
<h3>Compartilhar</h3>
<button sw-panel-cls sw-panel-close aria-label="Fechar"></button>
</div>
<div sw-panel-bdy>
<a href="https://wa.me/?text=…" sw-btn="suc"><i class="swi-chat"></i> WhatsApp</a>
<a href="mailto:?body=…" sw-btn="inf"><i class="swi-envelope"></i> E-mail</a>
</div>
</div>
Eventos
sw:panel:open<div sw-panel>) e sobe para a página.sw:panel:closeSW.Panel.hide() ou porque ele saiu da página.API (JavaScript)
SW.Panel.show('#id')'#id' ou o próprio elemento. Devolve true se abriu (false se já estava aberto ou não existe).SW.Panel.hide('#id')true se fechou.Precisa de quê
swcore.min.csseswcore.min.js— o painel precisa dos dois.swcore.compl.min.css— só se usar íconeswi-*dentro dele.
Cuidados — erros comuns
- O valor de
sw-panel-opentem que começar com#:sw-panel-open="#carrinho". Sem o#, o botão não faz nada. - O × (
sw-panel-cls) é só o desenho. Semsw-panel-closejunto, ele não fecha. - Dois painéis com o mesmo
id: o botão sempre abre o primeiro. - Não coloque o painel dentro de uma caixa com animação de movimento (
transform) ou filtro: ele passa a se prender a essa caixa em vez da tela. O lugar mais seguro é direto no<body>. - Dê um
aria-label="Fechar"ao botão do ×, que não tem texto.
O que ele não faz
- Um de cada vez: um botão que abre outro painel de dentro de um painel aberto deixa os dois abertos. Feche o primeiro com
SW.Panel.hide()antes de abrir o segundo. - Enquanto está aberto, a página de trás não rola.
- Em topo/baixo, a altura para em 85% da tela (no celular, na tela toda).
- Para uma pergunta curta e centralizada, o componente certo é o Modal.

