SWCore
SWCore / Componentes / Sidebar

Sidebar Componentes

O menu lateral do painel: logo em cima, itens com ícone, grupos, submenus e rodapé. Recolhe para só ícones, vira barrinha ou sai por cima no celular. <aside sw-sidebar sw-sidebar-mode='collapse'>.

O que é

É o menu da esquerda que todo sistema/painel tem: "Painel", "Agenda", "Clientes", "Financeiro"… O SWCore monta com atributos: sw-sidebar no <aside>, sw-sidebar-hdr no cabeçalho, sw-sidebar-mn na lista, sw-sidebar-it em cada item e sw-sidebar-lbl no texto do item. Um único atributo, sw-sidebar-mode, escolhe o comportamento: collapse (botão recolhe para só ícones), rail (sempre só ícones), hover (abre quando o mouse passa), toggle (sai por cima do conteúdo, bom no celular) ou fixed (sempre aberta).

A sidebar é presa na lateral esquerda da tela, de cima a baixo (26 rem de largura). O JavaScript do núcleo escreve o estado dela como atributo: col = só ícones (7,2 rem), bar = barrinha fina (1,8 rem), hid = escondida. O CSS esconde textos, títulos de grupo e submenus conforme o estado. O estado atual também fica em data-sidebar-state (open, col ou bar). Clicar num item marca ele como atual (act) sozinho. Nos quadros abaixo a sidebar está dentro de uma caixa só para caber na página.

Quando usar

  • Painel admin / sistema: menu principal com as áreas (Agenda, Clientes, Financeiro, Configurações).
  • Área do cliente com várias seções (Pedidos, Endereços, Dados).
  • Documentação — o menu à esquerda desta página é uma sidebar.
  • Para o menu do topo de um site, use a Navbar.

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 swi-* dos itens.

    <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

    Monte o <aside> com cabeçalho e itens (ícone + texto). O botão com sw-sidebar-tgl na borda recolhe e abre. Clique na setinha.

    <aside sw-sidebar sw-sidebar-mode="collapse">
      <button sw-sidebar-tgl aria-label="Recolher menu"><i class="swi-chevron-left"></i></button>
      <div sw-sidebar-hdr><i sw-sidebar-hdr-ico class="swi-cut"></i><span sw-sidebar-hdr-ttl>Barbearia</span></div>
      <nav sw-sidebar-mn>
        <a sw-sidebar-it act href="#"><i class="swi-home"></i><span sw-sidebar-lbl>Painel</span></a>
        <a sw-sidebar-it href="#"><i class="swi-calendar"></i><span sw-sidebar-lbl>Agenda</span></a>
        <a sw-sidebar-it href="#"><i class="swi-group"></i><span sw-sidebar-lbl>Clientes</span></a>
        <a sw-sidebar-it href="#"><i class="swi-wallet"></i><span sw-sidebar-lbl>Caixa</span></a>
      </nav>
    </aside>
  3. 3

    A sidebar fica por cima da página, presa na esquerda. Empurre o conteúdo para o lado com uma margem do mesmo tamanho (a página não faz isso sozinha).

    <main class="conteudo">…</main>
    
    <style>
      .conteudo { margin-left: 26rem; transition: margin-left .3s; }
      /* quando recolher para só ícones */
      [data-sidebar-state="col"] ~ .conteudo { margin-left: 7.2rem; }
    </style>

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. Comportamento — sw-sidebar-mode

O mesmo menu, cinco jeitos de se comportar. Sem o atributo, o modo é toggle.

collapse — a setinha alterna: cheia ↔ só ícones
<aside sw-sidebar sw-sidebar-mode="collapse">
  <button sw-sidebar-tgl aria-label="Recolher menu"><i class="swi-chevron-left"></i></button>
  <div sw-sidebar-hdr><i sw-sidebar-hdr-ico class="swi-cut"></i><span sw-sidebar-hdr-ttl>Barbearia</span></div>
  <nav sw-sidebar-mn>
    <a sw-sidebar-it act href="#"><i class="swi-home"></i><span sw-sidebar-lbl>Painel</span></a>
    <a sw-sidebar-it href="#"><i class="swi-calendar"></i><span sw-sidebar-lbl>Agenda</span></a>
    <a sw-sidebar-it href="#"><i class="swi-group"></i><span sw-sidebar-lbl>Clientes</span></a>
    <a sw-sidebar-it href="#"><i class="swi-wallet"></i><span sw-sidebar-lbl>Caixa</span></a>
  </nav>
</aside>
rail — sempre só ícones, sem botão
<aside sw-sidebar sw-sidebar-mode="rail">
  <div sw-sidebar-hdr><i sw-sidebar-hdr-ico class="swi-cut"></i><span sw-sidebar-hdr-ttl>Barbearia</span></div>
  <nav sw-sidebar-mn>
    <a sw-sidebar-it act href="#"><i class="swi-home"></i><span sw-sidebar-lbl>Painel</span></a>
    <a sw-sidebar-it href="#"><i class="swi-calendar"></i><span sw-sidebar-lbl>Agenda</span></a>
    <a sw-sidebar-it href="#"><i class="swi-group"></i><span sw-sidebar-lbl>Clientes</span></a>
    <a sw-sidebar-it href="#"><i class="swi-wallet"></i><span sw-sidebar-lbl>Caixa</span></a>
  </nav>
</aside>
hover — só ícones; abre quando o mouse entra
<aside sw-sidebar sw-sidebar-mode="hover">
  <div sw-sidebar-hdr><i sw-sidebar-hdr-ico class="swi-cut"></i><span sw-sidebar-hdr-ttl>Barbearia</span></div>
  <nav sw-sidebar-mn>
    <a sw-sidebar-it act href="#"><i class="swi-home"></i><span sw-sidebar-lbl>Painel</span></a>
    <a sw-sidebar-it href="#"><i class="swi-calendar"></i><span sw-sidebar-lbl>Agenda</span></a>
    <a sw-sidebar-it href="#"><i class="swi-group"></i><span sw-sidebar-lbl>Clientes</span></a>
    <a sw-sidebar-it href="#"><i class="swi-wallet"></i><span sw-sidebar-lbl>Caixa</span></a>
  </nav>
</aside>
fixed — sempre aberta, sem recolher
<aside sw-sidebar sw-sidebar-mode="fixed">
  <div sw-sidebar-hdr><i sw-sidebar-hdr-ico class="swi-cut"></i><span sw-sidebar-hdr-ttl>Barbearia</span></div>
  <nav sw-sidebar-mn>
    <a sw-sidebar-it act href="#"><i class="swi-home"></i><span sw-sidebar-lbl>Painel</span></a>
    <a sw-sidebar-it href="#"><i class="swi-calendar"></i><span sw-sidebar-lbl>Agenda</span></a>
    <a sw-sidebar-it href="#"><i class="swi-group"></i><span sw-sidebar-lbl>Clientes</span></a>
    <a sw-sidebar-it href="#"><i class="swi-wallet"></i><span sw-sidebar-lbl>Caixa</span></a>
  </nav>
</aside>
toggle — escondida; um botão fora abre por cima, com cortina escura (fecha na cortina ou no Esc)
<button type="button" sw-btn="pri p" sw-sidebar-open="#menu"><i class="swi-menu"></i> Abrir menu</button>

<div sw-sidebar-ovl></div>   <!-- a cortina escura, uma vez na página -->

<aside sw-sidebar sw-sidebar-mode="toggle" id="menu" hid>   <!-- hid = começa escondida -->
  <div sw-sidebar-hdr><i sw-sidebar-hdr-ico class="swi-cut"></i><span sw-sidebar-hdr-ttl>Barbearia</span></div>
  <nav sw-sidebar-mn>
    <a sw-sidebar-it act href="#"><i class="swi-home"></i><span sw-sidebar-lbl>Painel</span></a>
    <a sw-sidebar-it href="#"><i class="swi-calendar"></i><span sw-sidebar-lbl>Agenda</span></a>
    <a sw-sidebar-it href="#"><i class="swi-group"></i><span sw-sidebar-lbl>Clientes</span></a>
    <a sw-sidebar-it href="#"><i class="swi-wallet"></i><span sw-sidebar-lbl>Caixa</span></a>
  </nav>
</aside>

2. Estados do modo collapse

sw-sidebar-start escolhe como ela nasce: open (cheia, padrão), icons (só ícones) ou bar (barrinha). Com sw-sidebar-bar, a setinha passa a girar por três estados: cheia → só ícones → barrinha → cheia. Clicar no ícone do cabeçalho faz o mesmo que a setinha.

Nasce só com ícones — sw-sidebar-start="icons"
<aside sw-sidebar sw-sidebar-mode="collapse" sw-sidebar-start="icons">
  <button sw-sidebar-tgl aria-label="Abrir menu"><i class="swi-chevron-left"></i></button>
  <div sw-sidebar-hdr><i sw-sidebar-hdr-ico class="swi-cut"></i><span sw-sidebar-hdr-ttl>Barbearia</span></div>
  <nav sw-sidebar-mn>
    <a sw-sidebar-it act href="#"><i class="swi-home"></i><span sw-sidebar-lbl>Painel</span></a>
    <a sw-sidebar-it href="#"><i class="swi-calendar"></i><span sw-sidebar-lbl>Agenda</span></a>
    <a sw-sidebar-it href="#"><i class="swi-group"></i><span sw-sidebar-lbl>Clientes</span></a>
    <a sw-sidebar-it href="#"><i class="swi-wallet"></i><span sw-sidebar-lbl>Caixa</span></a>
  </nav>
</aside>
Três estados — sw-sidebar-bar
<aside sw-sidebar sw-sidebar-mode="collapse" sw-sidebar-bar>
  <button sw-sidebar-tgl aria-label="Recolher menu"><i class="swi-chevron-left"></i></button>
  <div sw-sidebar-hdr><i sw-sidebar-hdr-ico class="swi-cut"></i><span sw-sidebar-hdr-ttl>Barbearia</span></div>
  <nav sw-sidebar-mn>
    <a sw-sidebar-it act href="#"><i class="swi-home"></i><span sw-sidebar-lbl>Painel</span></a>
    <a sw-sidebar-it href="#"><i class="swi-calendar"></i><span sw-sidebar-lbl>Agenda</span></a>
    <a sw-sidebar-it href="#"><i class="swi-group"></i><span sw-sidebar-lbl>Clientes</span></a>
    <a sw-sidebar-it href="#"><i class="swi-wallet"></i><span sw-sidebar-lbl>Caixa</span></a>
  </nav>
</aside>
Nasce como barrinha — sw-sidebar-bar + start="bar"
<aside sw-sidebar sw-sidebar-mode="collapse" sw-sidebar-bar sw-sidebar-start="bar">
  <button sw-sidebar-tgl aria-label="Abrir menu"><i class="swi-chevron-left"></i></button>
  <div sw-sidebar-hdr><i sw-sidebar-hdr-ico class="swi-cut"></i><span sw-sidebar-hdr-ttl>Barbearia</span></div>
  <nav sw-sidebar-mn>
    <a sw-sidebar-it act href="#"><i class="swi-home"></i><span sw-sidebar-lbl>Painel</span></a>
    <a sw-sidebar-it href="#"><i class="swi-calendar"></i><span sw-sidebar-lbl>Agenda</span></a>
    <a sw-sidebar-it href="#"><i class="swi-group"></i><span sw-sidebar-lbl>Clientes</span></a>
    <a sw-sidebar-it href="#"><i class="swi-wallet"></i><span sw-sidebar-lbl>Caixa</span></a>
  </nav>
</aside>
Botão dentro do cabeçalho (em vez da borda)
<aside sw-sidebar sw-sidebar-mode="collapse">
  <div sw-sidebar-hdr><i sw-sidebar-hdr-ico class="swi-cut"></i><span sw-sidebar-hdr-ttl>Barbearia</span><button sw-sidebar-tgl aria-label="Recolher menu"><i class="swi-menu"></i></button></div>
  <nav sw-sidebar-mn>
    <a sw-sidebar-it act href="#"><i class="swi-home"></i><span sw-sidebar-lbl>Painel</span></a>
    <a sw-sidebar-it href="#"><i class="swi-calendar"></i><span sw-sidebar-lbl>Agenda</span></a>
  </nav>
</aside>

3. Organizando o menu

Títulos de grupo (sw-sidebar-grp-ttl), submenus que abrem com clique (até 3 níveis) e um rodapé preso embaixo (sw-sidebar-ftr). O item que abre submenu tem sw-sidebar-sub e, logo depois dele, a caixa sw-sidebar-sub-items.

Grupos + rodapé
<aside sw-sidebar sw-sidebar-mode="fixed">
  <div sw-sidebar-hdr><i sw-sidebar-hdr-ico class="swi-store"></i><span sw-sidebar-hdr-ttl>Loja Bela</span></div>
  <nav sw-sidebar-mn>
    <span sw-sidebar-grp-ttl>Vendas</span>
    <a sw-sidebar-it act href="#"><i class="swi-receipt"></i><span sw-sidebar-lbl>Pedidos</span></a>
    <a sw-sidebar-it href="#"><i class="swi-package"></i><span sw-sidebar-lbl>Produtos</span></a>
    <span sw-sidebar-grp-ttl>Financeiro</span>
    <a sw-sidebar-it href="#"><i class="swi-wallet"></i><span sw-sidebar-lbl>Caixa</span></a>
  </nav>
  <div sw-sidebar-ftr>
    <a sw-sidebar-it href="#"><i class="swi-log-out"></i><span sw-sidebar-lbl>Sair</span></a>
  </div>
</aside>
Submenu de 2 e 3 níveis
<aside sw-sidebar sw-sidebar-mode="fixed">
  <div sw-sidebar-hdr><i sw-sidebar-hdr-ico class="swi-first-aid"></i><span sw-sidebar-hdr-ttl>Clínica Vida</span></div>
  <nav sw-sidebar-mn>
    <a sw-sidebar-it act href="#"><i class="swi-home"></i><span sw-sidebar-lbl>Painel</span></a>
    <a sw-sidebar-it sw-sidebar-sub open href="#"><i class="swi-calendar"></i><span sw-sidebar-lbl>Agenda</span><i class="swi-chevron-right" sw-sidebar-arrow></i></a>
    <div sw-sidebar-sub-items open>
      <a sw-sidebar-it href="#"><span sw-sidebar-lbl>Hoje</span></a>
      <a sw-sidebar-it sw-sidebar-sub href="#"><span sw-sidebar-lbl>Por médico</span><i class="swi-chevron-right" sw-sidebar-arrow></i></a>
      <div sw-sidebar-sub-items>
        <a sw-sidebar-it href="#"><span sw-sidebar-lbl>Dra. Ana</span></a>
        <a sw-sidebar-it href="#"><span sw-sidebar-lbl>Dr. Paulo</span></a>
      </div>
    </div>
    <a sw-sidebar-it href="#"><i class="swi-group"></i><span sw-sidebar-lbl>Pacientes</span></a>
  </nav>
</aside>

Tabela de opções

PalavraO que fazExemplo
Peças
sw-sidebarNo <aside>: o menu inteiro, preso na esquerda da tela.<aside sw-sidebar>
sw-sidebar-hdrCabeçalho (logo + nome).<div sw-sidebar-hdr>
sw-sidebar-hdr-icoÍcone/logo do cabeçalho. No modo collapse ele também recolhe/abre ao clicar.<i sw-sidebar-hdr-ico class="swi-cut">
sw-sidebar-hdr-ttlNome no cabeçalho (some quando recolhida).<span sw-sidebar-hdr-ttl>
sw-sidebar-mnA lista de itens (rola se for comprida).<nav sw-sidebar-mn>
sw-sidebar-itCada item.<a sw-sidebar-it href="…">
sw-sidebar-lblO texto do item (some quando recolhida; o ícone fica).<span sw-sidebar-lbl>Agenda</span>
actNo item: marca a página atual. O clique move sozinho.<a sw-sidebar-it act>
sw-sidebar-grp-ttlTítulo pequeno de grupo (some quando recolhida).<span sw-sidebar-grp-ttl>Vendas</span>
sw-sidebar-ftrRodapé preso embaixo (usuário, sair).<div sw-sidebar-ftr>
sw-sidebar-tglBotão que recolhe/abre (modo collapse). Filho direto do aside = botão redondo na borda; dentro do cabeçalho = botão no canto dele.<button sw-sidebar-tgl>
Comportamento — sw-sidebar-mode
togglePadrão. Aparece/some por cima do conteúdo com um botão de fora (sw-sidebar-open); fecha na cortina ou no Esc.sw-sidebar-mode="toggle"
collapseA setinha (sw-sidebar-tgl) alterna cheia ↔ só ícones.sw-sidebar-mode="collapse"
railSempre só ícones.sw-sidebar-mode="rail"
hoverSó ícones; abre enquanto o mouse está em cima.sw-sidebar-mode="hover"
fixedSempre aberta. Com sw-sidebar-start="icons" fica igual ao rail.sw-sidebar-mode="fixed"
Estado inicial e ciclo (collapse)
sw-sidebar-startopen (padrão), icons ou bar (este só com sw-sidebar-bar).sw-sidebar-start="icons"
sw-sidebar-barSem valor: a setinha gira por 3 estados (cheia → ícones → barrinha).<aside sw-sidebar sw-sidebar-mode="collapse" sw-sidebar-bar>
Modo toggle
sw-sidebar-openNum botão fora da sidebar, com o seletor dela: abre se estiver fechada, fecha se estiver aberta.<button sw-sidebar-open="#menu">
sw-sidebar-ovlA cortina escura atrás dela; clicar nela fecha. Sem valor = cortina geral da página. Com mais de uma sidebar, cada uma pode ter a sua: sw-sidebar-ovl="#id-da-sidebar".<div sw-sidebar-ovl></div>
hidEscondida. Escreva no HTML para ela começar fechada.<aside sw-sidebar id="menu" hid>
Submenu
sw-sidebar-subNo item que abre submenu (clique abre/fecha).<a sw-sidebar-it sw-sidebar-sub>
sw-sidebar-sub-itemsA caixa dos filhos, logo depois do item. Pode ter outro submenu dentro (3º nível).<div sw-sidebar-sub-items>
sw-sidebar-arrowNa setinha do item: gira ao abrir.<i class="swi-chevron-right" sw-sidebar-arrow>
openNo item e na caixa: submenu já nasce aberto.<a sw-sidebar-it sw-sidebar-sub open>
Estado (escrito pelo JS)
colSó ícones.
barBarrinha fina.
data-sidebar-stateopen, col ou bar — nos modos collapse e rail. Use no seu CSS para ajustar a margem do conteúdo.[data-sidebar-state="col"]

Receitas prontas — usos reais

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

Painel admin completo (grupos, submenu e rodapé) Ao vivo
<aside sw-sidebar sw-sidebar-mode="collapse" id="menu">
  <button sw-sidebar-tgl aria-label="Recolher menu"><i class="swi-chevron-left"></i></button>
  <div sw-sidebar-hdr><i sw-sidebar-hdr-ico class="swi-dumbbell"></i><span sw-sidebar-hdr-ttl>Academia Forte</span></div>
  <nav sw-sidebar-mn>
    <a sw-sidebar-it act href="/admin"><i class="swi-home"></i><span sw-sidebar-lbl>Painel</span></a>
    <span sw-sidebar-grp-ttl>Alunos</span>
    <a sw-sidebar-it href="/admin/matriculas"><i class="swi-group"></i><span sw-sidebar-lbl>Matrículas</span></a>
    <a sw-sidebar-it sw-sidebar-sub href="#"><i class="swi-calendar"></i><span sw-sidebar-lbl>Aulas</span><i class="swi-chevron-right" sw-sidebar-arrow></i></a>
    <div sw-sidebar-sub-items>
      <a sw-sidebar-it href="/admin/aulas/musculacao"><span sw-sidebar-lbl>Musculação</span></a>
      <a sw-sidebar-it href="/admin/aulas/funcional"><span sw-sidebar-lbl>Funcional</span></a>
    </div>
    <span sw-sidebar-grp-ttl>Gestão</span>
    <a sw-sidebar-it href="/admin/mensalidades"><i class="swi-wallet"></i><span sw-sidebar-lbl>Mensalidades</span></a>
  </nav>
  <div sw-sidebar-ftr><a sw-sidebar-it href="/sair"><i class="swi-log-out"></i><span sw-sidebar-lbl>Sair</span></a></div>
</aside>

<main class="conteudo">…</main>
Lembrar se a pessoa deixou recolhida Referência
<aside sw-sidebar sw-sidebar-mode="collapse" id="menu">…</aside>

<script>
  // ANTES do swcore.min.js: nasce do jeito que a pessoa deixou da última vez
  const menu = document.getElementById('menu');
  if (localStorage.getItem('menu') === 'col') menu.setAttribute('sw-sidebar-start', 'icons');

  // guarda a escolha a cada clique na setinha
  menu.addEventListener('sw:sidebar:state', (e) => {
    localStorage.setItem('menu', e.detail.state);   // "open" ou "col"
  });
</script>
<script src="https://swcore.sanweb.com.br/dist/2.1.0/swcore.min.js"></script>
No celular: menu escondido que abre pelo ☰ Referência
<header class="topo">
  <button type="button" sw-btn="ghost rnd" sw-sidebar-open="#menu" aria-label="Abrir menu"><i class="swi-menu"></i></button>
</header>

<div sw-sidebar-ovl></div>
<aside sw-sidebar sw-sidebar-mode="toggle" id="menu" hid>…</aside>

<script>
  // abrir e fechar por código (ex.: depois de escolher um item)
  SW.Sidebar.open('#menu');
  SW.Sidebar.close('#menu');
</script>

Eventos

sw:sidebar:state
Modo collapse: mudou de estado. e.detail.state = "open", "col" ou "bar". Também dispara uma vez quando a página abre.
sw:sidebar:submenu
Um submenu abriu ou fechou. e.detail = { trigger, items, open } (o item clicado, a caixa dos filhos e se ficou aberto).
sw:sidebar:open
Abriu: por SW.Sidebar.open(), pelo botão sw-sidebar-open ou, no modo hover, quando o mouse entrou.
sw:sidebar:close
Fechou: por SW.Sidebar.close(), pelo botão, pela cortina, pelo Esc ou, no modo hover, quando o mouse saiu.

API (JavaScript)

SW.Sidebar.open(el)
Mostra a sidebar (tira o hid) e liga a cortina. Aceita o elemento ou um seletor como "#menu".
SW.Sidebar.close(el)
Esconde a sidebar (põe hid) e desliga a cortina.
SW.Sidebar.initAll(raiz)
Liga as sidebars e botões sw-sidebar-open dentro de raiz. O núcleo já faz sozinho.

Precisa de quê

  • swcore.min.css + swcore.min.js — a sidebar e os modos.
  • swcore.compl.min.css — os ícones swi-* dos itens (sem eles, o modo só-ícones fica vazio).

Cuidados — erros comuns

  • Esquecer que ela fica por cima: sem margem no conteúdo, o texto da página fica escondido atrás do menu. Veja o passo 3 do "Comece aqui".
  • Item sem ícone: quando a sidebar recolhe para só ícones, ele fica vazio. Todo item do primeiro nível precisa de <i class="swi-…">.
  • Texto do item fora do <span sw-sidebar-lbl>: ele não some ao recolher e estoura a largura.
  • Colocar o sw-sidebar-sub-items dentro do item: ele vem logo depois do <a sw-sidebar-sub>, como irmão.
  • Mais de uma sidebar com cortina: dê a cada uma a sua (sw-sidebar-ovl="#menu", sw-sidebar-ovl="#filtros"). Sem valor, a cortina é a geral e serve a quem não tem cortina própria.
  • Esperar que o submenu abra com a sidebar recolhida (só ícones): de propósito ele não abre — não há espaço.

O que ele não faz

  • Fica sempre do lado esquerdo; não há opção de lado direito.
  • Não empurra o conteúdo da página sozinha — a margem é por sua conta (use data-sidebar-state).
  • Não guarda sozinha a preferência de recolhida/aberta (veja a receita com localStorage).
  • No modo collapse não existe função JS para recolher/abrir; use o clique no sw-sidebar-tgl.