React 19 · 8 kB comprimido · sem dependências

O chassi
sob a sua ferramenta.

Trilhos de ícones nas bordas, zonas redimensionáveis em volta de um centro que é seu, e um layout que sobrevive a um recarregamento. Sem renderização por baixo, repintável por cima.

Ver os exemplos
Ao vivo. Arraste as divisões entre as superfícies, clique num ícone do trilho ou leve-o para outra metade, redimensione a janela.

Quatro formas de começar

Cada um roda no seu navegador e o código completo está à vista. Comece pelo mais próximo.

Mínimo

O menor chassi que funciona. Duas colunas, uma faixa, um centro — e um cabeçalho seu comandando tudo.

import { Panels, Panel } from '@pasquelin/panels'
import '@pasquelin/panels/styles.css'

<Panels<PanelId>>
  <Panel<PanelId> id="files" zone="left" title="Files">
    <FileTree />
  </Panel>

  <Panel<PanelId> id="notes" zone="right" opens={380}>
    <Notes />
  </Panel>

  <Panels.Center>
    <YourApp />
  </Panels.Center>
</Panels>

Dica. Painéis que dividem a mesma zona e a mesma metade se revezam; o trilho alterna entre eles. Dê a metade secundária a um deles para empilhá-lo sob o primeiro. Aqui os ícones do trilho também se arrastam de uma metade para a outra.

Abrir Mínimo

React Router

O centro é uma saída de rota. Navegar muda o meio e nada mais: as colunas mantêm a largura e os painéis abertos continuam abertos.

function Layout() {
  return (
    <Panels<PanelId>>
      <Panel<PanelId> id="sites" zone="left" title="Sites">
        <SiteList />
      </Panel>

      <Panels.Center>
        <Outlet />
      </Panels.Center>
    </Panels>
  )
}

Dica. Declare os painéis na rota de layout, acima da saída. Declarados por página, seriam desmontados a cada navegação e perderiam o que guardavam.

Abrir React Router

Abas de documentos

O centro carrega documentos no Dockview — abas que se arrastam e se dividem — enquanto os painéis ficam nas bordas.

import { DockviewCenter } from '@pasquelin/panels/dockview'

<Panels.Center>
  <DockviewCenter
    documents={{ editor: Editor }}
    empty={NothingOpen}
    onReady={setApi}
  />
</Panels.Center>

Dica. Importe do ponto de entrada dockview: assim o peso recai só sobre os projetos que querem abas. Um painel nunca entra no centro: um documento tem nome, um painel tem ícone.

Abrir Abas de documentos

Repintado

O mesmo chassi sob quatro paletas. Cores, raio, largura do trilho, altura do cabeçalho — tudo são propriedades personalizadas.

.pnl-root {
  --pnl-chassis: #2e2b26;
  --pnl-panel: #1b1916;
  --pnl-accent: #d99a2b;
  --pnl-radius: 12px;
  --pnl-rail: 60px;
}

Dica. Defina o token de destaque em qualquer ancestral e o chassi herdará a sua marca em vez de impor a dele. Precisa ir além? Cada peça é exportada e substituível sozinha.

Abrir Repintado

Toda a superfície

Não é muita, e é esse o ponto. Seis coisas para saber.

Declarar

Um painel é um descritor: onde ele fica, como se chama e o que desenha.

<Panel id="files" zone="left" title="Files" icon={<Icon />}>
  <FileTree />
</Panel>
Comandar

Um único hook para qualquer cabeçalho, atalho ou menu que precise agir sobre os painéis.

const { reveal, close, toggle, isShown } = usePanels<PanelId>()
Reordenar

Uma prop, e quem lê arrasta um ícone do trilho para outra metade. O lugar escolhido fica guardado com o resto da disposição.

<Panels<PanelId> draggablePanels>
Comandar fora do React

Crie você mesmo o store e um socket, um menu nativo ou um worker poderá abrir um painel.

const store = createPanelsStore<PanelId>()
socket.on('alert', () => store.getState().show('alerts'))
Repintar

Cada valor é uma propriedade personalizada. Defina o destaque e os trilhos seguem a sua marca.

.pnl-root {
  --pnl-panel: #101418;
  --pnl-accent: #47965c;
  --pnl-radius: 10px;
}
Ou ficar só com a lógica

Os componentes são construídos sobre hooks que não desenham nada. Desenhe o seu próprio quadro sobre eles.

const zone = useZone('left')
useContainerFit(ref)