App Header

Navegacao

Barra superior do terminal desktop, composta por partes: marca, navegação, busca, resumo do dia, ações e controles de janela.

Carregando

Instalação

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

npm i @trdr/ui

import { AppHeader } from "@trdr/ui/app-header"

Uso

import { AppHeader, AppHeaderBrand, AppHeaderConnectionStatus, AppHeaderDivider, AppHeaderEnd, AppHeaderIconButton } from "@trdr/ui/app-header"

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

Variantes

GrupoValoresPadrão
active
truefalse
false

Props

AppHeaderPropsestende React.HTMLAttributes<HTMLElement>
AppHeaderStartPropsestende React.HTMLAttributes<HTMLDivElement>
AppHeaderEndPropsestende React.HTMLAttributes<HTMLDivElement>
AppHeaderDividerPropsestende React.HTMLAttributes<HTMLDivElement>
AppHeaderBrandPropsestende React.HTMLAttributes<HTMLDivElement>
PropTipoDescrição
logo?React.ReactNodeLogo da marca. Nao ha SVG embutido aqui de proposito: a versao do logo hoje em producao no Hub diverge da oficial do pacote de marca, e congelar a errada dentro deste componente impediria a correcao futura. Em produto, sirva o oficial: `<img src="/brand/logo-trdr.svg" alt="TRDR" className="h-6 w-auto" />`. O padrao aqui e so um texto simples, para o header nunca ficar vazio sem props.
AppHeaderNavPropsestende React.HTMLAttributes<HTMLElement>
PropTipoDescrição
itemsAppHeaderNavItem[]
value?stringItem ativo no momento. Selecao controlada: o componente nao guarda estado proprio.
onValueChange?(value: string) => void
AppHeaderSearchPropsestende React.ButtonHTMLAttributes<HTMLButtonElement>
PropTipoDescrição
icon?React.ReactNodeIcone de busca. Produto usa Material Symbols, nunca lucide: chega pronto via prop.
placeholder?stringTexto exibido no botao. Padrao "Pesquisar...".
AppHeaderQuotePropsestende Omit<React.HTMLAttributes<HTMLDivElement>, "onSelect">
PropTipoDescrição
dataAppHeaderQuoteData
onSelect?() => voidChamado ao acionar o resumo. Quando ausente, o resumo e apenas informativo (nao clicavel).
AppHeaderIconButtonPropsestende React.ButtonHTMLAttributes<HTMLButtonElement>
PropTipoDescrição
iconReact.ReactNodeIcone do botao. Produto usa Material Symbols, nunca lucide: chega pronto via prop.
labelstringNome acessivel do botao (nao ha texto visivel).
badgeCount?numberContagem exibida no badge de notificacao. Omitido ou zero esconde o badge.
AppHeaderConnectionStatusPropsestende React.ButtonHTMLAttributes<HTMLButtonElement>
PropTipoDescrição
icon?React.ReactNodeIcone de status. Produto usa Material Symbols, nunca lucide: chega pronto via prop.
labelstringTexto visivel e nome acessivel (ex.: "5/6 Conexoes").
AppHeaderWindowControlsPropsestende React.HTMLAttributes<HTMLDivElement>
PropTipoDescrição
onMinimize?() => void
onRestore?() => void
onClose?() => void
labels?{ minimize?: string restore?: string close?: string }Rotulos acessiveis dos tres controles, para localizacao sem trocar o componente.

Quando usar

Use o AppHeader como a barra fixa no topo do terminal desktop: identidade da marca, navegacao entre as areas principais do produto, busca de ativo, resumo do dia e acoes globais (notificacoes, perfil, configuracoes, status de conexao, controles de janela). E a peca de mais alto nivel deste pacote: praticamente todo app do terminal tem uma instancia dela.

Quando nao usar

Nao use AppHeader para uma barra de navegacao secundaria dentro de uma tela (abas de um modulo, por exemplo): monte essa com NavigationMenu ou uma lista de Button direto. Nao tente encaixar todo o estado da aplicacao nas props do header: cada peca e controlada (value/onValueChange, onSelect, onClick...), quem guarda o estado e o app.

Anatomia

AppHeader e composicao por partes, como Card/Item: a raiz e um container flexivel, e cada regiao e uma peca independente que o consumidor arruma dentro de AppHeaderStart (esquerda) e AppHeaderEnd (direita).

  • AppHeader (data-slot="app-header"): a raiz, um <header role="banner">.
  • AppHeaderStart / AppHeaderEnd (data-slot="app-header-start" / "app-header-end"): agrupam as pecas dos dois lados.
  • AppHeaderBrand (data-slot="app-header-brand"): a marca. Aceita logo?: ReactNode; sem logo, mostra um texto simples ("TRDR"). Veja a nota sobre o logo abaixo.
  • AppHeaderDivider (data-slot="app-header-divider"): divisor vertical fino, reutilizavel entre quaisquer duas pecas.
  • AppHeaderNav (data-slot="app-header-nav"): a navegacao principal. Recebe items: AppHeaderNavItem[] ({ value, label, icon? }), mais value/onValueChange (selecao controlada). Veja a nota sobre a decisao de nao usar NavigationMenu abaixo.
  • AppHeaderSearch (data-slot="app-header-search"): o gatilho de busca. E um botao, nao um Input: no legado (e aqui) ele abre a busca em outro lugar (paleta de comando, modal), nao edita texto no lugar.
  • AppHeaderQuote (data-slot="app-header-quote"): o resumo do ativo em foco e do resultado do dia. Recebe data: AppHeaderQuoteData (ticker, progress de 0 a 100, pnl e daily, cada um com direction: "up" | "down") e um onSelect? opcional. Sem onSelect, e so informativo; com onSelect, vira role="button" navegavel por teclado.
  • AppHeaderIconButton (data-slot="app-header-icon-button"): botao de icone generico, usado para notificacoes, perfil, configuracoes e layouts. Recebe icon, label (nome acessivel) e badgeCount? (contador de notificacao).
  • AppHeaderConnectionStatus (data-slot="app-header-connection-status"): indicador de conexao com icone e texto (ex.: "5/6 Conexoes").
  • AppHeaderWindowControls (data-slot="app-header-window-controls"): os tres controles de janela (minimizar, restaurar, fechar), com onMinimize/onRestore/onClose.

Sobre o logo

O logo nao vem embutido no componente: ele chega por logo?: ReactNode, com um texto simples como padrao sensato. Isso e deliberado, nao uma lacuna: a versao do logo hoje em producao no Hub diverge da oficial do pacote de marca, e congelar a versao errada dentro deste componente impediria a correcao futura sem uma nova versao da biblioteca. Em produto real, sirva o SVG oficial:

<AppHeaderBrand logo={<img src="/brand/logo-trdr.svg" alt="TRDR" className="h-6 w-auto" />} />

Sobre nao usar o NavigationMenu

Este pacote ja tem um primitivo NavigationMenu (Radix), mas o proprio MDX dele recomenda uma lista de Button ghost para "navegacao com poucas opcoes e sem submenu nenhum". Os itens do header (Grafico, Book e Cotacoes, Operacao...) sao exatamente isso: selecao de aba unica, sem painel flutuante. Por isso AppHeaderNav e uma lista de botoes simples dentro de um <nav>, seguindo a propria orientacao do NavigationMenu, em vez de o consumir.

Sobre os icones

Produto usa Material Symbols, nao lucide (CONTRACT secao 3); este pacote nao empacota Material Symbols. Por isso AppHeaderNav, AppHeaderSearch, AppHeaderIconButton e AppHeaderConnectionStatus recebem o icone pronto via prop (icon?: ReactNode), em vez de embutir um icone fixo. A unica excecao e AppHeaderWindowControls: os tres icones de minimizar, restaurar e fechar sao SVG customizado de 18x18 com fill="currentColor", desenhados dentro do proprio componente (o mesmo desenho do legado), porque nao existe equivalente em Material Symbols nem em lucide para esses tres glifos especificos de janela.

Migracao do componente legado

O Header do Hub antigo (src/components/ui/Header.tsx, Figma 15:4644 e 1921:55292) era um componente fechado com 11 props posicionais (activeNav, ticker, barPercent, pnlValue, pnlPercent, pnlPositive, resultadoDia, resultadoDiaPositive, notifications, profileBadge, connections). Isso deixou de existir como uma lista plana de props e virou composicao: cada regiao (marca, navegacao, busca, resumo, acoes, conexao, janela) e uma peca que o app monta dentro de AppHeaderStart/AppHeaderEnd, na ordem e combinacao que fizer sentido para aquele app. Os quatro botoes de icone quase identicos do legado (notificacoes, perfil, configuracoes, layouts) viraram uma unica peca parametrizada, AppHeaderIconButton.

O alvo de toque dos controles de janela tambem mudou: o legado desenhava o botao com exatamente 18x18px (o tamanho do proprio SVG), abaixo do minimo de 24px de area de toque que o CONTRACT exige para controle interativo. Aqui o botao tem 24x24px de area clicavel, com o mesmo SVG de 18x18 centralizado dentro.

Acessibilidade

  • A raiz e um <header role="banner">; a navegacao e um <nav aria-label="Navegacao principal"> (customizavel via prop aria-label do AppHeaderNav).
  • Cada AppHeaderIconButton tem aria-label obrigatorio (nao ha texto visivel no botao); o badge de notificacao entra na propria contagem do nome acessivel ("Notificacoes (4)"), em vez de exigir que o leitor de tela descubra o numero por conta propria no badge visual.
  • AppHeaderQuote so vira interativo (role="button", tabIndex, navegavel por Enter/Espaco) quando onSelect e informado; sem callback, e puramente informativo.
  • AppHeaderWindowControls e um role="toolbar" com aria-label="Controles da janela"; cada botao tem aria-label proprio (Minimizar/Restaurar/Fechar), customizavel via prop labels para localizacao.
  • Cor de alta/baixa (context-trading-up/down) no P&L e no resultado do dia nunca e a unica informacao: o texto (+R$ 1.250, -R$ 180) ja carrega o sinal, e o aria-label do AppHeaderQuote descreve a direcao por extenso ("alta"/"baixa") para quem usa leitor de tela.

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="app-header"][data-slot="app-header-brand"][data-slot="app-header-connection-status"][data-slot="app-header-divider"][data-slot="app-header-end"][data-slot="app-header-icon-button"][data-slot="app-header-icon-button-badge"][data-slot="app-header-nav"][data-slot="app-header-nav-item"][data-slot="app-header-quote"][data-slot="app-header-quote-bar"][data-slot="app-header-quote-bar-fill"][data-slot="app-header-quote-daily"][data-slot="app-header-quote-pnl"][data-slot="app-header-quote-ticker"][data-slot="app-header-search"][data-slot="app-header-start"][data-slot="app-header-window-button"][data-slot="app-header-window-controls"]
22 tokens usados
bg-backgroundbg-border-subtlebg-content-brandbg-context-trading-downbg-context-trading-upbg-surface-primarybg-surface-secondaryborder-bborder-border-subtleborder-transparentoutline-nonering-offset-2ring-offset-backgroundring-ringtext-b3text-content-inversetext-content-primarytext-content-secondarytext-content-tertiarytext-context-trading-downtext-context-trading-uptext-h7