Window

TradingLayout

Painel de aplicação desktop: barra de ferramentas, abas de sessão, área de conteúdo e menu de mais ações.

Carregando

Instalação

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

npm i @trdr/ui

import { Window } from "@trdr/ui/window"

Uso

import { Window, WindowAction, WindowActions, WindowContent, WindowTab, WindowTabs } from "@trdr/ui/window"

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

Props

WindowPropsestende React.HTMLAttributes<HTMLDivElement>
WindowToolbarPropsestende React.HTMLAttributes<HTMLDivElement>
WindowTabsPropsestende React.HTMLAttributes<HTMLDivElement>
PropTipoDescrição
valuestringvalor da aba ativa, controlado pelo consumidor
onValueChange(value: string) => void
WindowTabPropsestende React.ButtonHTMLAttributes<HTMLButtonElement>
PropTipoDescrição
valuestring
WindowContentPropsestende React.HTMLAttributes<HTMLDivElement>
PropTipoDescrição
showVerticalScrollHint?booleanMostra a faixa decorativa de rolagem vertical, encostada na borda direita.
showHorizontalScrollHint?booleanMostra a faixa decorativa de rolagem horizontal, encostada na borda inferior.
WindowActionsPropsestende Omit<React.ComponentPropsWithoutRef<typeof DropdownMenuContent>, "children">
PropTipoDescrição
actionsWindowAction[]
onAction(id: string) => void
open?boolean
onOpenChange?(open: boolean) => void
triggerLabel?stringnome acessivel do botao que abre o menu, ja que ele so mostra um icone

Quando usar

Use Window como o container de um painel do terminal: um grafico, um book de ofertas, uma tela de times & trades, qualquer area que fica sempre visivel no layout da aplicacao, com sua propria barra de ferramentas e suas proprias abas de sessao. E o "quadro" que o usuario arrasta, redimensiona e multiplica dentro do workspace de trading.

Quando nao usar

Nao use Window para conteudo temporario que precisa de foco preso e fechamento por Escape (uma confirmacao, um formulario modal): isso e o Dialog. Window nao tem overlay, nao bloqueia o scroll da pagina atras dele, e nao rouba foco ao aparecer, porque ele nunca "aparece": e o container persistente do painel, nao uma interrupcao.

Anatomia

<Window>                                     data-slot="window"
  <WindowToolbar>                            data-slot="window-toolbar"
    (conteudo livre: badge, texto, Button ghost/secondary, WindowActions)
  <WindowTabs value onValueChange>           data-slot="window-tabs", role="tablist"
    <WindowTab value>                        data-slot="window-tab", role="tab"
  <WindowContent>                            data-slot="window-content"
    (conteudo livre)
    <div data-slot="window-scroll-hint-y">   opcional, so quando showVerticalScrollHint
    <div data-slot="window-scroll-hint-x">   opcional, so quando showHorizontalScrollHint

<WindowActions actions onAction>             independente, usado dentro do WindowToolbar

WindowToolbar e WindowContent sao puramente de apresentacao (chrome + slot), no mesmo espirito do CardHeader/CardContent: o consumidor decide o que colocar dentro, incluindo reusar Tabs, Badge e Button da propria biblioteca para montar a fileira de ferramentas do cabecalho.

Migracao do componente legado

O Janela.tsx do Hub antigo era um componente fechado com quinze props (tools, activeTool, defaultActiveTool, onToolChange, tabs, activeTab, defaultActiveTab, onTabChange, multiLabel, onMultiClick, onLinkClick, onClose, showSideScroll, showBottomScroll, showActionsMenu, onActionsMenuToggle, actions...) e ainda gerenciava estado interno proprio (internalTool, internalTab) quando o consumidor nao controlava por fora. Isso e sinal de que o componente deveria ser composicao, nao um formulario de props. Aqui:

  • nao ha estado interno: WindowTabs e totalmente controlado por value/onValueChange
  • tools/activeTool/onToolChange deixaram de ser prop: monte a fileira de ferramentas dentro do WindowToolbar com o Tabs da biblioteca (icone + rotulo por aba, exatamente o que o legado fazia com o componente interno Abas)
  • multiLabel/onMultiClick, onLinkClick, onClose deixaram de ser prop: sao botoes comuns (Button variant="ghost" size="icon" ou variant="secondary") que o consumidor coloca dentro do WindowToolbar, com o onClick que quiser
  • showActionsMenu/onActionsMenuToggle/actions viraram o componente WindowActions, que encapsula o DropdownMenu inteiro (trigger, overlay, itens) em vez de expor um booleano de visibilidade que o consumidor tinha que combinar com uma lista de acoes renderizada por fora
  • showSideScroll/showBottomScroll viraram showVerticalScrollHint/showHorizontalScrollHint no WindowContent

O antigo menu flutuante (FloatingMenu) era feito a mao, sem overlay real: Escape nao fechava, nao havia navegacao por teclado. WindowActions resolve isso usando o DropdownMenu de verdade.

Acessibilidade

  • WindowTabs/WindowTab usam role="tablist"/role="tab" com aria-selected e navegacao por teclado: seta esquerda/direita move o foco entre abas, Home/End vao para a primeira/ultima. Isso e uma melhoria sobre o legado, que so tinha os mesmos papeis ARIA sem nenhum suporte a teclado.
  • Todo botao so-de-icone dentro do WindowToolbar (link, fechar, mais acoes) precisa de aria-label explicito: nenhum deles tem texto visivel.
  • WindowActions herda do DropdownMenu o fechamento com Escape, a navegacao por seta e o aria-label do botao de gatilho (prop triggerLabel).
  • As faixas de rolagem do WindowContent sao aria-hidden: sao decorativas, reproduzindo o indicador visual do legado, e nunca devem ser o unico jeito de rolar o conteudo (o scroll nativo do container continua funcionando por baixo).

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="window"][data-slot="window-actions-content"][data-slot="window-actions-item"][data-slot="window-actions-trigger"][data-slot="window-content"][data-slot="window-content-inner"][data-slot="window-scroll-hint-x"][data-slot="window-scroll-hint-y"][data-slot="window-tab"][data-slot="window-tabs"][data-slot="window-toolbar"]
13 tokens usados
bg-action-secondary-defaultbg-bg-secondarybg-bg-tertiaryborder-bborder-border-subtleborder-lborder-toutline-nonering-offset-2ring-offset-backgroundring-ringtext-b3text-content-tertiary