@aurea-uds/react 0.19.1 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/actions.d.ts CHANGED
@@ -39,9 +39,8 @@ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>, Re
39
39
  rel?: string;
40
40
  download?: boolean | string;
41
41
  /**
42
- * @deprecated Use `<Toggle>` instead. Pesquisado em 18/08/2026 nas doze referências (MUI,
43
- * Fluent 2, React Aria, Spectrum, Carbon, Radix/Base UI, shadcn, ReUI, PrimeReact, HeroUI,
44
- * Cedar, APG): **nenhuma** põe o estado de pressionado no botão comum — todas têm um
42
+ * @deprecated Use `<Toggle>` instead. Pesquisado em 18/08/2026 nas doze referências (entre
43
+ * elas o motor Base UI e o APG): **nenhuma** põe o estado de pressionado no botão comum — todas têm um
45
44
  * componente separado, e o nosso é o `Toggle`. Manter os dois é dois caminhos para a mesma
46
45
  * coisa, que é o "qual eu uso?" que denuncia recurso duplicado.
47
46
  * A diferença de verdade: aqui VOCÊ guarda o estado e isto só pinta e anuncia; o `Toggle`
package/dist/actions.js CHANGED
@@ -58,8 +58,8 @@ export const Button = forwardRef(function Button({ variant, appearance, tone, si
58
58
  // 🔴 OCUPADO TROCA, NÃO ACRESCENTA (01/10/2026, achado pelo Victor no aureauds.dev): a rodinha
59
59
  // entrava ANTES do ícone, e no `IconButton` — 36 de largura fixa — rodinha e glifo não cabiam:
60
60
  // medido no catálogo, a rodinha começava 4px FORA do botão, à esquerda, com o disquete ainda ao
61
- // lado. O HeroUI troca (exemplo "Loading State" da doc do Button 3.2.6:
62
- // `isPending ? <Spinner/> : <Paperclip/>`). Aqui também: ocupado, a rodinha toma o lugar do ícone
61
+ // lado. A referência troca (no exemplo de estado ocupado da doc do botão dela, a rodinha
62
+ // entra no lugar do ícone). Aqui também: ocupado, a rodinha toma o lugar do ícone
63
63
  // da frente; e sem conteúdo (o `IconButton` ocupado) o invólucro vazio some, senão o `gap` dele
64
64
  // empurraria a rodinha para fora do centro. Fora do estado ocupado o HTML é o mesmo de antes.
65
65
  const temConteudo = children != null && children !== false;
@@ -67,7 +67,7 @@ export const Button = forwardRef(function Button({ variant, appearance, tone, si
67
67
  // INERTE ≠ DESABILITADO, e a diferença é medida (M4, 13/08/2026): `disabled` tira o botão da
68
68
  // ordem de foco, então quem navega por teclado nunca alcança a explicação de POR QUE não dá — e
69
69
  // "não dá porque você não tem permissão" é justamente o caso em que a explicação é tudo. O
70
- // embrulho de <span> que o MUI documenta resolve o ponteiro e não resolve o teclado (span nasce
70
+ // embrulho de <span> que uma das referências documenta resolve o ponteiro e não resolve o teclado (span nasce
71
71
  // com tabIndex -1, medido). Com `aria-disabled` o botão continua focável e anunciado como
72
72
  // desabilitado, e é ESTE componente que tem de barrar a ativação — o atributo é só semântica.
73
73
  // Mesmo remendo do AUD-0004, que já barrava o link desabilitado; aqui ele alcança o <button>.
@@ -118,7 +118,7 @@ function temConteudoVisivel(children) {
118
118
  // ESTE é o toggle da Aurea. O `pressed` do `Button` está DEPRECIADO em favor dele (0.4.0,
119
119
  // sai na 1.0): as doze referências pesquisadas em 18/08/2026 têm componente separado, e
120
120
  // nenhuma põe o estado no botão comum.
121
- // E a REGRA QUE FALTAVA ESTAR ESCRITA AQUI, do Adobe Spectrum e do APG: **o rótulo não muda
121
+ // E a REGRA QUE FALTAVA ESTAR ESCRITA AQUI, de uma das referências e do APG: **o rótulo não muda
122
122
  // entre os estados**. Se o texto vira "Mute"/"Unmute" ou "Play"/"Pause", não é toggle — é
123
123
  // botão de ação, porque quem lê tela ouve o rótulo NOVO e o estado ao mesmo tempo e não sabe
124
124
  // se o botão descreve o que é ou o que fará.
@@ -145,7 +145,7 @@ export const ThemeToggle = forwardRef(function ThemeToggle({ className, ...props
145
145
  const s = useAureaStrings();
146
146
  const escuro = theme === "dark";
147
147
  // O corpo do `IconButton`, escrito aqui só para o glifo sair na forma CHEIA (ADR-0053: a lua e o
148
- // sol cheios, como os do Carbon aprovados pela imagem em 25/09/2026). O `IconButton` público não
148
+ // sol cheios, como os do conjunto de ícones anterior, aprovados pela imagem em 25/09/2026). O `IconButton` público não
149
149
  // tem peso de ícone.
150
150
  return _jsx(Button, { ref: ref, variant: "ghost", className: cx("btn-icon", escuro ? "theme-toggle-sun" : "theme-toggle-moon", className), "aria-label": escuro ? s.themeToLight : s.themeToDark, onClick: toggleTheme, ...props, children: _jsx(Icon, { name: escuro ? "sun" : "moon", weight: "fill" }) });
151
151
  });
package/dist/agents.js CHANGED
@@ -9,13 +9,13 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
9
9
  // `DIRECTION.md` se declara "ilustrativo, não-vinculante", então tirar dali uma
10
10
  // categoria é decisão, não dedução.
11
11
  //
12
- // PROCEDÊNCIA (BUILDING.md passo 2): estes três saem de `agents-kit-main`
13
- // (`components/agents-ui/agent-card.tsx`, `agent-status-panel.tsx`) e do `DetailsView/`
14
- // do `agent-prism-main`. As sete referências antigas NÃO têm esta família — foi por
12
+ // PROCEDÊNCIA (BUILDING.md passo 2): estes três saem de uma referência de agentes (o cartão
13
+ // de agente e o painel de estado) e da vista de detalhes
14
+ // de outra. As sete referências antigas NÃO têm esta família — foi por
15
15
  // isso que a Parte H ficou bloqueada até 08/08/2026.
16
16
  //
17
- // Escopo menor que o da referência (passo 5): o `AgentCard` de lá despacha ações por
18
- // STRING (`onAction: (action: string) => void`), o que troca o compilador por um acordo
17
+ // Escopo menor que o da referência (passo 5): o cartão de lá despacha ações por
18
+ // STRING (uma função que recebe o nome da ação como texto), o que troca o compilador por um acordo
19
19
  // verbal. Aqui as ações entram como nó, e quem monta o botão sabe o que ele faz.
20
20
  import React from "react";
21
21
  import { cx, useAureaStrings } from "./internal.js";
@@ -45,7 +45,7 @@ export function AgentCard({ name, description, avatarSrc, model, state, capabili
45
45
  return _jsxs("article", { className: cx("card", "agent-card", className), ...props, children: [_jsxs("header", { className: "agent-card-head", children: [_jsx(Avatar, { src: avatarSrc, alt: name, fallback: name.slice(0, 2), size: "md" }), _jsxs("div", { className: "agent-card-id", children: [_jsx("strong", { children: name }), model && _jsx("span", { className: "hint", children: model })] }), state && _jsx(AgentStatus, { state: state })] }), description && _jsx("p", { className: "agent-card-desc", children: description }), !!capabilities?.length && _jsx("ul", { className: "agent-caps", children: capabilities.map(c => _jsxs("li", { className: "agent-cap", title: c.description, children: [c.icon && _jsx(Icon, { name: c.icon, size: "sm" }), _jsx("span", { children: c.name })] }, c.name)) }), actions && _jsx("footer", { className: "agent-card-actions", children: actions })] });
46
46
  }
47
47
  // AgentInspector — o detalhe: configuração, ferramentas, instruções.
48
- // A anatomia é a do `DetailsView/` do `agent-prism`: cabeçalho + seções rotuladas, com
48
+ // A anatomia é a da vista de detalhes de uma das referências de agentes: cabeçalho + seções rotuladas, com
49
49
  // o valor cru disponível. Aqui as seções são `DataList`, que já existe e já tem pele —
50
50
  // e o corpo livre entra como filho, para inspecionar o que a ficha não previu.
51
51
  //
@@ -64,10 +64,10 @@ export function AgentInspector({ title, sections, children, className, ...props
64
64
  //
65
65
  // O passo que tem corpo é um `<details>` nativo, o mesmo idioma do `Accordion`: dobrar
66
66
  // e desdobrar já é comportamento de plataforma, com teclado e ARIA, e a referência
67
- // gasta um `Collapsible` de biblioteca para chegar no mesmo lugar.
67
+ // gasta um componente dobrável de biblioteca para chegar no mesmo lugar.
68
68
  //
69
69
  // `running` marca `aria-busy` na região INTEIRA em vez de animar o texto. A referência
70
- // usa um `TextShimmer` — animação em cima do rótulo — e isso é decoração que um leitor
70
+ // usa um brilho que corre pelo texto — animação em cima do rótulo — e isso é decoração que um leitor
71
71
  // de tela não alcança e que `prefers-reduced-motion` teria de desfazer.
72
72
  //
73
73
  // Entrada e saída são `group` NOMEADO, e não `<h3>` — mesmo defeito e mesma correção do
@@ -86,10 +86,10 @@ const TAREFA = {
86
86
  };
87
87
  // TaskQueue — a fila de trabalho.
88
88
  //
89
- // ESCOPO MENOR QUE O DA REFERÊNCIA, e por fronteira, não por preguiça: o `AgentTask` de
89
+ // ESCOPO MENOR QUE O DA REFERÊNCIA, e por fronteira, não por preguiça: a tarefa de
90
90
  // lá tem 15 campos, e cinco deles pertencem a OUTROS componentes desta mesma parte —
91
- // `metrics.tokens` e `metrics.cost` são o `ModelUsage` (H11) e o `CostMeter` (H12),
92
- // `checkpoints` é o `TraceTimeline` (H9), `assignee` é o `AgentCard` (H1). Absorvê-los
91
+ // a contagem de tokens e o custo são o `ModelUsage` (H11) e o `CostMeter` (H12),
92
+ // os pontos de controle são o `TraceTimeline` (H9), o responsável é o `AgentCard` (H1). Absorvê-los
93
93
  // aqui faria a fila responder por quatro contratos e nenhum deles direito.
94
94
  export function TaskQueue({ tasks, label, onRetry, className, ...props }) {
95
95
  const s = useAureaStrings();
@@ -150,7 +150,7 @@ export function EventStream({ events, label, follow, className, ...props }) {
150
150
  // (end-start)/(max-min) de largura.
151
151
  //
152
152
  // O que NÃO entrou: as ONZE cores por categoria de span da referência
153
- // (`llm_call`, `tool_execution`, `retrieval`…). Cor por categoria numa paleta travada é
153
+ // (chamada de modelo, execução de ferramenta, busca…). Cor por categoria numa paleta travada é
154
154
  // o mesmo defeito que o H.a recusou; `kind` entra como TEXTO, que é legível também por
155
155
  // quem não distingue as cores.
156
156
  export function TraceTimeline({ spans, label, className, ...props }) {
@@ -174,24 +174,24 @@ export function HealthMatrix({ entries, label, className, ...props }) {
174
174
  // ─────────────────────────────────────────────────────────────────────────────
175
175
  // H.e — custo e memória: quanto se consumiu, contra que teto, e o que ficou guardado.
176
176
  //
177
- // PROCEDÊNCIA: `langfuse-main/web/src/features/dashboard/components/` — o
178
- // `ModelUsageChart.tsx` (a métrica total no topo e a quebra por modelo), o
179
- // `ModelCostTable.tsx` (as colunas modelo × tokens × custo, com o número à direita), o
180
- // `TotalMetric.tsx` (número grande + descrição, e é UMA linha de arranjo) e o
181
- // `cards/BarListChartArea.tsx` (a lista de barras horizontais com rótulo de valor).
182
- // Mais `agent-prism-main/packages/ui/src/components/{TokensBadge,PriceBadge}.tsx` — o par
183
- // de unidades desta família, contagem e preço — e `agents-kit-main/components/agents-ui/
184
- // agent-status-panel.tsx`, que traz a tarifa por 1k tokens com entrada e saída separadas.
177
+ // PROCEDÊNCIA: o painel de uma referência de observabilidade de LLM — o
178
+ // gráfico de uso por modelo (a métrica total no topo e a quebra por modelo), a
179
+ // tabela de custo por modelo (as colunas modelo × tokens × custo, com o número à direita), a
180
+ // métrica total (número grande + descrição, e é UMA linha de arranjo) e a
181
+ // lista de barras (a lista de barras horizontais com rótulo de valor).
182
+ // Mais os selos de tokens e de preço de uma referência de agentes — o par
183
+ // de unidades desta família, contagem e preço — e o painel de estado de agente de outra,
184
+ // que traz a tarifa por 1k tokens com entrada e saída separadas.
185
185
  //
186
186
  // O `MemoryLedger` NÃO TEM REFERÊNCIA, e é o caso declarado no `BUILDING.md` §1: nasce de
187
187
  // pesquisa registrada no `REFERENCES.md` e de composição. A pesquisa está lá com data.
188
188
  // Formatação de número: `Intl` é a plataforma, e o locale entra como prop com default
189
189
  // FIXO. O default fixo é o que mantém a saída determinística no SSR do catálogo e no gate
190
190
  // de pixel — locale do ambiente mudaria o texto entre a máquina e a CI. A referência faz
191
- // igual: o `costFormatter` do langfuse é `Intl.NumberFormat("en-US")` pregado, medido em
192
- // `web/src/utils/numbers.ts`.
191
+ // igual: o formatador de custo dela é `Intl.NumberFormat("en-US")` pregado, medido no
192
+ // fonte dela.
193
193
  const compacto = (n, locale) => new Intl.NumberFormat(locale, { notation: "compact", maximumFractionDigits: 2 }).format(n);
194
- // Duas casas fixas é o que o `costFormatter` da referência usa, e aqui isso MENTE: custo de
194
+ // Duas casas fixas é o que o formatador de custo da referência usa, e aqui isso MENTE: custo de
195
195
  // modelo cai em fração de centavo o tempo todo, e "$0.00" para um gasto real de US$ 0,004
196
196
  // apaga o número justamente no componente que existe para vigiá-lo.
197
197
  const dinheiro = (n, currency, locale) => new Intl.NumberFormat(locale, { style: "currency", currency, minimumFractionDigits: 2, maximumFractionDigits: n !== 0 && Math.abs(n) < 0.01 ? 6 : 2 }).format(n);
@@ -202,8 +202,8 @@ const dinheiro = (n, currency, locale) => new Intl.NumberFormat(locale, { style:
202
202
  // levou quanto". No `CostMeter` o teto vem de fora, e a pergunta é "quanto ainda cabe".
203
203
  // Trocar um pelo outro é mostrar orçamento onde não existe orçamento nenhum.
204
204
  //
205
- // ESCOPO MENOR QUE O DA REFERÊNCIA (passo 5): as quatro abas de lá (`Cost by model`,
206
- // `Cost by type`, `Usage by model`, `Usage by type`) existem porque são quatro CONSULTAS
205
+ // ESCOPO MENOR QUE O DA REFERÊNCIA (passo 5): as quatro abas de lá (custo e uso,
206
+ // cada um por modelo e por tipo) existem porque são quatro CONSULTAS
207
207
  // diferentes no produto dela. Aqui a dimensão é uma prop e os dados chegam prontos. Também
208
208
  // ficaram fora o seletor de modelos em popover e a série temporal — a série é o `Chart`,
209
209
  // que já existe, e embutir um segundo gráfico aqui duplicaria aquele contrato.
@@ -212,7 +212,7 @@ export function ModelUsage({ entries, metric = "tokens", label, currency = "USD"
212
212
  const valor = (e) => (metric === "cost" ? e.cost : metric === "requests" ? e.requests : e.tokens) ?? 0;
213
213
  const fmt = (n) => metric === "cost" ? dinheiro(n, currency, locale) : compacto(n, locale);
214
214
  const total = entries.reduce((a, e) => a + valor(e), 0);
215
- // Ordem decrescente pela métrica, como a referência (`orderBy` em `ModelCostTable`): uma
215
+ // Ordem decrescente pela métrica, como a referência (a ordenação da tabela de custo dela): uma
216
216
  // lista de barras fora de ordem obriga a varrer tudo para achar o maior, que é a única
217
217
  // coisa que ela existe para responder de relance. Cópia, não `sort` no array de quem chamou.
218
218
  const linhas = [...entries].sort((a, b) => valor(b) - valor(a));
@@ -223,10 +223,10 @@ export function ModelUsage({ entries, metric = "tokens", label, currency = "USD"
223
223
  }
224
224
  // CostMeter — o gasto contra um TETO.
225
225
  //
226
- // Os dois limites são os do LiteLLM, que é o padrão de mercado de controle de custo de LLM
226
+ // Os dois limites são os do padrão de mercado de controle de custo de LLM,
227
227
  // medido em 09/08/2026 (pesquisa registrada no `REFERENCES.md`): o limite RÍGIDO bloqueia,
228
- // o limite BRANDO só avisa. Nenhuma das nove referências locais tem orçamento — o langfuse
229
- // OSS mostra custo e não teto —, então isto veio pelo passo 4 do `BUILDING.md`, pesquisado
228
+ // o limite BRANDO só avisa. Nenhuma das nove referências locais tem orçamento — a referência
229
+ // de observabilidade, na versão aberta, mostra custo e não teto —, então isto veio pelo passo 4 do `BUILDING.md`, pesquisado
230
230
  // antes de escrever, e não de memória.
231
231
  //
232
232
  // Sem `softLimit` NÃO EXISTE estado de aviso. A tentação era derivar um em 80% do teto;
@@ -244,9 +244,9 @@ const LANCAMENTO = {
244
244
  };
245
245
  // MemoryLedger — o que o agente guardou, esqueceu ou lembrou, e DE ONDE veio.
246
246
  //
247
- // É o único da Parte H sem referência no mundo aberto: o ADE do Letta só abre o servidor, o
248
- // OpenMemory do mem0 está sendo descontinuado e o painel do mem0 é só na nuvem. Medido em
249
- // 08/08/2026 e reconfirmado em 09/08.
247
+ // É o único da Parte H sem referência no mundo aberto: dos produtos de memória de agentes
248
+ // pesquisados, um só abre o servidor, e o outro tem a versão aberta sendo descontinuada e o
249
+ // painel só na nuvem. Medido em 08/08/2026 e reconfirmado em 09/08.
250
250
  //
251
251
  // Livro-razão é APENDE-SÓ, e é isso que o separa de uma lista de memórias: `forgotten` não
252
252
  // tira a linha, registra o esquecimento. Uma tela que apaga a linha ao esquecer perde
@@ -271,8 +271,8 @@ const RECADO = {
271
271
  // tem um remetente e um destinatário, e é a passagem entre os dois que se está lendo. Um
272
272
  // `MessageList` com dois autores não diz quem entregou o quê a quem.
273
273
  //
274
- // O que NÃO entrou: as seis cores por intenção do `agent-routing-hub` (`technical` ciano,
275
- // `billing` âmbar, `sales` ardósia…). É a TERCEIRA vez que esta parte recusa a mesma coisa —
274
+ // O que NÃO entrou: as seis cores por intenção do painel de encaminhamento da referência (ciano,
275
+ // âmbar, ardósia…). É a TERCEIRA vez que esta parte recusa a mesma coisa —
276
276
  // depois das onze de span no H.d e das seis de estado no H.a. Cor por categoria numa paleta
277
277
  // travada não é legível para quem não separa as cores. A `kind` entra como palavra, num selo.
278
278
  export function InterAgentMessage({ messages, label, className, ...props }) {
@@ -284,7 +284,7 @@ export function InterAgentMessage({ messages, label, className, ...props }) {
284
284
  }
285
285
  // AutomationCard — a regra que roda sozinha: QUANDO isto, ENTÃO aquilo.
286
286
  //
287
- // A anatomia é a do `AutomationSidebar` do langfuse, medida: nome, gatilho (fonte de evento) e
287
+ // A anatomia é a da lateral de automações da referência de observabilidade, medida: nome, gatilho (fonte de evento) e
288
288
  // ação (tipo), mais o estado ativo/inativo. É isso que separa este cartão do `AgentCard`, que é
289
289
  // identidade, e da `TaskQueue`, que é trabalho enfileirado: uma automação é uma REGRA, e regra
290
290
  // é uma condição e uma consequência.
package/dist/calendar.js CHANGED
@@ -13,9 +13,9 @@ import { cx } from "./internal.js";
13
13
  const NOMES = { months: "calendar-months", month_caption: "calendar-caption" };
14
14
  export function Calendar({ label, className, classNames, ...props }) {
15
15
  const grade = _jsx(DayPicker
16
- // Grade cheia por padrão, como o shadcn: mês com buraco nas pontas treme ao trocar de mês.
16
+ // Grade cheia por padrão, como naquela referência: mês com buraco nas pontas treme ao trocar de mês.
17
17
  , {
18
- // Grade cheia por padrão, como o shadcn: mês com buraco nas pontas treme ao trocar de mês.
18
+ // Grade cheia por padrão, como naquela referência: mês com buraco nas pontas treme ao trocar de mês.
19
19
  showOutsideDays: true, ...props, classNames: { ...NOMES, root: cx("calendar", className), ...classNames } });
20
20
  // O motor já nomeia a GRADE com o mês ("August 2026"). O que ele não sabe é para que serve
21
21
  // ESTE calendário — "de" e "até" lado a lado soariam os dois "August 2026". É o que `label`
package/dist/chart.js CHANGED
@@ -4,17 +4,17 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
4
  // componente que precisa do `recharts`, que é peer OPCIONAL. Se morasse em data-display.tsx,
5
5
  // quem importa Table baixaria um motor de gráfico inteiro — que é o achado A5 visto de perto.
6
6
  //
7
- // NÃO ESCREVEMOS MOTOR DE GRÁFICO. Duas das quatro referências (shadcn/ui e Untitled UI React)
7
+ // NÃO ESCREVEMOS MOTOR DE GRÁFICO. Duas das quatro referências
8
8
  // envelopam o MESMO motor, o Recharts, e nenhuma das quatro desenha eixo à mão. O que é nosso
9
9
  // aqui é só a pele: a caixa, o tooltip e a legenda. Escala, eixo, curva e interação são dele.
10
10
  //
11
11
  // O QUE FICOU DE FORA, e por quê (BUILDING.md passo 5 — escopo menor que o da referência):
12
- // • o `ChartConfig` do shadcn (mapa dataKey → {label, color, theme}). MEDIDO em 01/08/2026: o
12
+ // • o `ChartConfig` de uma delas (mapa dataKey → {label, color, theme}). MEDIDO em 01/08/2026: o
13
13
  // payload que o Recharts entrega ao `content` já traz `name` (do prop `name` da série) e
14
14
  // `color` resolvido. O objeto de configuração é indireção para reconstruir o que já chega.
15
15
  // E o eixo `theme:{light,dark}` não existe aqui: `var(--chart-2)` já troca com o data-theme.
16
16
  // • o par `ChartTooltip`/`ChartTooltipContent`. No Recharts 2 o filho tinha de ser o
17
- // componente DELES, o que forçava o shadcn a reexportar o primitivo e pôr a pele no
17
+ // componente DELES, o que forçava essa referência a reexportar o primitivo e pôr a pele no
18
18
  // `content`. MEDIDO no 3.10.1: um componente NOSSO como filho é reconhecido. Então é uma
19
19
  // peça só, não duas.
20
20
  // • prop de altura. Dimensão não é número (check 23): a caixa mede pelo CSS (`.chart`), e
package/dist/data-grid.js CHANGED
@@ -25,8 +25,8 @@ import { IconButton } from "./actions.js";
25
25
  //
26
26
  // Por que os nomes `manualSorting`/`manualFiltering`/`manualPagination` são os DO
27
27
  // MOTOR e não inventados aqui: as três referências de tabela foram medidas em
28
- // 08/08/2026 e NENHUMA expõe API controlada — o shadcn guarda tudo em useState
29
- // dentro do exemplo, o Kibo põe a ordenação num átomo global (jotai) e o Untitled
28
+ // 08/08/2026 e NENHUMA expõe API controlada — uma guarda tudo em useState
29
+ // dentro do exemplo, outra põe a ordenação num átomo de estado global e a terceira
30
30
  // é apresentação. Não havia anatomia para copiar; o vocabulário veio do contrato
31
31
  // do motor, que é o que o consumidor já lê na documentação dele.
32
32
  //
@@ -316,7 +316,7 @@ export function DataGrid({ data, columns, label, filterable, pageSize, selectabl
316
316
  };
317
317
  const rove = (r, c) => eff.r === r && eff.c === c ? 0 : -1;
318
318
  const sortIcon = (dir) => dir === "asc" ? "caret-up" : dir === "desc" ? "caret-down" : "caret-up-down";
319
- // F5: a barra de lote. Duas referências independentes (Activepieces e Kaneo) chegam
319
+ // F5: a barra de lote. Duas referências independentes chegam
320
320
  // à MESMA anatomia — contagem, divisória, ações, e um jeito de limpar —, então é
321
321
  // ela que entra. O que não entra é o resto das duas: barra `position:fixed` sobre a
322
322
  // janela inteira (decisão da APLICAÇÃO, não de um componente que o consumidor põe
package/dist/graph.js CHANGED
@@ -13,14 +13,14 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
13
13
  //
14
14
  // ── O MOTOR, e por que este ──────────────────────────────────────────────────────────────
15
15
  // Autorizado pelo Victor em 09/08/2026, e a autorização foi RECONFIRMADA por medição depois de
16
- // eu mesmo levantar dúvida. A dúvida era boa e a resposta desfez: o `trace-graph-view/` do
17
- // langfuse — a referência mais próxima do domínio — desenha `<div>` posicionados por ELK e NÃO
16
+ // eu mesmo levantar dúvida. A dúvida era boa e a resposta desfez: a vista de grafo de rastreio
17
+ // da referência mais próxima do domínio desenha `<div>` posicionados por um motor de layout de terceiro e NÃO
18
18
  // usa React Flow, e o React Flow não faz layout nenhum, então adotá-lo não entrega um grafo
19
- // pronto. O que decidiu foi o ALVO, que o Victor nomeou: uma aplicação tipo n8n. Aí a conta
19
+ // pronto. O que decidiu foi o ALVO, que o Victor nomeou: uma aplicação de automação de fluxos. Aí a conta
20
20
  // vira outra, e ela é medida:
21
- // • a `activepieces-main`, que já está em `Referencia/` e é concorrente direta do n8n, usa
22
- // `@xyflow/react` 12.3.5 — está no `package.json` dela;
23
- // • o próprio n8n usa **Vue Flow**, o irmão Vue do React Flow, da mesma equipe xyflow.
21
+ // • uma das referências, que já está em `Referencia/` e é concorrente direta do líder desse tipo de aplicação, usa
22
+ // `@xyflow/react` — está no `package.json` dela;
23
+ // • o próprio líder usa o irmão Vue do React Flow, da mesma equipe xyflow.
24
24
  // Grafo de LEITURA não precisa de motor. EDITOR precisa, e o padrão de mercado para este
25
25
  // editor é o xyflow. Registro completo no `REFERENCES.md`.
26
26
  //
@@ -50,7 +50,7 @@ import { cx, useAureaStrings } from "./internal.js";
50
50
  //
51
51
  // ponytail: sem minimização de cruzamento de arestas — grafo denso vai desenhar linhas se
52
52
  // cruzando, e isso é aceitável para dependência (dezenas de nós), não para mil. O caminho de
53
- // subida é o `elkjs`, que é o que o langfuse usa, e ele é DEPENDÊNCIA NOVA: entra com
53
+ // subida é uma biblioteca de layout automático de grafos, a que a referência usa, e ela é DEPENDÊNCIA NOVA: entra com
54
54
  // autorização, não de contrabando.
55
55
  const LARGURA = 180, ALTURA = 52, VAO_X = 90, VAO_Y = 24;
56
56
  // O VÃO ENTRE COLUNAS CRESCE COM O RÓTULO (A-09, 23/09/2026). Com o rótulo legível, a primeira
@@ -112,12 +112,12 @@ function dispor(nodes, edges) {
112
112
  return { posicoes, extensao: { larg: colunas * LARGURA + (colunas - 1) * vaoX, alt: linhas * ALTURA + (linhas - 1) * VAO_Y } };
113
113
  }
114
114
  // O nó é NOSSO, e é o ponto em que este componente deixa de ser "React Flow com outra cor".
115
- // O `GraphNode.tsx` do langfuse declara o motivo em uma linha — *"Real-HTML accessibility (the
116
- // win over the old canvas renderer)"* —: nó desenhado em canvas não existe para o teclado nem
115
+ // O componente de nó da referência declara o motivo em uma linha — a acessibilidade de HTML de
116
+ // verdade, que é a vantagem sobre o antigo desenho em canvas —: nó desenhado em canvas não existe para o teclado nem
117
117
  // para o leitor de tela. Aqui ele é `<button>` de verdade quando dá para selecionar.
118
118
  //
119
- // O que NÃO entrou: as DEZ cores por tipo de nó da referência (`AGENT` roxo, `TOOL` laranja,
120
- // `GENERATION` magenta…). É a quarta vez que esta parte recusa a mesma coisa. `kind` sai como
119
+ // O que NÃO entrou: as DEZ cores por tipo de nó da referência (agente roxo, ferramenta laranja,
120
+ // geração magenta…). É a quarta vez que esta parte recusa a mesma coisa. `kind` sai como
121
121
  // TEXTO, que é legível também por quem não separa as cores.
122
122
  function NoAurea({ data }) {
123
123
  const d = data;
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export { cx, defaultStrings, ptBR, defaultSpriteUrl, gridStateToParams, gridStat
2
2
  export { useAureaStrings, useSpriteUrl, useTheme, useDensity } from "./internal.js";
3
3
  export { type Responsive, type Breakpoint, type ContainerBreakpoint, type Orientation, ESCALA, ESCALA_CONTAINER } from "./pure.js";
4
4
  export { ContainerScope, useValorResponsivo } from "./responsivo-runtime.js";
5
- export { AspectRatio, InputGroup, InputGroupAddon, Label, Card, Stack, Cluster, Grid, KPI, DataList, Timeline, Prose, Text, Heading, Paragraph, Code, Badge, Progress, Skeleton, AvatarGroup, LogStream, MediaPlayerShell, Topbar, Kbd, Textarea, Checkbox, Radio, Switch, Range, formatBadgeCount, type BadgeVariant, type BadgeEmphasis, type BadgeSize, type BadgePlacement, type BadgeProps, type ProgressProps, type ProgressTone, type AvatarSize, type TopbarVariant, type TextProps, type HeadingProps, type ParagraphProps, type CodeProps, type TypographyType, type TypographyColor, type TypographyWeight, type TypographyAlign, type HeadingLevel, type ParagraphSize } from "./markup.js";
5
+ export { AspectRatio, InputGroup, InputGroupAddon, Label, Card, Stack, Cluster, Grid, Container, Section, KPI, DataList, Timeline, Prose, Text, Heading, Paragraph, Code, Badge, Progress, Skeleton, AvatarGroup, LogStream, MediaPlayerShell, Header, Topbar, Kbd, Textarea, Checkbox, Radio, Switch, Range, formatBadgeCount, type BadgeVariant, type BadgeEmphasis, type BadgeSize, type BadgePlacement, type BadgeProps, type ProgressProps, type ProgressTone, type AvatarSize, type HeaderVariant, type HeaderProps, type TopbarVariant, type SectionVariant, type SectionFooterGroup, type TextProps, type HeadingProps, type ParagraphProps, type CodeProps, type TypographyType, type TypographyColor, type TypographyWeight, type TypographyAlign, type HeadingLevel, type ParagraphSize } from "./markup.js";
6
6
  export * from "./system.js";
7
7
  export * from "./actions.js";
8
8
  export * from "./feedback.js";
package/dist/index.js CHANGED
@@ -51,7 +51,7 @@ export { ContainerScope, useValorResponsivo } from "./responsivo-runtime.js";
51
51
  // inteiro). O que muda é de ONDE ele vem — do módulo com a diretiva —, e aí ele volta a chegar
52
52
  // como referência de CLIENTE e os 118,5 KB voltam com ele. Não é um erro: é o ganho do item O1
53
53
  // se desfazendo em silêncio. É isso, exatamente isso, que o check 35 pega.
54
- export { AspectRatio, InputGroup, InputGroupAddon, Label, Card, Stack, Cluster, Grid, KPI, DataList, Timeline, Prose, Text, Heading, Paragraph, Code, Badge, Progress, Skeleton, AvatarGroup, LogStream, MediaPlayerShell, Topbar, Kbd, Textarea, Checkbox, Radio, Switch, Range, formatBadgeCount } from "./markup.js";
54
+ export { AspectRatio, InputGroup, InputGroupAddon, Label, Card, Stack, Cluster, Grid, Container, Section, KPI, DataList, Timeline, Prose, Text, Heading, Paragraph, Code, Badge, Progress, Skeleton, AvatarGroup, LogStream, MediaPlayerShell, Header, Topbar, Kbd, Textarea, Checkbox, Radio, Switch, Range, formatBadgeCount } from "./markup.js";
55
55
  export * from "./system.js";
56
56
  export * from "./actions.js";
57
57
  export * from "./feedback.js";
@@ -11,7 +11,7 @@ export interface FieldProps extends HTMLAttributes<HTMLDivElement>, RefAttribute
11
11
  error?: ReactNode;
12
12
  /** B-12 (24/09/2026): texto de ajuda que precisa de uma FRASE — mora embaixo do controle, onde
13
13
  * cabe, e não divide a linha do rótulo. O `hint` continua o que é: nota curta ao lado do rótulo
14
- * ("opcional", "em MB"). É o lugar do `Description` do HeroUI e da `description` que o
14
+ * ("opcional", "em MB"). É o lugar da descrição da referência e da `description` que o
15
15
  * `Checkbox` desta casa já tem. Entra no `aria-describedby` na ordem da tela: hint, descrição,
16
16
  * erro. */
17
17
  description?: ReactNode;
@@ -68,7 +68,7 @@ export declare function OTPField({ length, value, defaultValue, onValueChange, m
68
68
  id?: string;
69
69
  className?: string;
70
70
  }): React.JSX.Element;
71
- export declare function SegmentedControl({ items, value, onChange, label }: {
71
+ export declare function SegmentedControl({ items, value, onChange, label, fullWidth }: {
72
72
  items: Array<{
73
73
  value: string;
74
74
  label: ReactNode;
@@ -76,6 +76,7 @@ export declare function SegmentedControl({ items, value, onChange, label }: {
76
76
  value: string;
77
77
  onChange: (v: string) => void;
78
78
  label?: string;
79
+ fullWidth?: boolean;
79
80
  }): React.JSX.Element;
80
81
  export interface ComboboxOption {
81
82
  value: string;
@@ -133,9 +133,9 @@ export function Field({ label, hint, description, error, children, className, id
133
133
  // Form (M1): o formulário que EXIBE erro, e não o que decide o que é erro.
134
134
  //
135
135
  // A divisão saiu de pesquisa e da medição dos consumidores (13/08/2026). O padrão de mercado é
136
- // `react-hook-form` + `zod`, e é o que o shadcn embrulha — mas embrulhar isso aqui obrigaria TODO
137
- // projeto que usa a Aurea a usar react-hook-form, inclusive os que já validam de outro jeito (um
138
- // consumidor real valida com zod em server action, sem biblioteca de formulário no cliente).
136
+ // uma biblioteca de formulário com uma de esquema, e é o que uma das referências embrulha — mas embrulhar isso aqui obrigaria TODO
137
+ // projeto que usa a Aurea a usar essa biblioteca de formulário, inclusive os que já validam de outro jeito (um
138
+ // consumidor real valida com a biblioteca de esquema em server action, sem biblioteca de formulário no cliente).
139
139
  // Dependência nova também é decisão do Victor pelo BUILDING.md §3.3, e ela não foi necessária:
140
140
  // o `Form` do Base UI — motor que a Aurea JÁ paga desde a Fase 2 — declara no próprio tipo que
141
141
  // `errors` são "validation errors returned externally, typically after submission by a server or
@@ -232,9 +232,13 @@ export function OTPField({ length, value, defaultValue, onValueChange, mask, dis
232
232
  // é o rádio e o input é `aria-hidden`. Comportamento idêntico: Enter não seleciona, Espaço
233
233
  // seleciona, a seta move E seleciona. O que sai é a camada sintética que o motor punha por cima
234
234
  // da ativação nativa do `<button>`.
235
- export function SegmentedControl({ items, value, onChange, label }) {
235
+ //
236
+ // `fullWidth` (A5, 06/10/2026): o mesmo nome e o mesmo desenho do nativo — o controle ocupa a
237
+ // linha e cada segmento CRESCE a partir do rótulo, sem encolher abaixo dele. É como o grupo
238
+ // de botões alternáveis da referência ocupa a linha.
239
+ export function SegmentedControl({ items, value, onChange, label, fullWidth }) {
236
240
  const s = useAureaStrings();
237
- return _jsx(BaseRadioGroup, { className: "segmented", "aria-label": label ?? s.optionsLabel, value: value, onValueChange: v => onChange(String(v)), children: items.map(i => _jsx(BaseRadio.Root, { value: i.value, className: i.value === value ? "active" : undefined, nativeButton: true, render: _jsx("button", { type: "button" }), children: i.label }, i.value)) });
241
+ return _jsx(BaseRadioGroup, { className: fullWidth ? "segmented segmented-full" : "segmented", "aria-label": label ?? s.optionsLabel, value: value, onValueChange: v => onChange(String(v)), children: items.map(i => _jsx(BaseRadio.Root, { value: i.value, className: i.value === value ? "active" : undefined, nativeButton: true, render: _jsx("button", { type: "button" }), children: i.label }, i.value)) });
238
242
  }
239
243
  const ehAgrupado = (items) => items != null && items.length > 0 && typeof items[0] === "object" && items[0] != null && "items" in items[0];
240
244
  // UM renderizador e UMA lista para os dois combobox: duas cópias da mesma árvore é como a
package/dist/internal.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- // A diretiva na LINHA 1, como as referências a escrevem (Base UI e shadcn/ui, medidos em
2
+ // A diretiva na LINHA 1, como as referências a escrevem (o Base UI e outra delas, medidos em
3
3
  // 06/08/2026) — Parte A do PLANO-1.0. Este módulo chama `createContext`, que é API só de
4
4
  // cliente: sem a diretiva, `import {Button} from "@aurea-uds/react"` dentro de um componente
5
5
  // de servidor quebrava na hora, e quebrava no consumidor.
@@ -1,6 +1,6 @@
1
1
  import { type HTMLAttributes, type RefAttributes, type ReactNode } from "react";
2
2
  import { type Orientation, type Responsive } from "./pure.js";
3
- import { type TopbarVariant, type SidebarVariant, type SidebarItem } from "./navigation.js";
3
+ import { type HeaderVariant, type SidebarVariant, type SidebarItem } from "./navigation.js";
4
4
  export declare function AppShell({ brand, navigation, navItems, currentNavId, navLabel, topbar, topbarVariant, topbarDivider, sidebarVariant, sidebarCollapsed, sidebarCollapsible, defaultSidebarCollapsed, onSidebarCollapsedChange, contentVariant, children, className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement> & {
5
5
  brand: ReactNode;
6
6
  navigation?: ReactNode;
@@ -8,7 +8,7 @@ export declare function AppShell({ brand, navigation, navItems, currentNavId, na
8
8
  currentNavId?: string;
9
9
  navLabel?: string;
10
10
  topbar?: ReactNode;
11
- topbarVariant?: Exclude<TopbarVariant, "pill">;
11
+ topbarVariant?: Exclude<HeaderVariant, "pill">;
12
12
  topbarDivider?: boolean;
13
13
  sidebarVariant?: SidebarVariant;
14
14
  /** A lateral em trilha de ícones. Controlado: quem passa decide (e o `onSidebarCollapsedChange` avisa). */
@@ -11,7 +11,7 @@ import { useValorResponsivo } from "./responsivo-runtime.js";
11
11
  import { ESCALA } from "./escala.js";
12
12
  import { IconButton } from "./actions.js";
13
13
  import { Tooltip } from "./overlays.js";
14
- import { Sidebar, Topbar } from "./navigation.js";
14
+ import { Sidebar, Header } from "./navigation.js";
15
15
  // ── Auxiliar de topo: mora ANTES do primeiro export, e a posição é obrigatória ───────────────
16
16
  // O check 22 mede o corpo de um componente do `export` dele até o PRÓXIMO export — fatia longa
17
17
  // de propósito, porque a implementação de vários componentes daqui continua num auxiliar não
@@ -125,8 +125,8 @@ function useGavetaFechaNoDesktop() {
125
125
  // AN-01 (03/10/2026): O BOTÃO DE RECOLHER E A TRILHA SOZINHA. Um consumidor viu numa janela de 1508:
126
126
  // a lateral sempre aberta, sem botão, e diminuir a janela não a recolhia — só virava gaveta abaixo de
127
127
  // 1024. O modo trilha existia (`sidebarCollapsed`, `.sidebar-collapsed`), mas só controlado e sem
128
- // gatilho. A referência é a `Sidebar` do shadcn que o ReUI usa no `c-sidebar-2` (o HeroUI não tem
129
- // moldura de app): estado aberto/recolhido, controlado e não controlado, um gatilho, e o nome em
128
+ // gatilho. A referência é a lateral de uma das referências, que outra delas usa num dos seus exemplos
129
+ // (a referência principal não tem moldura de app): estado aberto/recolhido, controlado e não controlado, um gatilho, e o nome em
130
130
  // dica na trilha. O lugar do botão é o que o Victor marcou: no alto, na junção do menu com o
131
131
  // conteúdo. E a trilha sozinha em tela média vem do pedido — a referência não a tem.
132
132
  //
@@ -180,7 +180,7 @@ export function AppShell({ brand, navigation, navItems, currentNavId, navLabel,
180
180
  // A condição vai escrita no `icon=` do botão, e não numa variável: é ali que o check 46 lê os
181
181
  // ícones que o shell desenha.
182
182
  const paraOComeco = !efetiva, direita = useDirection() === "rtl";
183
- return _jsxs("div", { className: cx("app-shell", topbarVariant === "flush" && "app-shell-flush", sidebarCollapsible && "app-shell-collapsible", className), ...props, children: [_jsx("a", { className: "skip-link", href: `#${SHELL_MAIN_ID}`, children: s.skipToContent }), _jsx(Topbar, { variant: topbarVariant, divider: topbarDivider, brand: _jsxs(_Fragment, { children: [_jsx(IconButton, { className: "nav-toggle", icon: "list", label: s.navigationToggle, popoverTarget: SHELL_NAV_ID }), brand] }), children: topbar }), sidebarCollapsible && _jsx("div", { className: "sidebar-toggle-slot", children: _jsx(Tooltip, { content: rotulo, side: "right", children: _jsx(IconButton, { className: "sidebar-toggle", size: "xs", icon: paraOComeco === direita ? "caret-right" : "caret-left", label: rotulo, "aria-expanded": !efetiva, "aria-controls": SHELL_NAV_ID, onClick: alternar }) }) }), _jsx(Sidebar, { id: SHELL_NAV_ID, popover: "auto", variant: sidebarVariant, collapsed: efetiva, items: navItems, current: currentNavId, label: navLabel, onToggle: focoDaGaveta, children: navigation }), _jsx("main", { id: SHELL_MAIN_ID, tabIndex: -1, className: cx("content", contentVariant === "plain" && "content-plain"), children: children })] });
183
+ return _jsxs("div", { className: cx("app-shell", topbarVariant === "flush" && "app-shell-flush", sidebarCollapsible && "app-shell-collapsible", className), ...props, children: [_jsx("a", { className: "skip-link", href: `#${SHELL_MAIN_ID}`, children: s.skipToContent }), _jsx(Header, { variant: topbarVariant, divider: topbarDivider, brand: _jsxs(_Fragment, { children: [_jsx(IconButton, { className: "nav-toggle", icon: "list", label: s.navigationToggle, popoverTarget: SHELL_NAV_ID }), brand] }), children: topbar }), sidebarCollapsible && _jsx("div", { className: "sidebar-toggle-slot", children: _jsx(Tooltip, { content: rotulo, side: "right", children: _jsx(IconButton, { className: "sidebar-toggle", size: "xs", icon: paraOComeco === direita ? "caret-right" : "caret-left", label: rotulo, "aria-expanded": !efetiva, "aria-controls": SHELL_NAV_ID, onClick: alternar }) }) }), _jsx(Sidebar, { id: SHELL_NAV_ID, popover: "auto", variant: sidebarVariant, collapsed: efetiva, items: navItems, current: currentNavId, label: navLabel, onToggle: focoDaGaveta, children: navigation }), _jsx("main", { id: SHELL_MAIN_ID, tabIndex: -1, className: cx("content", contentVariant === "plain" && "content-plain"), children: children })] });
184
184
  }
185
185
  export function Separator({ orientation, spacing = "none", className, ...props }) {
186
186
  const ancora = useRef(null);
package/dist/layout.d.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export * from "./layout-client.js";
2
2
  export { Card, Stack, Cluster, Grid } from "./markup.js";
3
3
  export { AspectRatio } from "./markup.js";
4
+ export { Container, Section } from "./markup.js";
5
+ export type { GridSpan, GridItemProps, ContainerSize, ContainerProps, SectionSurface, SectionSpacing, SectionProps, SectionVariant, SectionFooterGroup } from "./markup.js";
package/dist/layout.js CHANGED
@@ -5,3 +5,5 @@ export * from "./layout-client.js";
5
5
  export { Card, Stack, Cluster, Grid } from "./markup.js";
6
6
  // PORTADO no merge de 28/08/2026 — sai do markup (servidor), como os demais de marcação.
7
7
  export { AspectRatio } from "./markup.js";
8
+ // GAR-02 a GAR-05 (06/10/2026): a página de site — `Container`, `Section` e o `Grid.Item` com `span`.
9
+ export { Container, Section } from "./markup.js";
package/dist/markup.d.ts CHANGED
@@ -1,9 +1,12 @@
1
1
  import React, { type HTMLAttributes, type InputHTMLAttributes, type ReactElement, type ReactNode, type RefAttributes, type TextareaHTMLAttributes } from "react";
2
2
  import { type Responsive } from "./pure.js";
3
3
  import type { ComponentSize } from "./actions.js";
4
+ import type { SidebarItem } from "./navigation-client.js";
4
5
  export type BadgeVariant = "neutral" | "primary" | "info" | "success" | "warning" | "danger" | "running" | "paused" | "offline" | "review";
5
6
  export type AvatarSize = "sm" | "md" | "lg";
6
- export type TopbarVariant = "floating" | "flush" | "pill";
7
+ export type HeaderVariant = "floating" | "flush" | "pill";
8
+ /** @deprecated `Topbar` é o nome antigo do `Header` (07/10/2026). O tipo continua valendo; use `HeaderVariant`. */
9
+ export type TopbarVariant = HeaderVariant;
7
10
  type CardBase = HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement> & {
8
11
  padding?: "normal" | "none";
9
12
  orientation?: "vertical" | "horizontal";
@@ -48,7 +51,7 @@ export interface ClusterProps extends DivProps {
48
51
  }
49
52
  export declare function Cluster({ gap, align, justify, wrap, className, ...props }: ClusterProps): React.JSX.Element;
50
53
  /**
51
- * A largura mínima da coluna, por nome — AN-08 (03/10/2026). O HeroUI não tem `Grid`, e nenhum dos
54
+ * A largura mínima da coluna, por nome — AN-08 (03/10/2026). A referência não tem `Grid`, e nenhum dos
52
55
  * quatro números é novo: cada um já mede uma grade ou uma caixa da Aurea (ver `.grid-min-*` no CSS).
53
56
  * `md` é o padrão de sempre.
54
57
  */
@@ -66,6 +69,78 @@ export interface GridProps extends DivProps {
66
69
  columns?: number;
67
70
  }
68
71
  export declare function Grid({ gap, min, columns, className, style, ...props }: GridProps): React.JSX.Element;
72
+ export declare namespace Grid {
73
+ export { GridItem as Item };
74
+ }
75
+ /**
76
+ * Quantas colunas da grade o item ocupa — GAR-03 (06/10/2026). Texto, e não número, porque é o
77
+ * valor de um eixo responsivo, como `size` e `orientation`.
78
+ */
79
+ export type GridSpan = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "10" | "11" | "12";
80
+ export interface GridItemProps extends DivProps {
81
+ /**
82
+ * Quantas colunas o item ocupa (GAR-03). Com `<Grid columns={12}>` é o "7 de 12" de página de
83
+ * site. Responsivo, mobile-first: `{base: "12", viewport: {md: "7"}}` ocupa a linha inteira no
84
+ * estreito e 7 de 12 a partir do `md`. Sem `span`, uma coluna, como qualquer filho de grade.
85
+ */
86
+ span?: Responsive<GridSpan>;
87
+ }
88
+ /** O item da grade que sabe quantas colunas ocupa (GAR-03). Mora em `Grid.Item`, como `Card.Media`. */
89
+ declare function GridItem({ span, className, ...props }: GridItemProps): React.JSX.Element;
90
+ /** A largura máxima do `Container`, pelos nomes da escala de pontos. `xl` (1280) é o padrão. */
91
+ export type ContainerSize = "sm" | "md" | "lg" | "xl" | "2xl" | "full";
92
+ export interface ContainerProps extends HTMLAttributes<HTMLDivElement>, RefAttributes<HTMLDivElement> {
93
+ /** Até onde o conteúdo cresce: `sm` 640 · `md` 768 · `lg` 1024 · `xl` 1280 (padrão) · `2xl` 1536 · `full` sem teto. */
94
+ size?: ContainerSize;
95
+ }
96
+ /**
97
+ * A largura de leitura de uma página de SITE: centrada, com teto e o respiro dos lados que cresce
98
+ * com a tela (16 no estreito, 32 a partir do `md`). É o que vai DENTRO de uma `Section`. O painel
99
+ * de aplicativo continua sendo o `AppShell`.
100
+ */
101
+ export declare function Container({ size, className, ...props }: ContainerProps): React.JSX.Element;
102
+ /** O fundo da faixa: o da página (padrão), o de cartão ou o rebaixado. */
103
+ export type SectionSurface = "background" | "card" | "inset";
104
+ /** `base` é a faixa comum; `footer` é o rodapé do site (GAR-06, 07/10/2026). */
105
+ export type SectionVariant = "base" | "footer";
106
+ /** Uma coluna de links do rodapé: o título e os itens. */
107
+ export interface SectionFooterGroup {
108
+ title: ReactNode;
109
+ items: SidebarItem[];
110
+ }
111
+ /** O respiro de cima e de baixo: `md` (padrão, 64 e 96 a partir do `md`) ou `sm` (32 e 48). */
112
+ export type SectionSpacing = "sm" | "md";
113
+ export interface SectionProps extends HTMLAttributes<HTMLElement>, RefAttributes<HTMLElement> {
114
+ surface?: SectionSurface;
115
+ spacing?: SectionSpacing;
116
+ /**
117
+ * Um tema só para esta faixa (GAR-05): `"dark"` faz uma faixa escura dentro de uma página clara,
118
+ * e o contrário. Fundo, letra e peças de dentro seguem o tema da faixa, e as regras de tema da
119
+ * página não vazam para dentro dela.
120
+ */
121
+ theme?: "light" | "dark";
122
+ /**
123
+ * `footer` faz da faixa o RODAPÉ do site (GAR-06): `<footer>` com a marca, as colunas de links e a
124
+ * linha legal, e o miolo já num `Container`. No celular, tudo empilha.
125
+ */
126
+ variant?: SectionVariant;
127
+ /** Só no `footer`: a marca e uma frase curta, no alto à esquerda. */
128
+ brand?: ReactNode;
129
+ /** Só no `footer`: as colunas de links, cada uma com título. Os itens são `SidebarItem` (`id`, `label`, `href`, `render`). */
130
+ links?: SectionFooterGroup[];
131
+ /** Só no `footer`: a linha de baixo — direitos, termos, privacidade. */
132
+ legal?: ReactNode;
133
+ /** Só no `footer`: até onde o miolo cresce, pela escala do `Container`. Padrão: `xl`. */
134
+ maxWidth?: ContainerSize;
135
+ /** Só no `footer`: o nome da navegação do rodapé para o leitor de tela. Padrão: `"Footer"`. */
136
+ navLabel?: string;
137
+ }
138
+ /**
139
+ * A faixa de ponta a ponta de uma página de site (GAR-04): `<section>` com fundo e respiro de site.
140
+ * O conteúdo vai dentro de um `Container`. Dê um nome à faixa (`aria-labelledby` no título dela)
141
+ * quando ela for uma região que o leitor de tela deva listar.
142
+ */
143
+ export declare function Section({ surface, spacing, theme, variant, brand, links, legal, maxWidth, navLabel, children, className, ...props }: SectionProps): React.JSX.Element;
69
144
  export declare function KPI({ label, value, trend, className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement> & {
70
145
  label: ReactNode;
71
146
  value: ReactNode;
@@ -126,7 +201,7 @@ export interface BadgeProps extends HTMLAttributes<HTMLSpanElement>, RefAttribut
126
201
  dot?: boolean;
127
202
  leading?: ReactNode;
128
203
  trailing?: ReactNode;
129
- /** Foto redonda no início — o `BadgeWithImage` da referência. */
204
+ /** Foto redonda no início — o selo com imagem da referência. */
130
205
  image?: string;
131
206
  imageAlt?: string;
132
207
  /** Conteúdo numérico. Passa por `max` e some em zero, salvo `showZero`. */
@@ -137,12 +212,12 @@ export interface BadgeProps extends HTMLAttributes<HTMLSpanElement>, RefAttribut
137
212
  fit?: BadgeFit;
138
213
  /** Liga o modo SOBREPOSTO e escolhe o canto. `children` passa a ser o que se decora. */
139
214
  anchor?: BadgePlacement;
140
- /** `circle` recolhe o canto em 14% — é o `overlap` da MUI, para avatar redondo. */
215
+ /** `circle` recolhe o canto em 14% — é a sobreposição circular da referência, para avatar redondo. */
141
216
  anchorShape?: "square" | "circle";
142
217
  /** Esconde sem tirar o filho do lugar. */
143
218
  invisible?: boolean;
144
219
  /** Conteúdo do badge no modo sobreposto (no modo chip, quem manda é `children`).
145
- * Nome da MUI, e não `content`: este colide com o atributo HTML de mesmo nome. */
220
+ * Chama-se assim, e não `content`, porque este colide com o atributo HTML de mesmo nome. */
146
221
  badgeContent?: ReactNode;
147
222
  }
148
223
  export declare function Badge({ variant, emphasis, size, dot, leading, trailing, image, imageAlt, count, max, showZero, fit, anchor, anchorShape, invisible, badgeContent, children, className, ...props }: BadgeProps): React.JSX.Element;
@@ -154,7 +229,7 @@ export interface ProgressProps {
154
229
  value?: number;
155
230
  /** O nome que o leitor de tela anuncia. Não aparece. */
156
231
  label?: string;
157
- /** O texto de apoio, no alto à direita — o `ProgressBar.Output` do HeroUI: velocidade, tempo
232
+ /** O texto de apoio, no alto à direita — a saída de texto da barra de progresso da referência: velocidade, tempo
158
233
  * que falta, bytes. Em texto, vai junto no `aria-valuetext`. */
159
234
  detail?: ReactNode;
160
235
  tone?: ProgressTone;
@@ -178,11 +253,34 @@ export declare function LogStream({ lines }: {
178
253
  }>;
179
254
  }): React.JSX.Element;
180
255
  export declare function MediaPlayerShell({ children, className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>): React.JSX.Element;
181
- export declare function Topbar({ variant, divider, brand, children, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement> & {
182
- variant?: TopbarVariant;
256
+ export interface HeaderProps extends HTMLAttributes<HTMLElement>, RefAttributes<HTMLElement> {
257
+ /** A pele: `floating` (caixa solta), `flush` (encostada, o fundo da página) ou `pill` (cápsula). */
258
+ variant?: HeaderVariant;
259
+ /** A marca. No `AppShell`, é aqui que entra também o botão que abre a lateral. */
183
260
  brand?: ReactNode;
261
+ /** Só na `flush` (B-07): a linha embaixo da barra. */
184
262
  divider?: boolean;
185
- }): React.JSX.Element;
263
+ /**
264
+ * Os links do site (GAR-01) — a mesma lista do `Sidebar` e do `BottomNav`. No celular (abaixo
265
+ * de 768) eles saem da barra e entram no painel do botão de menu.
266
+ */
267
+ items?: SidebarItem[];
268
+ /** O `id` do item da página atual: ganha `aria-current="page"` e a cor de destaque. */
269
+ current?: string;
270
+ /** O que fica do lado direito: busca, botão de ação, conta. Fica na barra também no celular. */
271
+ actions?: ReactNode;
272
+ /** Até onde o miolo da barra cresce, pela escala do `Container` (`sm` 640 … `2xl` 1536, `full`). */
273
+ maxWidth?: ContainerSize;
274
+ /** O nome da navegação para o leitor de tela. Padrão: `"Main"`. */
275
+ navLabel?: string;
276
+ /** O nome do botão de menu do celular. Padrão: `"Menu"`. */
277
+ menuLabel?: string;
278
+ /** O `id` do painel do celular. Padrão: `"aurea-header-menu"`. Troque só se a página tiver dois cabeçalhos de site. */
279
+ menuId?: string;
280
+ }
281
+ export declare function Header({ variant, divider, brand, items, current, actions, maxWidth, navLabel, menuLabel, menuId, children, className, ...props }: HeaderProps): React.JSX.Element;
282
+ /** @deprecated `Topbar` é o nome antigo do `Header` (07/10/2026). Continua funcionando, igual; use `Header`. */
283
+ export declare function Topbar(props: HeaderProps): React.JSX.Element;
186
284
  export declare function Kbd({ children, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement>): React.JSX.Element;
187
285
  export interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement>, RefAttributes<HTMLTextAreaElement> {
188
286
  size?: Responsive<FieldSize>;
package/dist/markup.js CHANGED
@@ -57,6 +57,37 @@ export function Grid({ gap, min, columns, className, style, ...props }) {
57
57
  : style;
58
58
  return _jsx("div", { className: cx("grid", gap && gap !== "normal" && `grid-gap-${gap}`, nome && min !== "md" && `grid-min-${min}`, columns != null && "grid-fixed", className), style: vars, ...props });
59
59
  }
60
+ /** O item da grade que sabe quantas colunas ocupa (GAR-03). Mora em `Grid.Item`, como `Card.Media`. */
61
+ function GridItem({ span, className, ...props }) {
62
+ return _jsx("div", { className: cx("grid-item", peleDoEixo("grid-span", span, "", "grid-span"), className), ...props });
63
+ }
64
+ Grid.Item = GridItem;
65
+ /**
66
+ * A largura de leitura de uma página de SITE: centrada, com teto e o respiro dos lados que cresce
67
+ * com a tela (16 no estreito, 32 a partir do `md`). É o que vai DENTRO de uma `Section`. O painel
68
+ * de aplicativo continua sendo o `AppShell`.
69
+ */
70
+ export function Container({ size = "xl", className, ...props }) {
71
+ return _jsx("div", { className: cx("container", size !== "xl" && `container-${size}`, className), ...props });
72
+ }
73
+ /**
74
+ * A faixa de ponta a ponta de uma página de site (GAR-04): `<section>` com fundo e respiro de site.
75
+ * O conteúdo vai dentro de um `Container`. Dê um nome à faixa (`aria-labelledby` no título dela)
76
+ * quando ela for uma região que o leitor de tela deva listar.
77
+ */
78
+ // GAR-06 (07/10/2026): o rodapé de site é uma VARIAÇÃO da Section (regra do Victor: peça nova entra
79
+ // como variação), porque o rodapé é a última faixa da página: herda o fundo (`surface`), o respiro
80
+ // (`spacing`) e o tema próprio (`theme` — rodapé escuro numa página clara). Nenhuma referência da
81
+ // fila tem um rodapé aberto; o desenho é da Aurea, com tokens que já existem. Os links de cada
82
+ // coluna são `SidebarItem`, a mesma forma dos menus, e o `render` leva o link do roteador.
83
+ export function Section({ surface = "background", spacing = "md", theme, variant = "base", brand, links, legal, maxWidth = "xl", navLabel = "Footer", children, className, ...props }) {
84
+ const pele = cx("section", surface !== "background" && `section-${surface}`, spacing !== "md" && `section-spacing-${spacing}`);
85
+ if (variant !== "footer")
86
+ return _jsx("section", { "data-theme": theme, className: cx(pele, className), ...props, children: children });
87
+ return _jsx("footer", { "data-theme": theme, className: cx(pele, "section-footer", className), ...props, children: _jsxs("div", { className: cx("container", maxWidth !== "xl" && `container-${maxWidth}`), children: [_jsxs("div", { className: "section-footer-top", children: [brand != null && _jsx("div", { className: "section-footer-brand", children: brand }), links && links.length > 0 && _jsx("nav", { className: "section-footer-nav", "aria-label": navLabel, children: links.map((g, n) => _jsxs("div", { className: "section-footer-group", children: [_jsx("h2", { className: "section-footer-title", children: g.title }), _jsx("ul", { className: "section-footer-links", children: g.items.map(it => _jsx("li", { children: it.render
88
+ ? fundirRender(it.render, { className: "section-footer-link", children: it.label }, "a")
89
+ : _jsx("a", { className: "section-footer-link", href: it.href, children: it.label }) }, it.id)) })] }, n)) }), children] }), legal != null && _jsx("div", { className: "section-footer-legal", children: legal })] }) });
90
+ }
60
91
  // ── Data Display ─────────────────────────────────────────────────────────────────────────────
61
92
  export function KPI({ label, value, trend, className, ...props }) { return _jsxs(Card, { className: cx("kpi", className), ...props, children: [_jsx("span", { className: "muted", children: label }), _jsx("strong", { children: value }), trend && _jsx("small", { children: trend })] }); }
62
93
  export function DataList({ items }) { return _jsx("dl", { className: "data-list", children: items.map((i, n) => _jsxs(React.Fragment, { children: [_jsx("dt", { children: i.term }), _jsx("dd", { children: i.value })] }, n)) }); }
@@ -69,11 +100,11 @@ export function Timeline({ items }) { return _jsx("ol", { className: "timeline",
69
100
  export function Prose({ className, ...props }) { return _jsx("div", { className: cx("prose", className), ...props }); }
70
101
  const tipografia = (tipo, { align, color, weight, truncate }, className) => cx("typography", `typography-${tipo}`, color === "muted" && "typography-muted", weight && `typography-weight-${weight}`, align && `typography-align-${align}`, truncate && "typography-truncate", className);
71
102
  export function Text({ type = "body", align, color, weight, truncate, className, ...props }) { return _jsx("span", { className: tipografia(type, { align, color, weight, truncate }, className), ...props }); }
72
- // O nível decide o elemento E o tamanho, como no HeroUI: um `h2` tem a cara de título 2.
103
+ // O nível decide o elemento E o tamanho, como na referência: um `h2` tem a cara de título 2.
73
104
  export function Heading({ level = 1, align, color, weight, truncate, className, ...props }) { const Tag = `h${level}`; return _jsx(Tag, { className: tipografia(`h${level}`, { align, color, weight, truncate }, className), ...props }); }
74
105
  export function Paragraph({ size = "base", align, color, weight, truncate, className, ...props }) { return _jsx("p", { className: tipografia(size === "base" ? "body" : `body-${size}`, { align, color, weight, truncate }, className), ...props }); }
75
106
  export function Code({ align, color, weight, truncate, className, ...props }) { return _jsx("code", { className: tipografia("code", { align, color, weight, truncate }, className), ...props }); }
76
- // `max` com `+` é o idioma universal do contador (MUI, Ant, Material 3). Exportada porque quem
107
+ // `max` com `+` é o idioma universal do contador (três das referências o usam). Exportada porque quem
77
108
  // escreve o nome acessível precisa do MESMO texto — "99+ unread" tem de bater com o que se vê.
78
109
  export function formatBadgeCount(count, max = 99) { return count > max ? `${max}+` : String(count); }
79
110
  export function Badge({ variant = "neutral", emphasis = "soft", size = "md", dot, leading, trailing, image, imageAlt, count, max = 99, showZero, fit = "auto", anchor, anchorShape = "square", invisible, badgeContent, children, className, ...props }) {
@@ -84,15 +115,15 @@ export function Badge({ variant = "neutral", emphasis = "soft", size = "md", dot
84
115
  const chip = _jsxs("span", { className: cx("badge", variant !== "neutral" && `badge-${variant}`, emphasis !== "soft" && `badge-${emphasis}`, size !== "md" && `badge-${size}`, fit === "content" && !anchor && "badge-fit", anchor && `badge-overlay badge-at-${anchor}`, anchor && anchorShape === "circle" && "badge-on-circle", anchor && soPonto && "badge-is-dot", className), ...props, children: [dot && !soPonto && _jsx("span", { className: "badge-dot" }), image && _jsx("img", { className: "badge-image", src: image, alt: imageAlt ?? "" }), leading, miolo, trailing] });
85
116
  if (!anchor)
86
117
  return chip;
87
- // Some em zero por padrão, como a MUI: caixa de entrada zerada não merece um "0" no canto.
118
+ // Some em zero por padrão, como na referência: caixa de entrada zerada não merece um "0" no canto.
88
119
  const escondido = invisible || (count === 0 && !showZero) || (miolo == null && !dot);
89
120
  // `aria-hidden` no contador, e o número vai para o nome de QUEM É DECORADO — regra da própria
90
- // documentação da MUI e das três fontes de acessibilidade lidas em 17/08/2026. Sem isso, o
121
+ // documentação da referência e das três fontes de acessibilidade lidas em 17/08/2026. Sem isso, o
91
122
  // botão do sino é anunciado "sino 8" e ninguém sabe o que é o 8.
92
123
  return _jsxs("span", { className: "badge-anchor", children: [children, !escondido && React.cloneElement(chip, { "aria-hidden": true })] });
93
124
  }
94
125
  // AN-07 (03/10/2026). Tudo novo é acréscimo: com `value` e sem `detail` nem `tone`, a marcação é a
95
- // de antes, mais a classe da caixa de fora. A anatomia é a do `ProgressBar` do HeroUI 3.2.6: a
126
+ // de antes, mais a classe da caixa de fora. A anatomia é a da barra de progresso da referência: a
96
127
  // saída no alto à direita, o trilho embaixo, e sem `aria-valuenow` quando não há total.
97
128
  export function Progress({ value, label, detail, tone = "brand", className }) {
98
129
  const semTotal = value == null || Number.isNaN(value);
@@ -125,11 +156,20 @@ export function AvatarGroup({ children, max, total, label, size, className }) {
125
156
  export function LogStream({ lines }) { return _jsx("div", { className: "log-stream", role: "log", "aria-live": "polite", children: lines.map((l, n) => _jsxs("div", { className: "log-line", children: [_jsx("time", { className: "log-time", children: l.time }), _jsx("span", { className: cx("log-level", l.level && l.level.toLowerCase()), children: l.level }), _jsx("span", { children: l.text })] }, n)) }); }
126
157
  // ── Media ────────────────────────────────────────────────────────────────────────────────────
127
158
  export function MediaPlayerShell({ children, className, ...props }) { return _jsx("div", { className: cx("media-player", className), ...props, children: children }); }
128
- // ── Navigation ───────────────────────────────────────────────────────────────────────────────
129
- // B-07 (24/09/2026): `divider` põe a linha de baixo na `flush`. Ela é fundo igual ao da página e
130
- // gruda no topo; sem linha, o conteúdo passa por baixo dela e nada diz onde a barra acaba. Só na
131
- // `flush`: a `floating` e a `pill` são caixas com borda própria.
132
- export function Topbar({ variant = "floating", divider, brand, children, className, ...props }) { return _jsxs("header", { className: cx("topbar", `topbar-${variant}`, divider && variant === "flush" && "topbar-divider", className), ...props, children: [brand != null && _jsx("div", { className: "brand", children: brand }), children] }); }
159
+ // O item da barra e o do painel são o MESMO elemento com a mesma pele: o atual é o atual nos dois.
160
+ function linksDoHeader(items, current) {
161
+ return _jsx("ul", { className: "topbar-links", children: items.map(it => {
162
+ const p = { className: "topbar-link", "aria-current": it.id === current ? "page" : undefined, children: it.label };
163
+ return _jsx("li", { children: it.render ? fundirRender(it.render, p, "a") : _jsx("a", { href: it.href, ...p }) }, it.id);
164
+ }) });
165
+ }
166
+ export function Header({ variant = "floating", divider, brand, items, current, actions, maxWidth, navLabel = "Main", menuLabel = "Menu", menuId = "aurea-header-menu", children, className, ...props }) {
167
+ const site = !!items && items.length > 0;
168
+ const miolo = _jsxs(_Fragment, { children: [brand != null && _jsx("div", { className: "brand", children: brand }), site && _jsx("nav", { className: "topbar-nav", "aria-label": navLabel, children: linksDoHeader(items, current) }), children, actions != null && _jsx("div", { className: "topbar-actions", children: actions }), site && _jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "btn btn-ghost btn-icon topbar-menu-toggle", popoverTarget: menuId, "aria-label": menuLabel, children: _jsx("span", { className: "topbar-menu-icon", "aria-hidden": "true" }) }), _jsx("nav", { id: menuId, popover: "auto", className: "topbar-menu-panel", "aria-label": navLabel, children: linksDoHeader(items, current) })] })] });
169
+ return _jsx("header", { className: cx("topbar", `topbar-${variant}`, divider && variant === "flush" && "topbar-divider", site && "topbar-site", maxWidth && "topbar-contained", className), ...props, children: maxWidth ? _jsx("div", { className: cx("container", maxWidth !== "xl" && `container-${maxWidth}`, "topbar-inner"), children: miolo }) : miolo });
170
+ }
171
+ /** @deprecated `Topbar` é o nome antigo do `Header` (07/10/2026). Continua funcionando, igual; use `Header`. */
172
+ export function Topbar(props) { return _jsx(Header, { ...props }); }
133
173
  // ── System / interno ─────────────────────────────────────────────────────────────────────────
134
174
  // Kbd — representação de tecla/atalho. <kbd> é o elemento HTML certo; a pele é nossa. Ele já
135
175
  // morava fora da casa dele (no `internal.tsx`, por causa do `Button`); agora mora aqui, pelo
@@ -189,13 +189,12 @@ export function Gallery({ items, label, selected, onSelect, zoom, ratio = "1/1",
189
189
  // MARCAÇÃO, NÃO MOTOR — e a pergunta que o item mandava decidir primeiro ("se `scroll-snap` do
190
190
  // CSS cobre, o componente é marcação") foi respondida MEDINDO, não preferindo:
191
191
  //
192
- // • as QUATRO referências embrulham o MESMO motor de terceiro, o `embla-carousel` — medido em
193
- // 15/08/2026 no `kibo-main/packages/shadcn-ui/.../carousel.tsx`, nas quatro bases do
194
- // `ui-main` (`aria`, `base`, `radix`, `new-york-v4`), no `carousel-base.tsx` do `react-main`
195
- // e no `activepieces-main`. Nenhuma escreve um motor; todas pagam o mesmo;
192
+ // • as QUATRO referências embrulham o MESMO motor de carrossel de terceiro — medido em
193
+ // 15/08/2026 no fonte de cada uma, nas pastas de `Referencia/` (numa delas, nas quatro bases
194
+ // que ela oferece). Nenhuma escreve um motor; todas pagam o mesmo;
196
195
  // • o `@base-ui/react` NÃO tem carrossel (medido: 46 pastas em `packages/react/src`, nenhuma
197
196
  // é carousel — a mesma medição que abriu a decisão de motor do Calendar);
198
- // • trazer o `embla` seria DEPENDÊNCIA NOVA, que pelo `BUILDING.md` §3.3 interrompe o lote e
197
+ // • trazer esse motor seria DEPENDÊNCIA NOVA, que pelo `BUILDING.md` §3.3 interrompe o lote e
199
198
  // exige o Victor — para um componente que o navegador já sabe fazer;
200
199
  // • e o caminho SEM JavaScript nenhum ainda não serve: `::scroll-button()`/`::scroll-marker()`
201
200
  // (CSS Overflow 5) não são Baseline — pesquisado em 15/08/2026: Chrome/Edge 135+ têm,
@@ -203,7 +202,7 @@ export function Gallery({ items, label, selected, onSelect, zoom, ratio = "1/1",
203
202
  // Um design system não pode entregar controle que só funciona num navegador.
204
203
  //
205
204
  // Então o motor é o CONTÊINER DE ROLAGEM nativo com `scroll-snap`, que é Baseline há anos e dá
206
- // de graça o que o `embla` reimplementa: arrasto por toque com inércia, rolagem por roda e
205
+ // de graça o que esse motor reimplementa: arrasto por toque com inércia, rolagem por roda e
207
206
  // teclado, e o encaixe no slide. O que sobra de JavaScript é o que o CSS ainda não tem — saber
208
207
  // em QUAL slide se está, para desenhar o ponto aceso e desabilitar a seta do fim.
209
208
  //
@@ -212,20 +211,20 @@ export function Gallery({ items, label, selected, onSelect, zoom, ratio = "1/1",
212
211
  // `prefers-reduced-motion` que o core já tem (`scroll-behavior:auto!important`) alcança este
213
212
  // componente sem uma linha nova. Passar `behavior:"smooth"` daqui passaria POR CIMA dela.
214
213
  //
215
- // UM componente, não sete peças: `Carousel.Root/Content/Item/PrevTrigger/NextTrigger/
216
- // IndicatorGroup/Indicator` é a decomposição da referência, e aqui ela custaria sete fichas para
214
+ // UM componente, não sete peças: raiz, conteúdo, item, seta de voltar, seta de avançar,
215
+ // grupo de indicadores e indicador é a decomposição da referência, e aqui ela custaria sete fichas para
217
216
  // desenhar uma lista que rola. É o mesmo argumento que o `Stepper`, o `TreeView` e a `Sidebar`
218
217
  // já resolveram: quem embrulha cada slide é o componente, e por isso o rótulo "Slide 3 de 8"
219
218
  // nunca fica com o consumidor — que é onde ele seria esquecido.
220
219
  //
221
220
  // LIMITES DECLARADOS (todos são escopo menor que o da referência, `BUILDING.md` §Passo 5):
222
- // • sem laço infinito, sem autoplay e sem arrasto com o MOUSE — os três são do `embla` e
221
+ // • sem laço infinito, sem autoplay e sem arrasto com o MOUSE — os três são do motor de terceiro e
223
222
  // nenhum deles apareceu na medição dos consumidores; laço, ainda por cima, não existe em
224
223
  // contêiner de rolagem nativo e voltaria a exigir motor;
225
224
  // • sem eixo vertical: não há uso medido, e o sprite não tem chevron para cima (a allowlist
226
225
  // do contrato tem `chevron--left/right/down`), então o eixo custaria glifo novo por nada;
227
226
  // • quantos slides aparecem por vez é CSS, não prop: `--carousel-slide` (default `100%`) é a
228
- // válvula no idioma do `--qr-size` e do `--datagrid-max-h`. É o caso `multiple` da
227
+ // válvula no idioma do `--qr-size` e do `--datagrid-max-h`. É o caso de vários slides por vez da
229
228
  // referência, sem API nenhuma;
230
229
  // • em RTL a rolagem vai para o lado certo (o deslocamento é medido pela borda inicial), mas
231
230
  // o GLIFO da seta não espelha — é uma linha de CSS que ninguém pediu e que nenhum teste
@@ -23,7 +23,8 @@ export declare function Breadcrumb({ items, label }: {
23
23
  label?: string;
24
24
  }): React.JSX.Element;
25
25
  export type TabsOrientation = "horizontal" | "vertical";
26
- export declare function Tabs({ tabs, value, onChange, label, orientation, activateOnFocus, loopFocus }: {
26
+ export type TabsPanel = "card" | "plain";
27
+ export declare function Tabs({ tabs, value, onChange, label, orientation, activateOnFocus, loopFocus, panel }: {
27
28
  tabs: Array<{
28
29
  id: string;
29
30
  label: ReactNode;
@@ -35,6 +36,7 @@ export declare function Tabs({ tabs, value, onChange, label, orientation, activa
35
36
  orientation?: Responsive<TabsOrientation>;
36
37
  activateOnFocus?: boolean;
37
38
  loopFocus?: boolean;
39
+ panel?: TabsPanel;
38
40
  }): React.JSX.Element;
39
41
  export declare function Pagination({ page, total, onPageChange }: {
40
42
  page: number;
@@ -29,7 +29,7 @@ export function Stepper({ items, label, className }) {
29
29
  }) });
30
30
  }
31
31
  export function Breadcrumb({ items, label }) { const s = useAureaStrings(); return _jsx("nav", { className: "breadcrumb", "aria-label": label ?? s.breadcrumbLabel, children: items.map((i, n) => _jsxs(React.Fragment, { children: [n > 0 && _jsx(Icon, { name: "caret-right", size: "sm" }), " ", i.render ? fundirRender(i.render, { children: i.label }, "a") : i.href ? _jsx("a", { href: i.href, children: i.label }) : _jsx("strong", { "aria-current": "page", children: i.label })] }, n)) }); }
32
- export function Tabs({ tabs, value, onChange, label, orientation, activateOnFocus = true, loopFocus }) { const s = useAureaStrings(); const ancora = useRef(null); const resolvida = useValorResponsivo(orientation, "horizontal", ancora); return _jsxs(BaseTabs.Root, { ref: ancora, value: value, onValueChange: v => onChange(String(v)), orientation: resolvida, className: "tabs-root", children: [_jsx(BaseTabs.List, { className: "tabs", "aria-label": label ?? s.tabsLabel, activateOnFocus: activateOnFocus, loopFocus: loopFocus, children: tabs.map(t => _jsx(BaseTabs.Tab, { value: t.id, className: "tab", children: t.label }, t.id)) }), tabs.map(t => _jsx(BaseTabs.Panel, { value: t.id, className: "card card-inset", tabIndex: 0, children: t.content }, t.id))] }); }
32
+ export function Tabs({ tabs, value, onChange, label, orientation, activateOnFocus = true, loopFocus, panel = "card" }) { const s = useAureaStrings(); const ancora = useRef(null); const resolvida = useValorResponsivo(orientation, "horizontal", ancora); return _jsxs(BaseTabs.Root, { ref: ancora, value: value, onValueChange: v => onChange(String(v)), orientation: resolvida, className: "tabs-root", children: [_jsx(BaseTabs.List, { className: "tabs", "aria-label": label ?? s.tabsLabel, activateOnFocus: activateOnFocus, loopFocus: loopFocus, children: tabs.map(t => _jsx(BaseTabs.Tab, { value: t.id, className: "tab", children: t.label }, t.id)) }), tabs.map(t => _jsx(BaseTabs.Panel, { value: t.id, className: panel === "plain" ? "tabs-panel" : "card card-inset", tabIndex: 0, children: t.content }, t.id))] }); }
33
33
  export function Pagination({ page, total, onPageChange }) { const s = useAureaStrings(); return _jsxs("nav", { className: "pagination", "aria-label": s.paginationLabel, children: [_jsx(Button, { variant: "ghost", size: "sm", disabled: page <= 1, onClick: () => onPageChange(page - 1), children: s.previous }), _jsxs(Badge, { variant: "primary", children: [page, " / ", total] }), _jsx(Button, { variant: "ghost", size: "sm", disabled: page >= total, onClick: () => onPageChange(page + 1), children: s.next })] }); }
34
34
  export function TableOfContents({ items, current, label, className, ...props }) {
35
35
  const s = useAureaStrings();
@@ -208,7 +208,7 @@ function sidebarList(items, ctx, sub, labelledBy) {
208
208
  : _jsx("button", { id: lid, type: "button", className: "sidebar-item", "aria-current": ativo ? "page" : undefined, onClick: it.onClick, children: miolo });
209
209
  // NO TRILHO O NOME SÓ EXISTE NO TOOLTIP. Recolhida, a lateral manda o rótulo para `.sr-only`: quem
210
210
  // usa leitor de tela continua ouvindo, e quem ENXERGA fica com um ícone mudo. A referência resolve
211
- // isso com tooltip no `NavButton`, e é o que falta para um trilho de ícone não virar adivinhação.
211
+ // isso com tooltip no botão de navegação dela, e é o que falta para um trilho de ícone não virar adivinhação.
212
212
  // Só quando recolhida: com o rótulo visível ao lado, o tooltip repetiria o que já está na tela.
213
213
  // `side="right"` porque a lateral encosta na borda esquerda — para cima o balão sairia do trilho.
214
214
  return _jsxs("li", { children: [ctx.collapsed ? _jsx(Tooltip, { content: it.label, side: "right", children: alvo }) : alvo, filhos && sidebarList(filhos, ctx, true, lid)] }, it.id);
@@ -216,8 +216,8 @@ function sidebarList(items, ctx, sub, labelledBy) {
216
216
  }
217
217
  // A GAVETA FECHA AO ESCOLHER (A-06, 23/09/2026). Abaixo de lg a lateral do `AppShell` é popover,
218
218
  // e a biblioteca a abria e NUNCA a fechava por código: `hidePopover` tinha zero ocorrências. O
219
- // usuário tocava "Relatórios", a página trocava por baixo e a gaveta ficava na frente dela. Material 3,
220
- // Fluent 2 e o guia de gaveta do iOS fecham ao escolher. O fechamento mora NA LATERAL, e não no
219
+ // usuário tocava "Relatórios", a página trocava por baixo e a gaveta ficava na frente dela. Duas das
220
+ // referências de desenho e o guia de gaveta do iOS fecham ao escolher. O fechamento mora NA LATERAL, e não no
221
221
  // item, para valer também para a navegação que o consumidor escreve e passa como `children` — o
222
222
  // catálogo é um desses. Fora do popover (desktop, lateral solta) o teste de `:popover-open` falha e
223
223
  // nada acontece. O `try` é porque `:popover-open` é seletor desconhecido em motor antigo, e lá o
@@ -252,8 +252,8 @@ export function BottomNav({ items, current, variant = "floating", indicator = "n
252
252
  const ativo = it.id === current;
253
253
  // O CONTADOR PENDURA NO ÍCONE, e é por isso que existe esta caixa. Pendurado no ITEM (a
254
254
  // primeira versão), `50%` cai no meio do RÓTULO quando o item é linha — o Victor viu o número
255
- // cobrir o nome inteiro em 17/08/2026. A pesquisa (Material 3 e os guias de barra de abas do
256
- // iOS) diz a mesma coisa: canto superior do ÍCONE, encostando na borda dele, nunca sobre o
255
+ // cobrir o nome inteiro em 17/08/2026. A pesquisa (uma das referências de desenho e os guias de
256
+ // barra de abas do iOS) diz a mesma coisa: canto superior do ÍCONE, encostando na borda dele, nunca sobre o
257
257
  // texto. A caixa é o que dá ao contador um canto para se ancorar — e nos quatro indicadores
258
258
  // redondos é ela que VIRA o círculo, com o rótulo embaixo, fora dele.
259
259
  // `size="lg"` porque a proporção contra o contador foi medida: 24 para 16, razão 0,67.
@@ -1,2 +1,2 @@
1
1
  export * from "./navigation-client.js";
2
- export { Topbar, type TopbarVariant } from "./markup.js";
2
+ export { Header, Topbar, type HeaderVariant, type HeaderProps, type TopbarVariant } from "./markup.js";
@@ -2,4 +2,5 @@
2
2
  // `"use client"` de propósito: a diretiva contamina o módulo inteiro e faria a marcação pura
3
3
  // chegar como cliente por vizinhança (ADR-0026; o check 26b reprova quem a puser de volta aqui).
4
4
  export * from "./navigation-client.js";
5
- export { Topbar } from "./markup.js";
5
+ // `Header` é o nome de mercado do antigo `Topbar` (07/10/2026); os dois são o mesmo componente.
6
+ export { Header, Topbar } from "./markup.js";
package/dist/overlays.js CHANGED
@@ -43,7 +43,7 @@ export function Dialog({ open, title, children, footer, onClose, size = "md", di
43
43
  // sobrevive a trocar um dos dois — e reprova quando os dois somem.
44
44
  //
45
45
  // ESCOPO MENOR que a referência (BUILDING.md §5): lá são nove peças compostas
46
- // (Root/Trigger/Content/Header/Title/Description/Footer/Cancel/Action). Aqui é uma prop `open`,
46
+ // (raiz, gatilho, conteúdo, cabeçalho, título, descrição, rodapé, cancelar e ação). Aqui é uma prop `open`,
47
47
  // como no `Dialog` e no `Drawer` — a composição não acrescenta escolha nenhuma num diálogo cujo
48
48
  // corpo é uma frase e dois botões.
49
49
  //
@@ -78,7 +78,7 @@ export function Popover({ trigger, title, children, side = "bottom" }) { const p
78
78
  // não de aparência: a Tooltip é um RÓTULO curto (`role="tooltip"`, some ao mover o mouse); o
79
79
  // Popover abre por CLIQUE e pode conter foco; este é uma PRÉVIA rica que aparece ao repousar o
80
80
  // ponteiro sobre um link e cujo conteúdo é alcançável — o cartão de perfil ao passar sobre um
81
- // nome. As três referências que o têm chamam de hover-card ou preview-card e concordam nisso.
81
+ // nome. As três referências que o têm chamam de cartão de sobrevoo ou de prévia e concordam nisso.
82
82
  // Superfície reusa `.popover` de propósito: é a mesma camada flutuante do sistema, e dar a ela
83
83
  // um segundo nome criaria duas peles para a mesma coisa.
84
84
  // Por depender de repouso do ponteiro, NÃO serve para informação essencial — quem navega só por
package/dist/pure.js CHANGED
@@ -9,8 +9,8 @@
9
9
  // módulos de cliente não precisarem saber da diferença; o barril (`index.tsx`, que também é de
10
10
  // servidor) importa DAQUI.
11
11
  //
12
- // Mesmo desenho da referência: no shadcn/ui o `cn` mora em `lib/utils.ts` sem diretiva, enquanto
13
- // 43 dos 57 componentes de `registry/bases/aria/ui` a declaram — medido em 06/08/2026.
12
+ // Mesmo desenho da referência: nela a função de juntar classes mora num arquivo utilitário sem diretiva, enquanto
13
+ // 43 dos 57 componentes dela a declaram — medido em 06/08/2026.
14
14
  //
15
15
  // `.tsx` sem JSX de propósito: os checks 11, 19 e 26 varrem `packages/react/src/*.tsx`, e um
16
16
  // `.ts` aqui seria um arquivo que gate nenhum enxerga.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aurea-uds/react",
3
- "version": "0.19.1",
3
+ "version": "0.23.0",
4
4
  "description": "Os componentes React da Aurea UDS. Importe @aurea-uds/fonts/css e @aurea-uds/core/css junto.",
5
5
  "keywords": [
6
6
  "aurea",