Resizable

Layout

Grupo de painéis redimensionáveis lado a lado ou empilhados, para telas com vários blocos de conteudo, como um terminal de trading.

Carregando

Instalação

Recebe correções por update de versão. O caminho recomendado.

npm i @trdr/ui

import { Resizable } from "@trdr/ui/resizable"

Uso

import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@trdr/ui/resizable"

export function Exemplo() {
  return <Resizable />
}

Props

ResizablePanelGroupPropsestende Omit<React.HTMLAttributes<HTMLDivElement>, "id">
PropTipoDescrição
orientation?"horizontal" | "vertical"Direcao de redimensionamento do grupo: paineis lado a lado ou empilhados. Padrao "horizontal".
defaultLayout?LayoutLayout inicial (mapa de id do painel para percentual 0..100), para lembrar entre recargas de pagina.
disabled?booleanDesativa o redimensionamento de todos os paineis deste grupo.
id?string | numberIdentifica o grupo dentro da aplicacao; cai para `useId` quando omitido.
onLayoutChange?(layout: Layout) => voidChamado a cada movimento do ponteiro enquanto o layout do grupo esta mudando.
onLayoutChanged?(layout: Layout, meta: LayoutChangedMeta) => voidChamado depois que o layout do grupo termina de mudar; preferido para persistir o layout.
ResizablePanelPropsestende Omit<React.HTMLAttributes<HTMLDivElement>, "onResize" | "id">
PropTipoDescrição
defaultSize?number | stringTamanho padrao do painel no grupo. Numero = pixels; string sem unidade = percentual; aceita tambem px/%/em/rem/vh/vw.
minSize?number | stringTamanho minimo do painel (mesmas regras de unidade do `defaultSize`).
maxSize?number | stringTamanho maximo do painel (mesmas regras de unidade do `defaultSize`); padrao "100%".
collapsible?booleanPermite este painel colapsar quando redimensionado abaixo do `minSize`.
collapsedSize?number | stringTamanho do painel quando colapsado; padrao 0%.
disabled?booleanDesativa o redimensionamento deste painel especificamente.
id?string | numberIdentifica o painel dentro do grupo; cai para `useId` quando omitido.
onResize?( panelSize: PanelSize, id: string | number | undefined, prevPanelSize: PanelSize | undefined ) => voidChamado quando o tamanho do painel muda; `prevPanelSize` vem `undefined` na montagem.
ResizableHandlePropsestende Omit<React.HTMLAttributes<HTMLDivElement>, "role" | "tabIndex" | "id">
PropTipoDescrição
disabled?booleanDesativa o redimensionamento dos paineis vizinhos por esta alca.
disableDoubleClick?booleanQuando true, o duplo clique nesta alca nao restaura o tamanho padrao dos paineis vizinhos.
id?string | numberIdentifica a alca dentro do grupo; cai para `useId` quando omitido.
withHandle?booleanMostra a alca visual (o "grip") no meio do separador, para deixar claro que arrasta.

Quando usar

Use paineis redimensionaveis quando a tela precisa mostrar varios blocos de conteudo lado a lado (ou empilhados) e o usuario se beneficia de ajustar o espaco de cada um: grafico ao lado do book de ofertas, historico de ordens abaixo do grafico. E o layout central de um terminal de trading, onde nenhuma proporcao fixa serve para todo mundo.

Quando nao usar

Nao use para layouts com dois ou tres blocos de tamanho fixo que nunca precisam mudar (um formulario com barra lateral de ajuda estatica): isso e so grid ou flex comum, sem o custo de interacao extra do redimensionamento. Tambem evite paineis redimensionaveis dentro de telas pequenas (mobile): a alca de arrasto exige precisao que o toque nao da tao bem quanto o mouse.

Anatomia

  • ResizablePanelGroup (data-slot="resizable-panel-group"): a raiz, define a orientacao (orientation="horizontal" ou "vertical") do grupo inteiro.
  • ResizablePanel (data-slot="resizable-panel"): um painel dentro do grupo. Aceita defaultSize, minSize, maxSize e collapsible. Estes tres aceitam numero (interpretado em pixels) ou string (interpretada em porcentagem, ex. "50%" ou so "50").
    <ResizablePanel defaultSize="60%" minSize="20%">...</ResizablePanel>
  • ResizableHandle (data-slot="resizable-handle"): a divisoria entre dois paineis, que o usuario arrasta para redimensionar. Aceita withHandle para mostrar uma alca visual (o "grip") no meio, deixando claro que aquele tracinho e arrastavel:
    <ResizableHandle withHandle />

Paineis e alcas precisam ser filhos diretos do ResizablePanelGroup (a lib exige isso na propria estrutura do DOM); para aninhar um grupo vertical dentro de um painel horizontal, coloque um ResizablePanelGroup completo dentro do ResizablePanel.

Nota de implementacao

A versao instalada do react-resizable-panels (a 4.x) renomeou os primitivos que o shadcn classico usava: nao existe mais PanelGroup/PanelResizeHandle com prop direction, e sim Group/Panel/Separator com prop orientation. Os nomes ResizablePanelGroup/ ResizablePanel/ResizableHandle daqui sao os do pedido original; por baixo, cada um so repassa para o primitivo correspondente da versao atual da biblioteca.

Acessibilidade

  • Cada ResizableHandle e um elemento com role="separator", aria-orientation (ligado a orientacao do grupo) e tabIndex="0": alcancavel por Tab, sem precisar de mouse.
  • Com a alca focada, as setas do teclado redimensionam os paineis vizinhos (esquerda/direita para grupos horizontais, cima/baixo para verticais), e Home/End vao para os extremos.
  • O foco na alca fica visivel (focus-visible:ring-2), e o alvo de arrasto e maior do que a linha visual (a lib usa uma area de hit-test ampliada por baixo do fio de 1px), para nao exigir precisao de pixel do mouse.

Slots e tokens

Todo elemento renderizado carrega um data-slot para estilizar partes internas sem depender de classe da biblioteca. Os tokens listados são extraídos do código fonte.

[data-slot="resizable-handle"][data-slot="resizable-handle-grip"][data-slot="resizable-panel"][data-slot="resizable-panel-group"]
9 tokens usados
bg-border-focusbg-border-subtlebg-surface-secondaryborder-borderoutline-nonering-offset-2ring-offset-backgroundring-ringtext-content-tertiary