App Header
Barra superior do terminal desktop, composta por partes: marca, navegação, busca, resumo do dia, ações e controles de janela.
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
| Grupo | Valores | Padrã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>| Prop | Tipo | Descrição |
|---|---|---|
| logo? | React.ReactNode | Logo 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>| Prop | Tipo | Descrição |
|---|---|---|
| items | AppHeaderNavItem[] | |
| value? | string | Item ativo no momento. Selecao controlada: o componente nao guarda estado proprio. |
| onValueChange? | (value: string) => void |
AppHeaderSearchPropsestende React.ButtonHTMLAttributes<HTMLButtonElement>| Prop | Tipo | Descrição |
|---|---|---|
| icon? | React.ReactNode | Icone de busca. Produto usa Material Symbols, nunca lucide: chega pronto via prop. |
| placeholder? | string | Texto exibido no botao. Padrao "Pesquisar...". |
AppHeaderQuotePropsestende Omit<React.HTMLAttributes<HTMLDivElement>, "onSelect">| Prop | Tipo | Descrição |
|---|---|---|
| data | AppHeaderQuoteData | |
| onSelect? | () => void | Chamado ao acionar o resumo. Quando ausente, o resumo e apenas informativo (nao clicavel). |
AppHeaderIconButtonPropsestende React.ButtonHTMLAttributes<HTMLButtonElement>| Prop | Tipo | Descrição |
|---|---|---|
| icon | React.ReactNode | Icone do botao. Produto usa Material Symbols, nunca lucide: chega pronto via prop. |
| label | string | Nome acessivel do botao (nao ha texto visivel). |
| badgeCount? | number | Contagem exibida no badge de notificacao. Omitido ou zero esconde o badge. |
AppHeaderConnectionStatusPropsestende React.ButtonHTMLAttributes<HTMLButtonElement>| Prop | Tipo | Descrição |
|---|---|---|
| icon? | React.ReactNode | Icone de status. Produto usa Material Symbols, nunca lucide: chega pronto via prop. |
| label | string | Texto visivel e nome acessivel (ex.: "5/6 Conexoes"). |
AppHeaderWindowControlsPropsestende React.HTMLAttributes<HTMLDivElement>| Prop | Tipo | Descriçã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. Aceitalogo?: ReactNode; semlogo, 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. Recebeitems: AppHeaderNavItem[]({ value, label, icon? }), maisvalue/onValueChange(selecao controlada). Veja a nota sobre a decisao de nao usarNavigationMenuabaixo.AppHeaderSearch(data-slot="app-header-search"): o gatilho de busca. E um botao, nao umInput: 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. Recebedata: AppHeaderQuoteData(ticker,progressde 0 a 100,pnledaily, cada um comdirection: "up" | "down") e umonSelect?opcional. SemonSelect, e so informativo; comonSelect, virarole="button"navegavel por teclado.AppHeaderIconButton(data-slot="app-header-icon-button"): botao de icone generico, usado para notificacoes, perfil, configuracoes e layouts. Recebeicon,label(nome acessivel) ebadgeCount?(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), comonMinimize/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 proparia-labeldoAppHeaderNav). - Cada
AppHeaderIconButtontemaria-labelobrigatorio (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. AppHeaderQuoteso vira interativo (role="button",tabIndex, navegavel por Enter/Espaco) quandoonSelecte informado; sem callback, e puramente informativo.AppHeaderWindowControlse umrole="toolbar"comaria-label="Controles da janela"; cada botao temaria-labelproprio (Minimizar/Restaurar/Fechar), customizavel via proplabelspara 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 oaria-labeldoAppHeaderQuotedescreve 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