@aurea-uds/react 0.35.0 → 0.37.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/agents.js CHANGED
@@ -298,5 +298,7 @@ export function InterAgentMessage({ messages, label, className, ...props }) {
298
298
  // cartão responder por dois contratos — o erro que o `TaskQueue` recusou no H.b.
299
299
  export function AutomationCard({ name, description, trigger, action, enabled, onToggle, lastRun, lastResult, details, actions, className, ...props }) {
300
300
  const s = useAureaStrings();
301
- return _jsxs("article", { className: cx("card", "automation", className), "data-enabled": enabled ?? undefined, ...props, children: [_jsxs("header", { className: "automation-head", children: [_jsxs("div", { className: "automation-id", children: [_jsx("strong", { children: name }), description && _jsx("span", { className: "hint", children: description })] }), onToggle && _jsx(Switch, { checked: !!enabled, onChange: e => onToggle(e.target.checked), label: s.automationEnabled })] }), _jsx(DataList, { items: [{ term: s.automationWhen, value: trigger }, { term: s.automationThen, value: action }, ...(details ?? [])] }), (lastRun || lastResult) && _jsxs("footer", { className: "automation-foot", children: [lastResult && _jsx(Status, { variant: lastResult === "success" ? "success" : "danger", children: s.automationResult[lastResult] }), lastRun && _jsxs("span", { className: "hint", children: [s.automationLastRun, ": ", lastRun] }), actions] }), !lastRun && !lastResult && actions && _jsx("footer", { className: "automation-foot", children: actions })] });
301
+ // `data-enabled` só quando LIGADA: o `false` saía como `data-enabled="false"` e escapava da regra que faz a regra
302
+ // desligada recuar (`:not([data-enabled])`) — achado do check 49, lote 1, 20/10/2026.
303
+ return _jsxs("article", { className: cx("card", "automation", className), "data-enabled": enabled || undefined, ...props, children: [_jsxs("header", { className: "automation-head", children: [_jsxs("div", { className: "automation-id", children: [_jsx("strong", { children: name }), description && _jsx("span", { className: "hint", children: description })] }), onToggle && _jsx(Switch, { checked: !!enabled, onChange: e => onToggle(e.target.checked), label: s.automationEnabled })] }), _jsx(DataList, { items: [{ term: s.automationWhen, value: trigger }, { term: s.automationThen, value: action }, ...(details ?? [])] }), (lastRun || lastResult) && _jsxs("footer", { className: "automation-foot", children: [lastResult && _jsx(Status, { variant: lastResult === "success" ? "success" : "danger", children: s.automationResult[lastResult] }), lastRun && _jsxs("span", { className: "hint", children: [s.automationLastRun, ": ", lastRun] }), actions] }), !lastRun && !lastResult && actions && _jsx("footer", { className: "automation-foot", children: actions })] });
302
304
  }
@@ -1,9 +1,23 @@
1
1
  import React from "react";
2
- export declare function CodeBlock({ children, language, copyable, preview, className }: {
2
+ /** Um pedaço de uma linha de código, com a classe da cor (`tok-keyword`, `tok-string`…) quando tem cor. */
3
+ export interface CodeToken {
4
+ text: string;
5
+ className?: string;
6
+ }
7
+ /** Uma linha de código: os pedaços, na ordem. */
8
+ export type CodeLine = CodeToken[];
9
+ /** Quem colore: recebe o código e a língua e devolve as linhas, ou `null` quando não conhece a língua. O da Aurea é o
10
+ * `highlightCode` de `@aurea-uds/react/code-highlight`. */
11
+ export type CodeHighlighter = (code: string, language: string) => CodeLine[] | null;
12
+ export declare function CodeBlock({ children, language, copyable, preview, lineNumbers, highlight, className }: {
3
13
  children: string;
4
14
  language?: string;
5
15
  copyable?: boolean;
6
16
  /** A prévia viva do código: com ela, o bloco vira a caixa de exemplo, com as abas Prévia | Código. */
7
17
  preview?: React.ReactNode;
18
+ /** Mostra o número de cada linha à esquerda. O número não entra no texto copiado nem é lido pelo leitor de tela. */
19
+ lineNumbers?: boolean;
20
+ /** Colore o código. Passe o `highlightCode` de `@aurea-uds/react/code-highlight` (os analisadores são peer opcional). */
21
+ highlight?: CodeHighlighter;
8
22
  className?: string;
9
23
  }): React.JSX.Element;
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  // Fase 9 (achado A5): este arquivo saiu do index.tsx de 970 linhas. Um módulo por categoria
4
4
  // do registry — a taxonomia já existia e é gateada. A ordem de import entre eles é um DAG:
5
5
  // internal → system → actions → feedback → inputs → navigation → layout → data-display → resto.
@@ -29,9 +29,17 @@ function CaixaDeExemplo({ preview, codigo, className }) {
29
29
  const botao = (a, rotulo) => _jsx("button", { type: "button", role: "tab", id: `${id}-${a}`, ref: a === "preview" ? refPrevia : refCodigo, className: aba === a ? "active" : undefined, "aria-selected": aba === a, "aria-controls": `${id}-${a}-panel`, tabIndex: aba === a ? 0 : -1, onClick: () => setAba(a), onKeyDown: tecla, children: rotulo });
30
30
  return _jsxs("div", { className: cx("demo code-preview", className), children: [_jsx("div", { className: "demo-tabs", children: _jsxs("div", { className: "segmented", role: "tablist", children: [botao("preview", s.codeBlockPreview), botao("code", s.codeBlockCode)] }) }), _jsx("div", { className: "demo-panel", "data-panel": "preview", role: "tabpanel", id: `${id}-preview-panel`, "aria-labelledby": `${id}-preview`, tabIndex: 0, hidden: aba !== "preview", children: preview }), _jsx("div", { className: "demo-panel demo-code", "data-panel": "code", role: "tabpanel", id: `${id}-code-panel`, "aria-labelledby": `${id}-code`, tabIndex: 0, hidden: aba !== "code", children: codigo })] });
31
31
  }
32
- export function CodeBlock({ children, language = "text", copyable, preview, className }) {
32
+ // lineNumbers e highlight (lote V, 20/10/2026): as linhas viram um <span class="code-line"> cada, com o "\n" entre
33
+ // elas — o texto do bloco continua IGUAL ao código (copiar com o mouse traz o mesmo texto), e o número é desenhado pelo
34
+ // CSS, sem entrar no texto nem no leitor de tela. Sem as duas, a marcação é a de antes, sem mudar nada.
35
+ // O "\n" do fim (o código que termina em quebra de linha) não vira uma linha numerada e vazia: ele sai depois da última.
36
+ function linhasDoCodigo(codigo, language, highlight) {
37
+ const linhas = highlight?.(codigo, language) ?? codigo.split("\n").map(l => l === "" ? [] : [{ text: l }]);
38
+ return codigo.endsWith("\n") && linhas.length > 1 && linhas[linhas.length - 1].length === 0 ? linhas.slice(0, -1) : linhas;
39
+ }
40
+ export function CodeBlock({ children, language = "text", copyable, preview, lineNumbers, highlight, className }) {
33
41
  if (preview !== undefined)
34
- return _jsx(CaixaDeExemplo, { preview: preview, className: className, codigo: _jsx(CodeBlock, { language: language, copyable: copyable, children: children }) });
42
+ return _jsx(CaixaDeExemplo, { preview: preview, className: className, codigo: _jsx(CodeBlock, { language: language, copyable: copyable, lineNumbers: lineNumbers, highlight: highlight, children: children }) });
35
43
  const s = useAureaStrings();
36
44
  // tabIndex no <pre>: `.code-block` é `overflow:auto` por construção, então é REGIÃO ROLÁVEL
37
45
  // e não tem nada focável dentro — quem navega por teclado não alcança o código que passa da
@@ -39,7 +47,13 @@ export function CodeBlock({ children, language = "text", copyable, preview, clas
39
47
  // demo do catálogo já tinha corrigido em 30/07/2026 no lado dele; aqui, na biblioteca, ele
40
48
  // seguia aberto e só não aparecia porque nenhuma linha era comprida o bastante. Quem o achou
41
49
  // foi o `catalog-sweep` em 10/08/2026, quando o bloco do I1 fez a linha de import crescer.
42
- const pre = _jsx("pre", { className: cx("code-block", !copyable && className), "data-language": language, tabIndex: 0, children: _jsx("code", { children: children }) });
50
+ const linhas = lineNumbers || highlight ? linhasDoCodigo(children, language, highlight) : null;
51
+ const colorido = linhas != null && highlight != null && linhas.some(l => l.some(p => p.className));
52
+ // Os algarismos da última linha: a coluna do número tem a largura deles (99 → 2, 100 → 3).
53
+ const digitos = lineNumbers && linhas ? { "--code-line-digits": String(linhas.length).length } : undefined;
54
+ const pre = _jsx("pre", { className: cx("code-block", lineNumbers && "code-block-numbered", colorido && "code-block-highlighted", !copyable && className), style: digitos, "data-language": language, tabIndex: 0, children: _jsx("code", { children: linhas
55
+ ? _jsxs(_Fragment, { children: [linhas.map((l, i) => _jsxs(React.Fragment, { children: [_jsx("span", { className: "code-line", children: l.map((p, j) => p.className ? _jsx("span", { className: p.className, children: p.text }, j) : p.text) }), i < linhas.length - 1 ? "\n" : null] }, i)), children.endsWith("\n") ? "\n" : null] })
56
+ : children }) });
43
57
  if (!copyable)
44
58
  return pre;
45
59
  // 0.28.0: o "copiado" é dito ao leitor de tela. Com o `aurea.js` na página, é ele quem diz (pelo
@@ -92,7 +92,10 @@ export function CodeEditor({ defaultValue = "", onChange, extensions, readOnly =
92
92
  const dynExt = () => [
93
93
  EditorState.readOnly.of(readOnly),
94
94
  EditorView.editable.of(!readOnly),
95
- EditorView.contentAttributes.of({ "aria-label": label }),
95
+ // `tabindex="0"` (21/10/2026): o CodeMirror põe -1 na área de rolagem, e com o código mais alto que o editor o axe
96
+ // reprovava `scrollable-region-focusable` — a área rola e nada dentro DIZ que recebe o teclado. O conteúdo já era
97
+ // parada de Tab (contenteditable); no readOnly, é o que deixa o teclado chegar ao código para rolar.
98
+ EditorView.contentAttributes.of({ "aria-label": label, tabindex: "0" }),
96
99
  ...(extensions ?? []),
97
100
  ];
98
101
  React.useEffect(() => {
@@ -0,0 +1,14 @@
1
+ import type { CodeLine } from "./code-client.js";
2
+ /** As línguas que `highlightCode` colore. Com outra, ele devolve `null` e o `CodeBlock` mostra o texto puro. */
3
+ export declare const highlightLanguages: readonly string[];
4
+ /**
5
+ * Colore o código para o `CodeBlock` (a prop `highlight`): devolve as linhas, cada uma com os pedaços de texto e a
6
+ * classe da cor. Língua que não está em `highlightLanguages` devolve `null`, e o bloco sai sem cor.
7
+ *
8
+ * ```tsx
9
+ * import {CodeBlock} from "@aurea-uds/react";
10
+ * import {highlightCode} from "@aurea-uds/react/code-highlight";
11
+ * <CodeBlock language="tsx" highlight={highlightCode} lineNumbers>{code}</CodeBlock>
12
+ * ```
13
+ */
14
+ export declare function highlightCode(code: string, language: string): CodeLine[] | null;
@@ -0,0 +1,92 @@
1
+ // AS CORES DO CÓDIGO (lote V, 20/10/2026). O Victor, comparando as caixas de código do site com as da referência:
2
+ // "não são como dos outros, com numero de linhas laterais e cores". A ficha do `CodeBlock` já prometia código com cores
3
+ // de sintaxe, e o código desenhava texto puro.
4
+ //
5
+ // O MOTOR é o mesmo do `CodeEditor` (decisão do Victor, "A: motor da Aurea"): o `@lezer/highlight`, com os
6
+ // analisadores do próprio Lezer. A função `highlightCode` dele colore código PARADO — sem editor, sem espera e sem
7
+ // navegador —, então serve ao site, montado no Node, e a quem usa o `CodeBlock` no servidor ou no cliente.
8
+ // As CORES são as do `aureaHighlightStyle` do `CodeEditor`, pelos mesmos grupos de etiquetas: o comentário apagado e
9
+ // em itálico, a palavra-chave e o nome de tipo em azul, o texto em verde, o número em amarelo, a função em 600. Lá elas
10
+ // são estilo de linha (o editor monta no navegador); aqui são CLASSES (`tok-*`), pintadas pelo `aurea.css` com os
11
+ // mesmos tokens, porque o HTML parado não carrega estilo calculado.
12
+ //
13
+ // Módulo próprio, como o `code-editor`: os analisadores são peer OPCIONAL, e quem não usa as cores não os instala
14
+ // (o check 19 do `validate.py` cobra que só este arquivo e o do editor importam o `@lezer/`).
15
+ import { highlightCode as colorirArvore, tagHighlighter, tags as t } from "@lezer/highlight";
16
+ import { parser as js } from "@lezer/javascript";
17
+ import { parser as css } from "@lezer/css";
18
+ import { parser as html } from "@lezer/html";
19
+ import { parser as json } from "@lezer/json";
20
+ import { StreamLanguage } from "@codemirror/language";
21
+ import { shell } from "@codemirror/legacy-modes/mode/shell";
22
+ // As etiquetas do Lezer → as classes que o `aurea.css` pinta. Os grupos são os do `aureaHighlightStyle`.
23
+ const destaque = tagHighlighter([
24
+ { tag: [t.comment, t.lineComment, t.blockComment, t.docComment], class: "tok-comment" },
25
+ { tag: [t.keyword, t.controlKeyword, t.moduleKeyword, t.operatorKeyword, t.definitionKeyword, t.modifier, t.self, t.atom, t.bool, t.null, t.typeName, t.className, t.namespace, t.tagName], class: "tok-keyword" },
26
+ { tag: [t.string, t.character, t.docString, t.regexp, t.escape, t.special(t.string)], class: "tok-string" },
27
+ { tag: [t.number, t.integer, t.float, t.unit], class: "tok-number" },
28
+ { tag: [t.propertyName, t.attributeName, t.labelName], class: "tok-property" },
29
+ { tag: t.function(t.variableName), class: "tok-function" },
30
+ { tag: t.invalid, class: "tok-invalid" },
31
+ ]);
32
+ // As línguas que a Aurea colore. Os nomes são os que o `CodeBlock` recebe em `language`; `sh` e `shell` são o bash.
33
+ const ANALISADORES = {
34
+ js, javascript: js,
35
+ jsx: js.configure({ dialect: "jsx" }),
36
+ ts: js.configure({ dialect: "ts" }), typescript: js.configure({ dialect: "ts" }),
37
+ tsx: js.configure({ dialect: "jsx ts" }),
38
+ css, html, json,
39
+ };
40
+ let bash;
41
+ // O bash vem do modo antigo do CodeMirror (o Lezer não tem gramática de shell); ele só é montado quando pedido.
42
+ function analisador(lingua) {
43
+ const l = lingua.toLowerCase();
44
+ if (l === "bash" || l === "sh" || l === "shell")
45
+ return bash ??= StreamLanguage.define(shell).parser;
46
+ return ANALISADORES[l];
47
+ }
48
+ /** As línguas que `highlightCode` colore. Com outra, ele devolve `null` e o `CodeBlock` mostra o texto puro. */
49
+ export const highlightLanguages = ["bash", "css", "html", "javascript", "js", "json", "jsx", "sh", "shell", "ts", "tsx", "typescript"];
50
+ /**
51
+ * Colore o código para o `CodeBlock` (a prop `highlight`): devolve as linhas, cada uma com os pedaços de texto e a
52
+ * classe da cor. Língua que não está em `highlightLanguages` devolve `null`, e o bloco sai sem cor.
53
+ *
54
+ * ```tsx
55
+ * import {CodeBlock} from "@aurea-uds/react";
56
+ * import {highlightCode} from "@aurea-uds/react/code-highlight";
57
+ * <CodeBlock language="tsx" highlight={highlightCode} lineNumbers>{code}</CodeBlock>
58
+ * ```
59
+ */
60
+ export function highlightCode(code, language) {
61
+ const p = analisador(language);
62
+ if (!p)
63
+ return null;
64
+ // O TRECHO DE JSX. O exemplo de documentação é um pedaço — várias linhas de JSX soltas, uma embaixo da outra —, e o
65
+ // analisador lê código de verdade: o `<` da segunda linha vira "menor que", e a partir dali as cores trocam de lugar
66
+ // (medido na página do Button, 20/10/2026: só a primeira linha saía certa). Quando a leitura direta tem erro, o
67
+ // trecho é lido de novo dentro de um fragmento (`<>…</>`), fica a leitura com menos erros, e só o trecho original é
68
+ // pintado — o fragmento não aparece.
69
+ let texto = code, arvore = p.parse(code), de = 0;
70
+ if (JSX.has(language.toLowerCase())) {
71
+ const direto = erros(arvore);
72
+ if (direto > 0) {
73
+ const embrulhado = `<>${code}</>`, outra = p.parse(embrulhado);
74
+ if (erros(outra) < direto) {
75
+ texto = embrulhado;
76
+ arvore = outra;
77
+ de = 2;
78
+ }
79
+ }
80
+ }
81
+ const linhas = [[]];
82
+ colorirArvore(texto, arvore, destaque, (pedaco, classes) => { linhas[linhas.length - 1].push(classes ? { text: pedaco, className: classes } : { text: pedaco }); }, () => { linhas.push([]); }, de, de + code.length);
83
+ return linhas;
84
+ }
85
+ const JSX = new Set(["jsx", "tsx"]);
86
+ // Quantos nós de erro a leitura deixou: é a régua para escolher entre a leitura direta e a do fragmento.
87
+ function erros(arvore) {
88
+ let n = 0;
89
+ arvore.iterate({ enter: (no) => { if (no.type.isError)
90
+ n++; } });
91
+ return n;
92
+ }
@@ -18,14 +18,36 @@ export declare function Alert({ variant, state, title, icon, onDismiss, action,
18
18
  /** O botão do aviso ("Atualizar", "Desfazer"): depois do texto, antes do X. No celular, embaixo do texto. */
19
19
  action?: ReactNode;
20
20
  }): React.JSX.Element;
21
- export type BannerVariant = "info" | "success" | "warning" | "danger";
22
- export declare function Banner({ variant, state, title, icon, onDismiss, children, className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement> & {
21
+ export type BannerVariant = "info" | "success" | "warning" | "danger" | "consent";
22
+ /** Uma categoria de cookies do aviso de consentimento (GAR-19): a chave, o nome, para que serve e se é necessária. */
23
+ export interface ConsentCategory {
24
+ /** A chave da categoria na escolha que o `onConsent` devolve. */
25
+ id: string;
26
+ label: ReactNode;
27
+ /** Para que serve: o que a pessoa ganha ou perde ligando. */
28
+ description?: ReactNode;
29
+ /** Necessária para o site funcionar: sempre ligada, sem chave para desligar. */
30
+ required?: boolean;
31
+ }
32
+ /** A escolha: a chave de cada categoria, ligada ou não. As necessárias vêm sempre ligadas. */
33
+ export type ConsentChoice = Record<string, boolean>;
34
+ /** Como a pessoa escolheu: aceitou tudo, rejeitou o que não é necessário, ou escolheu na janela. */
35
+ export type ConsentAction = "accept-all" | "reject" | "custom";
36
+ export interface BannerProps extends Omit<HTMLAttributes<HTMLDivElement>, "title">, RefAttributes<HTMLDivElement> {
23
37
  variant?: BannerVariant;
24
38
  state?: UniversalState;
25
39
  title?: ReactNode;
26
40
  icon?: IconName;
41
+ /** Desenha o X. No `consent`, é o botão "Ocultar esta mensagem" da confirmação; sem ele, o aviso some sozinho. */
27
42
  onDismiss?: () => void;
28
- }): React.JSX.Element;
43
+ /** Só no `consent`: as categorias da janela de preferências, na ordem em que aparecem. */
44
+ categories?: ConsentCategory[];
45
+ /** Só no `consent`: a escolha que já está guardada — para a pessoa voltar e mudar. Sem ela, só as necessárias ligadas. */
46
+ value?: ConsentChoice;
47
+ /** Só no `consent`: a escolha feita, para o app guardar e obedecer. As necessárias vêm sempre `true`. */
48
+ onConsent?: (choice: ConsentChoice, action: ConsentAction) => void;
49
+ }
50
+ export declare function Banner(props: BannerProps): React.JSX.Element;
29
51
  export type SpinnerSize = "sm" | "md" | "lg" | "xl";
30
52
  export declare function Spinner({ size, label, decorative, className, ...props }: HTMLAttributes<HTMLSpanElement> & RefAttributes<HTMLSpanElement> & {
31
53
  size?: Responsive<SpinnerSize>;
@@ -9,13 +9,15 @@ import { Popover as BasePopover } from "@base-ui/react/popover";
9
9
  import { cx, useAureaStrings, usePortalContainer, stateSeverity } from "./internal.js";
10
10
  import { Icon } from "./system.js";
11
11
  import { Button, IconButton, CloseButton } from "./actions.js";
12
+ // NotificationCenter aceita `side`: o tipo é do módulo que define overlay, não uma cópia.
13
+ import { Dialog } from "./overlays.js";
12
14
  // `oracle` saiu daqui (achado M9, 26/07/2026): estava no tipo e no CSS, e NÃO estava na
13
15
  // ficha — ou seja, era superfície pública que o contrato não declarava. E é vocabulário do
14
16
  // app de origem (papel de agente), não do sistema, como as classes de domínio que o achado
15
17
  // A6 mapeou. As classes `.badge-oracle`/`.btn-oracle` seguem no core porque o
16
18
  // `apps/docs/index.html` escrito à mão as usa; saem junto com ele, na Fase 4 do plano.
17
19
  // `.btn-oracle` nunca foi alcançável pelo React — `ButtonVariant` não tem `oracle`.
18
- import { Skeleton } from "./markup.js";
20
+ import { Skeleton, Badge, Switch } from "./markup.js";
19
21
  // Status (DIRECTION §3.6): condição OPERACIONAL — ponto + rótulo. Não é Badge: Badge é
20
22
  // metadado curto num pill; Status diz em que estado a coisa está. Reusa o .status-dot que
21
23
  // já existia solto. A variante colore só o PONTO (currentColor); o rótulo fica legível em
@@ -54,7 +56,50 @@ const ICONE_DA_VARIANTE = { info: "info",
54
56
  // `action` (15/10/2026, o "Upgrade" da referência): o botão do aviso, depois do texto e antes do X; no celular ele desce
55
57
  // para baixo do texto, na mesma coluna (a referência repete o botão; aqui ele só muda de lugar).
56
58
  export function Alert({ variant, state, title, icon, onDismiss, action, children, className, ...props }) { const s = useAureaStrings(); const v = variant ?? (state ? stateSeverity(state) : "info"); return _jsxs("div", { className: cx("alert", `alert-${v}`, action != null && "alert-has-action", className), role: v === "danger" ? "alert" : "status", "data-state": state, ...props, children: [_jsx(Icon, { name: icon ?? ICONE_DA_VARIANTE[v], weight: icon ? undefined : "fill" }), _jsxs("div", { children: [title && _jsx("strong", { children: title }), children ?? (state ? s.universalState[state] : null)] }), action != null && _jsx("div", { className: "alert-action", children: action }), onDismiss ? _jsx(CloseButton, { onClick: onDismiss }) : _jsx("span", {})] }); }
57
- export function Banner({ variant, state, title, icon, onDismiss, children, className, ...props }) { const s = useAureaStrings(); const v = variant ?? (state ? stateSeverity(state) : "info"); return _jsxs("div", { className: cx("banner", `banner-${v}`, className), role: v === "danger" ? "alert" : "status", "data-state": state, ...props, children: [icon ? _jsx(Icon, { name: icon }) : _jsx("span", {}), _jsxs("div", { children: [title && _jsx("strong", { children: title }), children ?? (state ? s.universalState[state] : null)] }), onDismiss ? _jsx(IconButton, { variant: "ghost", size: "sm", icon: "x", label: s.close, onClick: onDismiss }) : _jsx("span", {})] }); }
59
+ export function Banner(props) {
60
+ if (props.variant === "consent")
61
+ return _jsx(BannerConsent, { ...props });
62
+ const { variant, state, title, icon, onDismiss, children, className, categories: _c, value: _v, onConsent: _o, ...rest } = props;
63
+ const s = useAureaStrings();
64
+ const v = variant ?? (state ? stateSeverity(state) : "info");
65
+ return _jsxs("div", { className: cx("banner", `banner-${v}`, className), role: v === "danger" ? "alert" : "status", "data-state": state, ...rest, children: [icon ? _jsx(Icon, { name: icon }) : _jsx("span", {}), _jsxs("div", { children: [title && _jsx("strong", { children: title }), children ?? (state ? s.universalState[state] : null)] }), onDismiss ? _jsx(IconButton, { variant: "ghost", size: "sm", icon: "x", label: s.close, onClick: onDismiss }) : _jsx("span", {})] });
66
+ }
67
+ // GAR-19 (lote U, 19/10/2026): o aviso de cookies é uma VARIAÇÃO do Banner (decisão do Victor). Nenhuma referência da fila
68
+ // tem a peça aberta; as regras vêm de duas fontes primárias, lidas em 19/10/2026:
69
+ // - o guia de cookies da ANPD (págs. 30–33): no primeiro nível, o botão de rejeitar os não necessários, tão fácil de ver
70
+ // quanto o de aceitar (nada de destaque só no aceite); categoria não necessária DESLIGADA por padrão; um segundo nível
71
+ // com as categorias; e um jeito direto de mudar a escolha depois. Os três botões são os do exemplo do guia.
72
+ // - o aviso de cookies do governo britânico: no alto da página, sem `position:fixed` (que cobriria o foco — WCAG 2.4.11),
73
+ // uma região com nome e título h2, e a confirmação depois da escolha com `role="alert"`, que recebe o foco.
74
+ // O app guarda a escolha (`onConsent`) e deixa de desenhar o aviso; para mudar depois, desenha de novo, com `value`.
75
+ function BannerConsent({ title, icon: _icon, state: _state, variant: _variant, onDismiss, categories = [], value, onConsent, children, className, ...props }) {
76
+ const s = useAureaStrings();
77
+ const tituloId = React.useId();
78
+ const inicial = React.useCallback(() => Object.fromEntries(categories.map(c => [c.id, c.required ? true : value?.[c.id] === true])), [categories, value]);
79
+ const [escolha, setEscolha] = React.useState(inicial);
80
+ const [aberta, setAberta] = React.useState(false);
81
+ const [feito, setFeito] = React.useState(null);
82
+ const [oculto, setOculto] = React.useState(false);
83
+ const aviso = React.useRef(null);
84
+ // A confirmação recebe o foco quando aparece: o botão que a pessoa apertou some com a pergunta.
85
+ React.useEffect(() => { if (feito)
86
+ aviso.current?.focus(); }, [feito]);
87
+ const escolher = (acao, custom) => {
88
+ const final = Object.fromEntries(categories.map(c => [c.id, c.required ? true : acao === "accept-all" ? true : acao === "reject" ? false : custom?.[c.id] === true]));
89
+ setEscolha(final);
90
+ setAberta(false);
91
+ setFeito(acao);
92
+ onConsent?.(final, acao);
93
+ };
94
+ if (oculto)
95
+ return null;
96
+ const confirmacao = feito === "accept-all" ? s.consentAccepted : feito === "reject" ? s.consentRejected : s.consentSaved;
97
+ return _jsxs("div", { role: "region", "aria-labelledby": tituloId, className: cx("banner", "banner-consent", className), ...props, children: [_jsx("h2", { id: tituloId, className: "banner-consent-title", children: title ?? s.consentTitle }), feito
98
+ ? _jsxs(_Fragment, { children: [_jsx("div", { ref: aviso, role: "alert", tabIndex: -1, className: "banner-consent-message", children: confirmacao }), _jsx("div", { className: "banner-consent-actions", children: _jsx(Button, { variant: "secondary", onClick: () => { onDismiss ? onDismiss() : setOculto(true); }, children: s.consentHide }) })] })
99
+ : _jsxs(_Fragment, { children: [_jsx("div", { className: "banner-consent-text", children: children }), _jsxs("div", { className: "banner-consent-actions", children: [_jsx(Button, { variant: "secondary", onClick: () => escolher("reject"), children: s.consentReject }), _jsx(Button, { variant: "secondary", onClick: () => escolher("accept-all"), children: s.consentAccept }), _jsx(Button, { variant: "tertiary", onClick: () => { setEscolha(inicial()); setAberta(true); }, children: s.consentChoose })] })] }), _jsx(Dialog, { open: aberta, title: s.consentPreferences, onClose: () => setAberta(false), footer: _jsxs(_Fragment, { children: [_jsx(Button, { variant: "secondary", onClick: () => escolher("reject"), children: s.consentReject }), _jsx(Button, { variant: "secondary", onClick: () => escolher("accept-all"), children: s.consentAccept }), _jsx(Button, { variant: "primary", onClick: () => escolher("custom", escolha), children: s.consentSave })] }), children: _jsx("div", { className: "banner-consent-categories", children: categories.map(c => c.required
100
+ ? _jsxs("div", { className: "banner-consent-required", children: [_jsxs("div", { className: "banner-consent-required-head", children: [_jsx("strong", { children: c.label }), _jsx(Badge, { children: s.consentRequired })] }), c.description != null && _jsx("p", { children: c.description })] }, c.id)
101
+ : _jsx(Switch, { label: c.label, description: c.description, checked: escolha[c.id] === true, onChange: (e) => { const ligado = e.currentTarget.checked; setEscolha(atual => ({ ...atual, [c.id]: ligado })); } }, c.id)) }) })] });
102
+ }
58
103
  export function Spinner({ size = "md", label, decorative, className, ...props }) { const s = useAureaStrings(); return _jsx("span", { className: cx("spinner", peleDoEixo("spinner", size, "sm", "spinner"), className), ...(decorative ? { "aria-hidden": true } : { role: "status", "aria-label": label ?? s.loading }), ...props }); }
59
104
  // `children` como FUNÇÃO é de propósito para o caso `loading`: assim o consumidor não paga o
60
105
  // render do conteúdo enquanto ele não existe. Aceita nó também, porque a maioria das telas já
@@ -1,2 +1,2 @@
1
1
  export * from "./feedback-client.js";
2
- export { Badge, formatBadgeCount, Progress, Skeleton, type BadgeVariant, type BadgeCategory, type BadgeEmphasis, type BadgeSize, type BadgePlacement, type BadgeProps, type ProgressProps, type ProgressTone } from "./markup.js";
2
+ export { Badge, Chip, formatBadgeCount, Progress, Skeleton, type BadgeVariant, type BadgeCategory, type BadgeEmphasis, type BadgeSize, type BadgePlacement, type BadgeProps, type ChipProps, type ProgressProps, type ProgressTone } from "./markup.js";
package/dist/feedback.js CHANGED
@@ -2,4 +2,4 @@
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 "./feedback-client.js";
5
- export { Badge, formatBadgeCount, Progress, Skeleton } from "./markup.js";
5
+ export { Badge, Chip, formatBadgeCount, Progress, Skeleton } from "./markup.js";
package/dist/graph.d.ts CHANGED
@@ -34,7 +34,10 @@ export interface GraphNodeItem {
34
34
  tone?: GraphTone;
35
35
  };
36
36
  ports?: GraphPort[];
37
- /** A camada sugerida pelo app, contada de 0 (só na arrumação `layered`). */
37
+ /** A FAIXA do nó na arrumação `layered`: é ORDEM, não número — 0, 5 e 10 viram a 1ª, a 2ª e a 3ª, e nós com o mesmo
38
+ * `layer` saem na mesma altura (MNT-27). Vale quando TODO nó fora de contêiner tem um; faltando em algum, o mapa sai
39
+ * como sem `layer` e avisa uma vez no console. O contêiner entra na faixa dele (ou na menor dos nós de dentro), e
40
+ * DENTRO dele o motor arruma sozinho: lá o `layer` não vale. */
38
41
  layer?: number;
39
42
  /** O CONTÊINER deste nó (site, andar, rack): um só. O contêiner é um nó como os outros, e vira
40
43
  * a caixa em volta dos filhos, com o botão de fechar (MNT-16.6). VLAN não é contêiner: um
package/dist/graph.js CHANGED
@@ -171,6 +171,7 @@ const LADO_ELK = { top: "NORTH", right: "EAST", bottom: "SOUTH", left: "WEST" };
171
171
  // E no nó com porta, a linha SEM porta vai a uma porta "de base", no meio do lado de entrada ou de
172
172
  // saída: medido no protótipo, sem ela o arrumador ligava a linha no CANTO do nó (o 0,0 da caixa).
173
173
  let avisouSemElk = false;
174
+ let avisouFaixa = false;
174
175
  let elkNaTela = null;
175
176
  // FORA DA TELA PRINCIPAL (MNT-19.1): o `elk.bundled.js` roda na própria tela (é um "falso trabalhador").
176
177
  // Com `layoutWorker`, o APP entrega o trabalhador de verdade — o jeito de criar um trabalhador muda de
@@ -224,13 +225,36 @@ async function arrumarComElk(elk, e) {
224
225
  }
225
226
  arestas = arvore;
226
227
  }
228
+ // A FAIXA QUE O APP PEDE (`layer`, MNT-27, 17/10/2026). A opção que ia antes (`layerChoiceConstraint`) só é lida pelo
229
+ // arrumador interativo do ELK, que o `elkjs` não tem: medido no 0.12.0, o mapa saía igual com e sem ela — o firewall
230
+ // secundário caía abaixo do núcleo, como o app relatou. O que funciona é a PARTIÇÃO do motor (ordem das faixas). Medido
231
+ // no motor: (1) com partição em só alguns nós, nada muda — por isso ela liga só quando TODO nó de cima tem faixa;
232
+ // (2) com partição DENTRO de contêiner, o mapa inteiro quebra (o núcleo ia para baixo) — por isso ela vai só nos nós
233
+ // de cima e no contêiner, que entra na faixa dele ou na menor dos de dentro; lá dentro, o motor arruma sozinho.
234
+ const paiDoGrupo = new Map(e.grupos.map(g => [g.id, g.pai]));
235
+ const topoDe = (pai) => { let t = pai; while (t && paiDoGrupo.get(t))
236
+ t = paiDoGrupo.get(t); return t; };
237
+ const faixaDoGrupo = (id) => {
238
+ const g = e.grupos.find(x => x.id === id);
239
+ if (g?.camada != null)
240
+ return g.camada;
241
+ const de = e.folhas.filter(f => f.camada != null && topoDe(f.pai) === id).map(f => f.camada);
242
+ return de.length ? Math.min(...de) : undefined;
243
+ };
244
+ const deCima = [...e.folhas.filter(f => !(hierarquia && f.pai)).map(f => f.camada), ...(hierarquia ? e.grupos.filter(g => !g.pai).map(g => faixaDoGrupo(g.id)) : [])];
245
+ const algumaFaixa = e.algoritmo === "layered" && e.folhas.some(f => f.camada != null);
246
+ const porFaixa = algumaFaixa && deCima.every(c => c != null);
247
+ if (algumaFaixa && !porFaixa && !avisouFaixa) {
248
+ avisouFaixa = true;
249
+ console.warn("DependencyGraph: `layer` só vale quando todo nó fora de contêiner tem um (e todo contêiner, ou um nó dentro dele). Ficou a arrumação sem faixas.");
250
+ }
227
251
  const comPortas = new Set(e.algoritmo === "layered" ? e.folhas.filter(f => f.portas.length).map(f => f.id) : []);
228
252
  const noElk = (f) => {
229
253
  const opcoes = {};
230
254
  if (f.raiz && e.algoritmo === "layered")
231
255
  opcoes["elk.layered.layering.layerConstraint"] = "FIRST";
232
- if (f.camada != null && e.algoritmo === "layered")
233
- opcoes["elk.layered.layering.layerChoiceConstraint"] = String(f.camada);
256
+ if (porFaixa && !f.pai)
257
+ opcoes["elk.partitioning.partition"] = String(f.camada);
234
258
  if (!comPortas.has(f.id))
235
259
  return { id: f.id, width: f.larg, height: f.alt, layoutOptions: opcoes };
236
260
  opcoes["elk.portConstraints"] = "FIXED_POS";
@@ -252,7 +276,8 @@ async function arrumarComElk(elk, e) {
252
276
  const recheio = `[top=${RECHEIO_DO_GRUPO + CABECA_DO_GRUPO},left=${RECHEIO_DO_GRUPO},bottom=${RECHEIO_DO_GRUPO},right=${RECHEIO_DO_GRUPO}]`;
253
277
  if (hierarquia)
254
278
  for (const g of e.grupos)
255
- caixas.set(g.id, { id: g.id, children: [], layoutOptions: { "elk.padding": recheio } });
279
+ caixas.set(g.id, { id: g.id, children: [], layoutOptions: { "elk.padding": recheio,
280
+ ...(porFaixa && !g.pai ? { "elk.partitioning.partition": String(faixaDoGrupo(g.id)) } : {}) } });
256
281
  const dentro = (pai) => (pai && caixas.get(pai)) || raiz;
257
282
  if (hierarquia)
258
283
  for (const g of e.grupos)
@@ -265,6 +290,7 @@ async function arrumarComElk(elk, e) {
265
290
  ...(e.algoritmo === "layered" ? { "elk.algorithm": "layered", "elk.direction": vertical ? "DOWN" : "RIGHT",
266
291
  "elk.layered.spacing.nodeNodeBetweenLayers": String(VAO_X),
267
292
  "elk.layered.nodePlacement.strategy": "BRANDES_KOEPF", "elk.layered.nodePlacement.bk.fixedAlignment": "BALANCED",
293
+ ...(porFaixa ? { "elk.partitioning.activate": "true" } : {}),
268
294
  ...(hierarquia ? { "elk.hierarchyHandling": "INCLUDE_CHILDREN" } : {}) }
269
295
  : e.algoritmo === "mrtree" ? { "elk.algorithm": "mrtree", "elk.direction": vertical ? "DOWN" : "RIGHT" }
270
296
  : { "elk.algorithm": "radial" }) };
@@ -654,8 +680,8 @@ export function DependencyGraph({ nodes, edges, label, selectedId, onSelect, con
654
680
  const algoritmo = layout === "layered" ? "layered" : layout === "tree" ? "mrtree" : layout === "radial" ? "radial" : null;
655
681
  const entradaElk = React.useMemo(() => algoritmo ? { algoritmo, orientacao: orientation,
656
682
  folhas: folhas.map(n => ({ id: n.id, ...tamanho(n.id), portas: n.ports ?? [], camada: n.layer, pai: paiAberto(n.id), raiz: n.id === rootId })),
657
- grupos: [...abertos].sort((a, b) => profundidade(a) - profundidade(b)).map(id => ({ id, pai: paiAberto(id) })),
658
- arestas: desenhadas.map((x, i) => ({ id: ident[i].id, de: x.item.from, para: x.item.to, portaDe: x.item.fromPort, portaPara: x.item.toPort })) } : null, [algoritmo, orientation, folhas, tamanho, paiAberto, rootId, abertos, profundidade, desenhadas, ident]);
683
+ grupos: [...abertos].sort((a, b) => profundidade(a) - profundidade(b)).map(id => ({ id, pai: paiAberto(id), camada: porId.get(id)?.layer })),
684
+ arestas: desenhadas.map((x, i) => ({ id: ident[i].id, de: x.item.from, para: x.item.to, portaDe: x.item.fromPort, portaPara: x.item.toPort })) } : null, [algoritmo, orientation, folhas, tamanho, paiAberto, rootId, abertos, profundidade, desenhadas, ident, porId]);
659
685
  const chaveElk = React.useMemo(() => entradaElk ? JSON.stringify(entradaElk) : "", [entradaElk]);
660
686
  // A arrumação chega DEPOIS (é assíncrona e o pacote é opcional); até lá, e no servidor, a simples.
661
687
  const [elk, setElk] = React.useState(null);
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, Container, Section, KPI, DataList, Timeline, Prose, Text, Heading, Paragraph, Code, Badge, Progress, Skeleton, Link, ColorSwatch, ProgressCircle, AvatarGroup, LogStream, MediaPlayerShell, Header, Topbar, Kbd, Textarea, Checkbox, Radio, Switch, Range, formatBadgeCount, type BadgeVariant, type BadgeCategory, type BadgeEmphasis, type BadgeSize, type BadgePlacement, type BadgeProps, type KPIProps, type KPIDirection, type KPITone, type KPIVariant, type ProgressProps, type ProgressTone, type AvatarSize, type HeaderVariant, type HeaderProps, type TopbarVariant, type SectionVariant, type SectionFooterGroup, type CardProps, type CardAccent, type TextProps, type HeadingProps, type ParagraphProps, type CodeProps, type TypographyType, type TypographyColor, type TypographyWeight, type TypographyAlign, type HeadingLevel, type ParagraphSize, type LinkProps, type ColorSwatchProps, type ColorSwatchSize, type ProgressCircleProps, type ProgressCircleSize, type ProgressSize, type SkeletonAnimation, type TypographyTone } from "./markup.js";
5
+ export { AspectRatio, InputGroup, InputGroupAddon, Label, Card, Stack, Cluster, Grid, Container, Section, KPI, DataList, Timeline, Prose, Text, Heading, Paragraph, Code, Badge, Chip, Progress, Skeleton, Link, ColorSwatch, ProgressCircle, AvatarGroup, LogStream, MediaPlayerShell, Header, Topbar, Kbd, Textarea, Checkbox, Radio, Switch, Range, formatBadgeCount, type BadgeVariant, type BadgeCategory, type BadgeEmphasis, type BadgeSize, type BadgePlacement, type BadgeProps, type ChipProps, type KPIProps, type KPIDirection, type KPITone, type KPIVariant, type ProgressProps, type ProgressTone, type AvatarSize, type HeaderVariant, type HeaderProps, type TopbarVariant, type SectionVariant, type SectionFooterGroup, type CardProps, type CardAccent, type TextProps, type HeadingProps, type ParagraphProps, type CodeProps, type TypographyType, type TypographyColor, type TypographyWeight, type TypographyAlign, type HeadingLevel, type ParagraphSize, type LinkProps, type ColorSwatchProps, type ColorSwatchSize, type ProgressCircleProps, type ProgressCircleSize, type ProgressSize, type SkeletonAnimation, type TypographyTone } 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, Container, Section, KPI, DataList, Timeline, Prose, Text, Heading, Paragraph, Code, Badge, Progress, Skeleton, Link, ColorSwatch, ProgressCircle, AvatarGroup, LogStream, MediaPlayerShell, Header, 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, Chip, Progress, Skeleton, Link, ColorSwatch, ProgressCircle, 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,6 +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 { Icon } from "./system.js";
14
15
  import { Sidebar, Header } from "./navigation.js";
15
16
  // ── Auxiliar de topo: mora ANTES do primeiro export, e a posição é obrigatória ───────────────
16
17
  // O check 22 mede o corpo de um componente do `export` dele até o PRÓXIMO export — fatia longa
@@ -92,24 +93,32 @@ const SHELL_NAV_ID = "aurea-shell-nav";
92
93
  // CSS acima de lg. Girar um tablet ou encaixar a janela de lado no Windows bastava. O número é o
93
94
  // `ESCALA.lg`, gerado dos tokens pela mesma leitura que escreve o `@media (max-width:1023px)` do
94
95
  // core: um número só, e o `consumidores-lote1.test` cobra que o do `aurea.js` é o mesmo.
95
- function useGavetaFechaNoDesktop() {
96
+ // No `layout="docs"` (lote U, 19/10/2026) a lateral é coluna desde 768 (`ESCALA.md`), como a da documentação da
97
+ // referência, e o índice, que abaixo de 1280 é a gaveta da barra do índice, volta a ser coluna em 1280 (`ESCALA.xl`): cada
98
+ // gaveta fecha no corte DELA.
99
+ const SHELL_TOC_ID = "aurea-shell-toc";
100
+ function useGavetaFechaNoDesktop(docs = false) {
96
101
  useEffect(() => {
97
102
  if (typeof window === "undefined" || typeof window.matchMedia !== "function")
98
103
  return;
99
- const mq = window.matchMedia(`(min-width: ${ESCALA.lg}px)`);
100
- const aoMudar = (e) => {
104
+ const fechar = (id) => (e) => {
101
105
  if (!e.matches)
102
106
  return;
103
- const gaveta = document.getElementById(SHELL_NAV_ID);
107
+ const gaveta = document.getElementById(id);
104
108
  try {
105
109
  if (gaveta?.matches(":popover-open"))
106
110
  gaveta.hidePopover();
107
111
  }
108
112
  catch { /* motor sem popover */ }
109
113
  };
110
- mq.addEventListener?.("change", aoMudar);
111
- return () => mq.removeEventListener?.("change", aoMudar);
112
- }, []);
114
+ const pares = [[window.matchMedia(`(min-width: ${docs ? ESCALA.md : ESCALA.lg}px)`), fechar(SHELL_NAV_ID)]];
115
+ if (docs)
116
+ pares.push([window.matchMedia(`(min-width: ${ESCALA.xl}px)`), fechar(SHELL_TOC_ID)]);
117
+ for (const [mq, f] of pares)
118
+ mq.addEventListener?.("change", f);
119
+ return () => { for (const [mq, f] of pares)
120
+ mq.removeEventListener?.("change", f); };
121
+ }, [docs]);
113
122
  }
114
123
  // A LISTA DA LATERAL ENTRA PELO SHELL (A-03, 24/09/2026). O shell cria o `<Sidebar>` e só
115
124
  // repassava `children`; quem queria a lista declarativa (`items` + `current`) tinha de passar OUTRO
@@ -148,7 +157,8 @@ function useLargura(query) {
148
157
  }
149
158
  export function AppShell({ brand, navigation, navItems, currentNavId, navLabel, topbar, topbarVariant = "floating", topbarDivider, topbarTabs, topbarCurrentTab, topbarTabsLabel, layout = "app", sidebarVariant, sidebarScrollbar, sidebarCollapsed, sidebarCollapsible, defaultSidebarCollapsed, onSidebarCollapsedChange, contentVariant = "surface", aside, asideLabel, asideVariant, children, className, ...props }) {
150
159
  const s = useAureaStrings();
151
- useGavetaFechaNoDesktop();
160
+ const docs = layout === "docs";
161
+ useGavetaFechaNoDesktop(docs);
152
162
  const controlado = sidebarCollapsed !== undefined;
153
163
  // `null` = ninguém escolheu, e vale a largura.
154
164
  const [escolha, setEscolha] = useState(defaultSidebarCollapsed ?? null);
@@ -180,7 +190,13 @@ export function AppShell({ brand, navigation, navItems, currentNavId, navLabel,
180
190
  // A condição vai escrita no `icon=` do botão, e não numa variável: é ali que o check 46 lê os
181
191
  // ícones que o shell desenha.
182
192
  const paraOComeco = !efetiva, direita = useDirection() === "rtl";
183
- return _jsxs("div", { className: cx("app-shell", layout === "docs" && "app-shell-docs", topbarVariant === "flush" && "app-shell-flush", sidebarCollapsible && "app-shell-collapsible", aside != null && "app-shell-with-aside", className), ...props, children: [_jsx("a", { className: "skip-link", href: `#${SHELL_MAIN_ID}`, children: s.skipToContent }), _jsx(Header, { variant: topbarVariant, divider: topbarDivider, tabs: topbarTabs, currentTab: topbarCurrentTab, tabsLabel: topbarTabsLabel, ...(layout === "docs" ? { maxWidth: "docs", size: "sm" } : {}), 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, scrollbar: sidebarScrollbar, 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 }), aside != null && _jsx(Sidebar, { placement: "right", variant: asideVariant ?? sidebarVariant, className: "app-shell-aside", "aria-label": asideLabel ?? s.tocLabel, children: aside })] });
193
+ // O BOTÃO DA GAVETA. No `layout="docs"` ele vai para o FIM da barra, depois das ações, como o da documentação da
194
+ // referência no celular (o "Open Sidebar" à direita, 19/10/2026): ali ele vem por último também na ordem do Tab, e a
195
+ // gaveta abre pelo mesmo lado (a folha). No shell de sempre, continua antes da marca.
196
+ // No arranjo, o topo é o pequeno (`size="sm"`), e o botão também: com o tamanho de sempre ele ficava 4 maior que os
197
+ // vizinhos e fora da linha deles (medido a 375, sem toque; com toque, todos sobem para 44).
198
+ const botaoDaGaveta = _jsx(IconButton, { className: "nav-toggle", icon: "list", label: s.navigationToggle, popoverTarget: SHELL_NAV_ID, ...(docs ? { size: "sm" } : {}) });
199
+ return _jsxs("div", { className: cx("app-shell", layout === "docs" && "app-shell-docs", topbarVariant === "flush" && "app-shell-flush", sidebarCollapsible && "app-shell-collapsible", aside != null && "app-shell-with-aside", className), ...props, children: [_jsx("a", { className: "skip-link", href: `#${SHELL_MAIN_ID}`, children: s.skipToContent }), _jsxs(Header, { variant: topbarVariant, divider: topbarDivider, tabs: topbarTabs, currentTab: topbarCurrentTab, tabsLabel: topbarTabsLabel, ...(docs ? { maxWidth: "docs", size: "sm" } : {}), brand: docs ? brand : _jsxs(_Fragment, { children: [botaoDaGaveta, brand] }), children: [topbar, docs && botaoDaGaveta] }), 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, scrollbar: sidebarScrollbar, collapsed: efetiva, items: navItems, current: currentNavId, label: navLabel, onToggle: focoDaGaveta, children: navigation }), docs && aside != null && _jsx("div", { className: "docs-toc-bar", children: _jsxs("button", { type: "button", className: "docs-toc-toggle", popoverTarget: SHELL_TOC_ID, children: [_jsx(Icon, { name: "list-bullets" }), _jsx("span", { className: "docs-toc-current", "data-toc-current": "", children: asideLabel ?? s.tocLabel }), _jsx(Icon, { name: "caret-down" })] }) }), _jsx("main", { id: SHELL_MAIN_ID, tabIndex: -1, className: cx("content", contentVariant === "plain" && "content-plain"), children: children }), aside != null && _jsx(Sidebar, { placement: "right", variant: asideVariant ?? sidebarVariant, className: "app-shell-aside", "aria-label": asideLabel ?? s.tocLabel, ...(docs ? { id: SHELL_TOC_ID, popover: "auto", onToggle: focoDaGaveta } : {}), children: aside })] });
184
200
  }
185
201
  export function Separator({ orientation, spacing = "none", className, ...props }) {
186
202
  const ancora = useRef(null);
package/dist/markup.d.ts CHANGED
@@ -114,8 +114,8 @@ export interface ContainerProps extends HTMLAttributes<HTMLDivElement>, RefAttri
114
114
  export declare function Container({ size, className, ...props }: ContainerProps): React.JSX.Element;
115
115
  /** O fundo da faixa: o da página (padrão), o de cartão ou o rebaixado. */
116
116
  export type SectionSurface = "background" | "card" | "inset";
117
- /** `base` é a faixa comum; `footer` é o rodapé do site (GAR-06, 07/10/2026). */
118
- export type SectionVariant = "base" | "footer";
117
+ /** `base` é a faixa comum; `footer` é o rodapé do site (GAR-06, 07/10/2026); `hero` é a abertura da página (GAR-21, 19/10/2026). */
118
+ export type SectionVariant = "base" | "footer" | "hero";
119
119
  /** Uma coluna de links do rodapé: o título e os itens. */
120
120
  export interface SectionFooterGroup {
121
121
  title: ReactNode;
@@ -123,7 +123,7 @@ export interface SectionFooterGroup {
123
123
  }
124
124
  /** O respiro de cima e de baixo: `md` (padrão, 64 e 96 a partir do `md`) ou `sm` (32 e 48). */
125
125
  export type SectionSpacing = "sm" | "md";
126
- export interface SectionProps extends HTMLAttributes<HTMLElement>, RefAttributes<HTMLElement> {
126
+ export interface SectionProps extends Omit<HTMLAttributes<HTMLElement>, "title">, RefAttributes<HTMLElement> {
127
127
  surface?: SectionSurface;
128
128
  spacing?: SectionSpacing;
129
129
  /**
@@ -141,23 +141,37 @@ export interface SectionProps extends HTMLAttributes<HTMLElement>, RefAttributes
141
141
  brand?: ReactNode;
142
142
  /** Só no `footer`: as colunas de links, cada uma com título. Os itens são `SidebarItem` (`id`, `label`, `href`, `render`). */
143
143
  links?: SectionFooterGroup[];
144
- /** Só no `footer`: a linha de baixo — direitos, termos, privacidade. */
145
144
  /** Só no `footer` (15/10/2026): `"columns"` (o padrão, o rodapé de site grande) ou `"inline"` — UMA linha centrada, como
146
145
  * o rodapé da página inicial da referência: a frase legal, os links (sem os títulos das colunas) e o que vier dentro
147
146
  * (os ícones sociais). A marca não entra. */
148
147
  layout?: "columns" | "inline";
148
+ /** Só no `footer`: a linha de baixo — direitos, termos, privacidade. */
149
149
  legal?: ReactNode;
150
- /** Só no `footer`: até onde o miolo cresce, pela escala do `Container`. Padrão: `xl`. */
150
+ /** No `footer` e no `hero`: até onde o miolo cresce, pela escala do `Container`. Padrão: `xl`. */
151
151
  maxWidth?: ContainerSize;
152
152
  /** Só no `footer`: o nome da navegação do rodapé para o leitor de tela. Padrão: `"Footer"`. */
153
153
  navLabel?: string;
154
+ /** No `hero`: o título da abertura. Nas outras variações, um texto aqui é o atributo `title` do HTML, como antes. */
155
+ title?: ReactNode;
156
+ /** Só no `hero`: a etiqueta do título. Padrão: `"h1"` — a abertura é o começo da página. */
157
+ titleAs?: "h1" | "h2";
158
+ /** Só no `hero`: a sobrelinha, acima do título — um selo, uma frase curta, um link para o que mudou. */
159
+ eyebrow?: ReactNode;
160
+ /** Só no `hero`: o texto abaixo do título. */
161
+ description?: ReactNode;
162
+ /** Só no `hero`: os botões, ou o campo de e-mail com o botão. */
163
+ actions?: ReactNode;
164
+ /** Só no `hero`: a imagem, ou a peça que prova o que o texto diz. Com `align="start"`, fica ao lado do texto a partir de 1024. */
165
+ media?: ReactNode;
166
+ /** Só no `hero`: `"start"` (o padrão; o texto à esquerda e a imagem ao lado) ou `"center"` (tudo centrado, a imagem embaixo). */
167
+ align?: "start" | "center";
154
168
  }
155
169
  /**
156
170
  * A faixa de ponta a ponta de uma página de site (GAR-04): `<section>` com fundo e respiro de site.
157
171
  * O conteúdo vai dentro de um `Container`. Dê um nome à faixa (`aria-labelledby` no título dela)
158
172
  * quando ela for uma região que o leitor de tela deva listar.
159
173
  */
160
- export declare function Section({ surface, spacing, theme, variant, brand, links, legal, layout, maxWidth, navLabel, children, className, ...props }: SectionProps): React.JSX.Element;
174
+ export declare function Section({ surface, spacing, theme, variant, brand, links, legal, layout, maxWidth, navLabel, title, titleAs: Titulo, eyebrow, description, actions, media, align, children, className, ...props }: SectionProps): React.JSX.Element;
161
175
  export type KPIDirection = "up" | "down" | "flat";
162
176
  export type KPITone = "success" | "danger" | "neutral";
163
177
  export type KPIVariant = "card" | "plain";
@@ -263,6 +277,10 @@ export interface BadgeProps extends HTMLAttributes<HTMLSpanElement>, RefAttribut
263
277
  badgeContent?: ReactNode;
264
278
  }
265
279
  export declare function Badge({ variant: variantProp, tone, emphasis, size, dot, leading, trailing, image, imageAlt, count, max, showZero, fit, anchor, anchorShape, invisible, badgeContent, children, className, ...props }: BadgeProps): React.JSX.Element;
280
+ /** `Chip` é outro nome do `Badge` (GAR-20, 19/10/2026): o nome que a referência dá à mesma peça. Igual em tudo. */
281
+ export type ChipProps = BadgeProps;
282
+ /** `Chip` é outro nome do `Badge` (GAR-20, 19/10/2026): o nome que a referência dá à mesma peça. Igual em tudo. */
283
+ export declare function Chip(props: BadgeProps): React.JSX.Element;
266
284
  /** O tom da barra: a mesma lista fechada do `ButtonTone`. Pausado é `neutral`; falha é `danger`. */
267
285
  export type ProgressTone = "brand" | "neutral" | "success" | "warning" | "danger" | "info";
268
286
  export interface ProgressProps {
package/dist/markup.js CHANGED
@@ -95,17 +95,25 @@ export function Container({ size = "xl", className, ...props }) {
95
95
  // (`spacing`) e o tema próprio (`theme` — rodapé escuro numa página clara). Nenhuma referência da
96
96
  // fila tem um rodapé aberto; o desenho é da Aurea, com tokens que já existem. Os links de cada
97
97
  // coluna são `SidebarItem`, a mesma forma dos menus, e o `render` leva o link do roteador.
98
- export function Section({ surface = "background", spacing = "md", theme, variant = "base", brand, links, legal, layout = "columns", maxWidth = "xl", navLabel = "Footer", children, className, ...props }) {
98
+ // GAR-21 e GAR-22 (lote U, 19/10/2026): a abertura de página é outra VARIAÇÃO, `hero`. Nenhuma referência da fila tem a
99
+ // peça aberta; a anatomia é a do pedido (sobrelinha, título, texto, botões ou e-mail, imagem ao lado, empilhado no
100
+ // celular) e os vãos são os do início da referência, medidos em 15/10/2026. O título cresce 36, 60 e 72 com a largura
101
+ // da FAIXA (`--text-4xl`, `--text-6xl` a partir de 768, `--text-7xl` a partir de 1024), decisão do Victor de 19/10/2026.
102
+ export function Section({ surface = "background", spacing = "md", theme, variant = "base", brand, links, legal, layout = "columns", maxWidth = "xl", navLabel = "Footer", title, titleAs: Titulo = "h1", eyebrow, description, actions, media, align = "start", children, className, ...props }) {
99
103
  const pele = cx("section", surface !== "background" && `section-${surface}`, spacing !== "md" && `section-spacing-${spacing}`);
104
+ // Fora do `hero`, o `title` em texto continua sendo o atributo do HTML, como era antes de ele virar o título da abertura.
105
+ const atributo = variant !== "hero" && typeof title === "string" ? { title } : {};
106
+ if (variant === "hero")
107
+ return _jsx("section", { "data-theme": theme, className: cx(pele, "section-hero", align === "center" && "section-hero-center", align !== "center" && media != null && "section-hero-split", className), ...props, children: _jsxs("div", { className: cx("container", maxWidth !== "xl" && `container-${maxWidth}`, "section-hero-inner"), children: [_jsxs("div", { className: "section-hero-content", children: [eyebrow != null && _jsx("div", { className: "section-hero-eyebrow", children: eyebrow }), _jsxs("div", { className: "section-hero-text", children: [title != null && _jsx(Titulo, { className: "section-hero-title", children: title }), description != null && _jsx("p", { className: "section-hero-description", children: description })] }), actions != null && _jsx("div", { className: "section-hero-actions", children: actions }), children] }), media != null && _jsx("div", { className: "section-hero-media", children: media })] }) });
100
108
  if (variant !== "footer")
101
- return _jsx("section", { "data-theme": theme, className: cx(pele, className), ...props, children: children });
109
+ return _jsx("section", { "data-theme": theme, className: cx(pele, className), ...atributo, ...props, children: children });
102
110
  if (layout === "inline") {
103
111
  const itens = (links ?? []).flatMap((g) => g.items);
104
- return _jsx("footer", { "data-theme": theme, className: cx(pele, "section-footer", "section-footer-inline", className), ...props, children: _jsxs("div", { className: cx("container", maxWidth !== "xl" && `container-${maxWidth}`, "section-footer-line"), children: [legal != null && _jsx("p", { className: "section-footer-inline-legal", children: legal }), itens.length > 0 && _jsx("nav", { "aria-label": navLabel, children: _jsx("ul", { className: "section-footer-inline-links", children: itens.map(it => _jsx("li", { children: it.render
112
+ return _jsx("footer", { "data-theme": theme, className: cx(pele, "section-footer", "section-footer-inline", className), ...atributo, ...props, children: _jsxs("div", { className: cx("container", maxWidth !== "xl" && `container-${maxWidth}`, "section-footer-line"), children: [legal != null && _jsx("p", { className: "section-footer-inline-legal", children: legal }), itens.length > 0 && _jsx("nav", { "aria-label": navLabel, children: _jsx("ul", { className: "section-footer-inline-links", children: itens.map(it => _jsx("li", { children: it.render
105
113
  ? fundirRender(it.render, { className: "section-footer-link", children: it.label }, "a")
106
114
  : _jsx("a", { className: "section-footer-link", href: it.href, children: it.label }) }, it.id)) }) }), children] }) });
107
115
  }
108
- 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
116
+ return _jsx("footer", { "data-theme": theme, className: cx(pele, "section-footer", className), ...atributo, ...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
109
117
  ? fundirRender(it.render, { className: "section-footer-link", children: it.label }, "a")
110
118
  : _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 })] }) });
111
119
  }
@@ -150,6 +158,8 @@ export function Badge({ variant: variantProp = "neutral", tone, emphasis = "soft
150
158
  // botão do sino é anunciado "sino 8" e ninguém sabe o que é o 8.
151
159
  return _jsxs("span", { className: "badge-anchor", children: [children, !escondido && React.cloneElement(chip, { "aria-hidden": true })] });
152
160
  }
161
+ /** `Chip` é outro nome do `Badge` (GAR-20, 19/10/2026): o nome que a referência dá à mesma peça. Igual em tudo. */
162
+ export function Chip(props) { return _jsx(Badge, { ...props }); }
153
163
  // AN-07 (03/10/2026). Tudo novo é acréscimo: com `value` e sem `detail` nem `tone`, a marcação é a
154
164
  // de antes, mais a classe da caixa de fora. A anatomia é a da barra de progresso da referência: a
155
165
  // saída no alto à direita, o trilho embaixo, e sem `aria-valuenow` quando não há total.
package/dist/pure.d.ts CHANGED
@@ -247,6 +247,17 @@ export interface AureaStrings {
247
247
  colorNameFormat: string;
248
248
  colorHex: string;
249
249
  colorSwatches: string;
250
+ consentTitle: string;
251
+ consentReject: string;
252
+ consentAccept: string;
253
+ consentChoose: string;
254
+ consentPreferences: string;
255
+ consentSave: string;
256
+ consentRequired: string;
257
+ consentAccepted: string;
258
+ consentRejected: string;
259
+ consentSaved: string;
260
+ consentHide: string;
250
261
  universalState: Record<UniversalState, string>;
251
262
  }
252
263
  export declare const defaultStrings: AureaStrings;
package/dist/pure.js CHANGED
@@ -53,10 +53,10 @@ export const universalStates = ["waiting_user", "waiting_approval", "waiting_dep
53
53
  // perdeu qualidade é avisado. Um `role="alert"` aqui interromperia o leitor de tela por uma
54
54
  // condição que não pede ação imediata, que é o oposto do que o papel serve.
55
55
  export const stateSeverity = (state) => state.startsWith("waiting_") ? "info" : "warning";
56
- export const defaultStrings = { passwordShow: "Show password", passwordHide: "Hide password", skipToContent: "Skip to content", close: "Close", confirmCancel: "Cancel", dataError: "This could not be loaded.", dataCrashed: "Something went wrong here.", dataRetry: "Try again", dataEmpty: "Nothing here yet", confirmProceed: "Continue", paginationLabel: "Pagination", paginationPage: "Page", previous: "Previous", next: "Next", breadcrumbLabel: "Breadcrumb", tabsLabel: "Tabs", optionsLabel: "Options", tableLabel: "Table", commandLabel: "Command palette", commandPlaceholder: "Type a command…", commandHintMove: "move", commandHintSelect: "open", commandHintClose: "close", dismissNotification: "Dismiss notification", toolbarLabel: "Toolbar", loading: "Loading", otpDigit: "Digit", stepperLabel: "Steps", increment: "Increase", decrement: "Decrease", comboboxEmpty: "No results", comboboxClear: "Clear selection", comboboxOpen: "Open list", comboboxRemove: "Remove", comboboxLoading: "Loading…", fileDropPrompt: "Drag files here or click to select", fileAdded: "File added", fileRemoved: "File removed", fileRemove: "Remove", fileTooLarge: "File exceeds the size limit", fileWrongType: "File type not allowed", treeLabel: "Tree", notificationsLabel: "Notifications", notificationMarkAll: "Mark all as read", notificationEmpty: "No notifications", notificationUnread: "Unread", notificationNew: "new notifications", dataGridFilter: "Filter", dataGridEmpty: "No results", dataGridSelectAll: "Select all rows", dataGridSelectRow: "Select row", dataGridSelected: "selected", dataGridClearSelection: "Clear selection", dataGridBulkLabel: "Bulk actions", dataGridColumns: "Columns", dataGridResize: "Resize column", dataGridStale: "Showing data that may be out of date.", dataGridPartial: "Some rows could not be loaded. What you see is incomplete.", dataGridError: "The rows could not be loaded.", dataGridDetails: "Details", dataGridDetailPanel: "Row detail", dataGridExport: "Export", dataGridExportRows: "rows", dataGridExportFiltered: "filtered rows", dataGridExportSelected: "selected rows", mediaPlayer: "Media player", mediaPlay: "Play", mediaPause: "Pause", mediaMute: "Mute", mediaUnmute: "Unmute", mediaSeek: "Seek", mediaVolume: "Volume", mediaCaptionsShow: "Show captions", mediaCaptionsHide: "Hide captions", mediaSkipBack: "Skip back 10 seconds", mediaSkipForward: "Skip forward 10 seconds", mediaFullscreenEnter: "Enter full screen", mediaFullscreenExit: "Exit full screen", mediaEmbedOpen: "Open the video on its own site", carouselLabel: "Carousel", carouselSlide: "Slide", positionOf: "of", carouselPrev: "Previous slide", carouselNext: "Next slide", galleryLabel: "Gallery", galleryVideo: "Video", sortableLabel: "Sortable list", sortableHandle: "Reorder", sortableHelp: "Press Space to pick this up, then Arrow Up and Arrow Down to move it. Space drops it, Escape puts it back.", sortableGrabbed: "Picked up", sortableDropped: "Dropped", sortableMoved: "Moved", sortableCanceled: "Put back", blockEditorLabel: "Content blocks", blockLabel: "Block", blockRemove: "Remove block", uploadSending: "Uploading", uploadCancel: "Cancel upload", uploadRetry: "Retry upload", uploadError: "Upload failed", uploadCanceled: "Upload canceled", uploadComplete: "Upload complete", uploadPause: "Pause upload", uploadResume: "Resume upload", uploadPaused: "Paused", uploadPending: "Waiting", uploadChecksum: "Checksum", uploadChecksumBad: "The server received different bytes than the ones sent.", fileConflict: "A file with this name is already in the queue", fileReplace: "Replace", fileKeepBoth: "Keep both", fileSkip: "Skip", uploadReceipt: "Receipt", uploadReceiptCopy: "Copy receipt", agentInspector: "Agent inspector", invocationLabel: "Invocation", invocationInput: "Input", invocationOutput: "Output", taskQueueLabel: "Task queue", taskState: { queued: "Queued", running: "Running", completed: "Completed", failed: "Failed", blocked: "Blocked", paused: "Paused" }, taskPriority: { low: "Low", medium: "Medium", high: "High" }, approvalLabel: "Approval", approvalApprove: "Approve", approvalDeny: "Deny", approvalApproved: "Approved", approvalDenied: "Denied", approvalDeadline: "Decide by", approvalRisk: { low: "Low risk", medium: "Medium risk", high: "High risk" }, permissionLabel: "Tool permissions", permissionAsk: "Ask", permissionAlways: "Always", permissionNever: "Never", eventStreamLabel: "Events", traceLabel: "Trace", healthLabel: "Health", healthState: { operational: "Operational", degraded: "Degraded", down: "Down", maintenance: "Maintenance", unknown: "Unknown" }, modelUsageLabel: "Model usage", usageMetric: { tokens: "Tokens", cost: "Cost", requests: "Requests" }, costMeterLabel: "Cost", costMeterSpent: "Spent", costMeterRemaining: "left", costMeterExceeded: "Over the limit", costMeterNear: "Spending is past the soft limit.", costMeterOver: "The limit has been reached. Further calls are blocked.", memoryLabel: "Memory ledger", memoryProvenance: "Where this came from", memoryOperation: { added: "Added", updated: "Updated", recalled: "Recalled", forgotten: "Forgotten" }, memoryScope: { episodic: "Episodic", semantic: "Semantic", procedural: "Procedural" }, agentMessageLabel: "Agent messages", agentMessageTo: "to", agentMessageBroadcast: "all agents", agentMessageReason: "Why it went this way", agentMessageKind: { request: "Request", response: "Response", handoff: "Handoff", broadcast: "Broadcast", error: "Error" }, automationWhen: "When", automationThen: "Then", automationEnabled: "Enabled", automationLastRun: "Last run", automationResult: { success: "Succeeded", failure: "Failed" }, graphLabel: "Dependency graph", graphZoomIn: "Zoom in", graphZoomOut: "Zoom out", graphFit: "Fit to screen", graphLegend: "Legend", graphLegendKind: "Link type", graphLegendStatus: "Status", graphOverview: "Overview", graphConnections: "connections", graphShow: "Show", graphJoin: "Join", graphArrange: "Arrange the map", graphUndo: "Undo", graphRedo: "Redo", graphAlignLeft: "Align left", graphAlignCenter: "Align centers", graphAlignRight: "Align right", graphAlignTop: "Align top", graphAlignMiddle: "Align middles", graphAlignBottom: "Align bottom", graphDistributeH: "Distribute horizontally", graphDistributeV: "Distribute vertically", graphPin: "Pin in place", graphPinned: "pinned", graphRelayout: "Rearrange", graphExpand: "Open", graphCollapse: "Close", graphHidden: "hidden", graphEdge: "Connection", graphEdgeHelp: "Enter selects the connection.", graphHandle: "Connection point", graphNodeHelp: "Enter or Space selects the node. Once selected, the arrow keys move it; with Shift, further. Escape releases it.", graphMoved: "Node moved", agentState: { idle: "Idle", thinking: "Thinking", running: "Running", paused: "Paused", error: "Error", completed: "Completed" }, codeEditor: "Code editor", chatLabel: "Conversation", chatMessage: "Message", chatSend: "Send", chatAttach: "Attach file", chatAttachments: "Attachments", chatReplyTo: "Replying to", chatReplyCancel: "Cancel reply", chatEditing: "Editing message", chatEditCancel: "Cancel editing", chatSave: "Save", chatEdited: "edited", chatForwardedFrom: "Forwarded from", qrCode: "QR code", chartLabel: "Chart", copyCode: "Copy code", codeBlockPreview: "Preview", codeBlockCode: "Code", copied: "Copied", linkCopied: "Link copied", linkCopyFailed: "Could not copy. Copy the link below.", tocLabel: "On this page", navigationToggle: "Navigation", sidebarLabel: "Sidebar", sidebarCollapse: "Collapse sidebar", sidebarExpand: "Expand sidebar", bottomNavLabel: "Main", themeToDark: "Switch to dark theme", themeChoice: "Theme", themeLight: "Light", themeDark: "Dark", themeSystem: "System", themeToLight: "Switch to light theme", datePlaceholder: "Pick a date", dateRangePlaceholder: "Pick a date range", colorPicker: "Color picker", colorArea2D: "2D slider", colorChannel: { hue: "Hue", saturation: "Saturation", brightness: "Brightness", lightness: "Lightness", red: "Red", green: "Green", blue: "Blue", alpha: "Alpha" }, colorHue: { red: "red", orange: "orange", yellow: "yellow", green: "green", cyan: "cyan", blue: "blue", purple: "purple", magenta: "magenta", pink: "pink", brown: "brown", gray: "gray", white: "white", black: "black" }, colorTone: { veryDark: "very dark", dark: "dark", light: "light", veryLight: "very light", vivid: "vivid", pale: "pale", grayish: "grayish" }, colorNameFormat: "{lightness} {chroma} {hue}", colorHex: "Hex", colorSwatches: "Swatches", universalState: { waiting_user: "Waiting for someone to act.", waiting_approval: "Waiting for approval.", waiting_dependency: "Waiting for something else to finish.", offline: "No connection. This was loaded earlier.", stale: "This may be out of date.", partial: "Some of this could not be loaded.", degraded: "Working with reduced capability." } };
56
+ export const defaultStrings = { passwordShow: "Show password", passwordHide: "Hide password", skipToContent: "Skip to content", close: "Close", confirmCancel: "Cancel", dataError: "This could not be loaded.", dataCrashed: "Something went wrong here.", dataRetry: "Try again", dataEmpty: "Nothing here yet", confirmProceed: "Continue", paginationLabel: "Pagination", paginationPage: "Page", previous: "Previous", next: "Next", breadcrumbLabel: "Breadcrumb", tabsLabel: "Tabs", optionsLabel: "Options", tableLabel: "Table", commandLabel: "Command palette", commandPlaceholder: "Type a command…", commandHintMove: "move", commandHintSelect: "open", commandHintClose: "close", dismissNotification: "Dismiss notification", toolbarLabel: "Toolbar", loading: "Loading", otpDigit: "Digit", stepperLabel: "Steps", increment: "Increase", decrement: "Decrease", comboboxEmpty: "No results", comboboxClear: "Clear selection", comboboxOpen: "Open list", comboboxRemove: "Remove", comboboxLoading: "Loading…", fileDropPrompt: "Drag files here or click to select", fileAdded: "File added", fileRemoved: "File removed", fileRemove: "Remove", fileTooLarge: "File exceeds the size limit", fileWrongType: "File type not allowed", treeLabel: "Tree", notificationsLabel: "Notifications", notificationMarkAll: "Mark all as read", notificationEmpty: "No notifications", notificationUnread: "Unread", notificationNew: "new notifications", dataGridFilter: "Filter", dataGridEmpty: "No results", dataGridSelectAll: "Select all rows", dataGridSelectRow: "Select row", dataGridSelected: "selected", dataGridClearSelection: "Clear selection", dataGridBulkLabel: "Bulk actions", dataGridColumns: "Columns", dataGridResize: "Resize column", dataGridStale: "Showing data that may be out of date.", dataGridPartial: "Some rows could not be loaded. What you see is incomplete.", dataGridError: "The rows could not be loaded.", dataGridDetails: "Details", dataGridDetailPanel: "Row detail", dataGridExport: "Export", dataGridExportRows: "rows", dataGridExportFiltered: "filtered rows", dataGridExportSelected: "selected rows", mediaPlayer: "Media player", mediaPlay: "Play", mediaPause: "Pause", mediaMute: "Mute", mediaUnmute: "Unmute", mediaSeek: "Seek", mediaVolume: "Volume", mediaCaptionsShow: "Show captions", mediaCaptionsHide: "Hide captions", mediaSkipBack: "Skip back 10 seconds", mediaSkipForward: "Skip forward 10 seconds", mediaFullscreenEnter: "Enter full screen", mediaFullscreenExit: "Exit full screen", mediaEmbedOpen: "Open the video on its own site", carouselLabel: "Carousel", carouselSlide: "Slide", positionOf: "of", carouselPrev: "Previous slide", carouselNext: "Next slide", galleryLabel: "Gallery", galleryVideo: "Video", sortableLabel: "Sortable list", sortableHandle: "Reorder", sortableHelp: "Press Space to pick this up, then Arrow Up and Arrow Down to move it. Space drops it, Escape puts it back.", sortableGrabbed: "Picked up", sortableDropped: "Dropped", sortableMoved: "Moved", sortableCanceled: "Put back", blockEditorLabel: "Content blocks", blockLabel: "Block", blockRemove: "Remove block", uploadSending: "Uploading", uploadCancel: "Cancel upload", uploadRetry: "Retry upload", uploadError: "Upload failed", uploadCanceled: "Upload canceled", uploadComplete: "Upload complete", uploadPause: "Pause upload", uploadResume: "Resume upload", uploadPaused: "Paused", uploadPending: "Waiting", uploadChecksum: "Checksum", uploadChecksumBad: "The server received different bytes than the ones sent.", fileConflict: "A file with this name is already in the queue", fileReplace: "Replace", fileKeepBoth: "Keep both", fileSkip: "Skip", uploadReceipt: "Receipt", uploadReceiptCopy: "Copy receipt", agentInspector: "Agent inspector", invocationLabel: "Invocation", invocationInput: "Input", invocationOutput: "Output", taskQueueLabel: "Task queue", taskState: { queued: "Queued", running: "Running", completed: "Completed", failed: "Failed", blocked: "Blocked", paused: "Paused" }, taskPriority: { low: "Low", medium: "Medium", high: "High" }, approvalLabel: "Approval", approvalApprove: "Approve", approvalDeny: "Deny", approvalApproved: "Approved", approvalDenied: "Denied", approvalDeadline: "Decide by", approvalRisk: { low: "Low risk", medium: "Medium risk", high: "High risk" }, permissionLabel: "Tool permissions", permissionAsk: "Ask", permissionAlways: "Always", permissionNever: "Never", eventStreamLabel: "Events", traceLabel: "Trace", healthLabel: "Health", healthState: { operational: "Operational", degraded: "Degraded", down: "Down", maintenance: "Maintenance", unknown: "Unknown" }, modelUsageLabel: "Model usage", usageMetric: { tokens: "Tokens", cost: "Cost", requests: "Requests" }, costMeterLabel: "Cost", costMeterSpent: "Spent", costMeterRemaining: "left", costMeterExceeded: "Over the limit", costMeterNear: "Spending is past the soft limit.", costMeterOver: "The limit has been reached. Further calls are blocked.", memoryLabel: "Memory ledger", memoryProvenance: "Where this came from", memoryOperation: { added: "Added", updated: "Updated", recalled: "Recalled", forgotten: "Forgotten" }, memoryScope: { episodic: "Episodic", semantic: "Semantic", procedural: "Procedural" }, agentMessageLabel: "Agent messages", agentMessageTo: "to", agentMessageBroadcast: "all agents", agentMessageReason: "Why it went this way", agentMessageKind: { request: "Request", response: "Response", handoff: "Handoff", broadcast: "Broadcast", error: "Error" }, automationWhen: "When", automationThen: "Then", automationEnabled: "Enabled", automationLastRun: "Last run", automationResult: { success: "Succeeded", failure: "Failed" }, graphLabel: "Dependency graph", graphZoomIn: "Zoom in", graphZoomOut: "Zoom out", graphFit: "Fit to screen", graphLegend: "Legend", graphLegendKind: "Link type", graphLegendStatus: "Status", graphOverview: "Overview", graphConnections: "connections", graphShow: "Show", graphJoin: "Join", graphArrange: "Arrange the map", graphUndo: "Undo", graphRedo: "Redo", graphAlignLeft: "Align left", graphAlignCenter: "Align centers", graphAlignRight: "Align right", graphAlignTop: "Align top", graphAlignMiddle: "Align middles", graphAlignBottom: "Align bottom", graphDistributeH: "Distribute horizontally", graphDistributeV: "Distribute vertically", graphPin: "Pin in place", graphPinned: "pinned", graphRelayout: "Rearrange", graphExpand: "Open", graphCollapse: "Close", graphHidden: "hidden", graphEdge: "Connection", graphEdgeHelp: "Enter selects the connection.", graphHandle: "Connection point", graphNodeHelp: "Enter or Space selects the node. Once selected, the arrow keys move it; with Shift, further. Escape releases it.", graphMoved: "Node moved", agentState: { idle: "Idle", thinking: "Thinking", running: "Running", paused: "Paused", error: "Error", completed: "Completed" }, codeEditor: "Code editor", chatLabel: "Conversation", chatMessage: "Message", chatSend: "Send", chatAttach: "Attach file", chatAttachments: "Attachments", chatReplyTo: "Replying to", chatReplyCancel: "Cancel reply", chatEditing: "Editing message", chatEditCancel: "Cancel editing", chatSave: "Save", chatEdited: "edited", chatForwardedFrom: "Forwarded from", qrCode: "QR code", chartLabel: "Chart", copyCode: "Copy code", codeBlockPreview: "Preview", codeBlockCode: "Code", copied: "Copied", linkCopied: "Link copied", linkCopyFailed: "Could not copy. Copy the link below.", tocLabel: "On this page", navigationToggle: "Navigation", sidebarLabel: "Sidebar", sidebarCollapse: "Collapse sidebar", sidebarExpand: "Expand sidebar", bottomNavLabel: "Main", themeToDark: "Switch to dark theme", themeChoice: "Theme", themeLight: "Light", themeDark: "Dark", themeSystem: "System", themeToLight: "Switch to light theme", datePlaceholder: "Pick a date", dateRangePlaceholder: "Pick a date range", colorPicker: "Color picker", colorArea2D: "2D slider", colorChannel: { hue: "Hue", saturation: "Saturation", brightness: "Brightness", lightness: "Lightness", red: "Red", green: "Green", blue: "Blue", alpha: "Alpha" }, colorHue: { red: "red", orange: "orange", yellow: "yellow", green: "green", cyan: "cyan", blue: "blue", purple: "purple", magenta: "magenta", pink: "pink", brown: "brown", gray: "gray", white: "white", black: "black" }, colorTone: { veryDark: "very dark", dark: "dark", light: "light", veryLight: "very light", vivid: "vivid", pale: "pale", grayish: "grayish" }, colorNameFormat: "{lightness} {chroma} {hue}", colorHex: "Hex", colorSwatches: "Swatches", consentTitle: "Cookies on this site", consentReject: "Reject non-essential cookies", consentAccept: "Accept all cookies", consentChoose: "Choose cookies", consentPreferences: "Cookie preferences", consentSave: "Save my choices", consentRequired: "Always on", consentAccepted: "You accepted all cookies. You can change your choice at any time.", consentRejected: "You rejected the non-essential cookies. You can change your choice at any time.", consentSaved: "Your cookie choices were saved. You can change them at any time.", consentHide: "Hide this message", universalState: { waiting_user: "Waiting for someone to act.", waiting_approval: "Waiting for approval.", waiting_dependency: "Waiting for something else to finish.", offline: "No connection. This was loaded earlier.", stale: "This may be out of date.", partial: "Some of this could not be loaded.", degraded: "Working with reduced capability." } };
57
57
  // pt-BR preservado como locale (mesmos valores que já eram o default): passe
58
58
  // <AureaProvider strings={ptBR}> para restaurar português.
59
- export const ptBR = { passwordShow: "Mostrar senha", passwordHide: "Ocultar senha", skipToContent: "Pular para o conteúdo", close: "Fechar", confirmCancel: "Cancelar", dataError: "Não foi possível carregar.", dataCrashed: "Algo deu errado aqui.", dataRetry: "Tentar de novo", dataEmpty: "Ainda não há nada aqui", confirmProceed: "Continuar", paginationLabel: "Paginação", paginationPage: "Página", previous: "Anterior", next: "Próxima", breadcrumbLabel: "Breadcrumb", tabsLabel: "Abas", optionsLabel: "Opções", tableLabel: "Tabela", commandLabel: "Paleta de comandos", commandPlaceholder: "Digite um comando…", commandHintMove: "mover", commandHintSelect: "abrir", commandHintClose: "fechar", dismissNotification: "Dispensar notificação", toolbarLabel: "Barra de ferramentas", loading: "Carregando", otpDigit: "Dígito", stepperLabel: "Etapas", increment: "Aumentar", decrement: "Diminuir", comboboxEmpty: "Nenhum resultado", comboboxClear: "Limpar seleção", comboboxOpen: "Abrir lista", comboboxRemove: "Remover", comboboxLoading: "Carregando…", fileDropPrompt: "Arraste arquivos aqui ou clique para selecionar", fileAdded: "Arquivo adicionado", fileRemoved: "Arquivo removido", fileRemove: "Remover", fileTooLarge: "Arquivo maior que o limite", fileWrongType: "Tipo de arquivo não aceito", treeLabel: "Árvore", notificationsLabel: "Notificações", notificationMarkAll: "Marcar todas como lidas", notificationEmpty: "Nenhuma notificação", notificationUnread: "Não lida", notificationNew: "novas notificações", dataGridFilter: "Filtrar", dataGridEmpty: "Nenhum resultado", dataGridSelectAll: "Selecionar todas as linhas", dataGridSelectRow: "Selecionar linha", dataGridSelected: "selecionadas", dataGridClearSelection: "Limpar seleção", dataGridBulkLabel: "Ações em lote", dataGridColumns: "Colunas", dataGridResize: "Redimensionar coluna", dataGridStale: "Mostrando dados que podem estar desatualizados.", dataGridPartial: "Algumas linhas não puderam ser carregadas. O que aparece está incompleto.", dataGridError: "Não foi possível carregar as linhas.", dataGridDetails: "Detalhes", dataGridDetailPanel: "Detalhe da linha", dataGridExport: "Exportar", dataGridExportRows: "linhas", dataGridExportFiltered: "linhas filtradas", dataGridExportSelected: "linhas selecionadas", mediaPlayer: "Reprodutor de mídia", mediaPlay: "Reproduzir", mediaPause: "Pausar", mediaMute: "Silenciar", mediaUnmute: "Ativar som", mediaSeek: "Posição da reprodução", mediaVolume: "Volume", mediaCaptionsShow: "Ativar legendas", mediaCaptionsHide: "Desativar legendas", mediaSkipBack: "Voltar 10 segundos", mediaSkipForward: "Avançar 10 segundos", mediaFullscreenEnter: "Tela cheia", mediaFullscreenExit: "Sair da tela cheia", mediaEmbedOpen: "Abrir o vídeo no site de origem", carouselLabel: "Carrossel", carouselSlide: "Slide", positionOf: "de", carouselPrev: "Slide anterior", carouselNext: "Próximo slide", galleryLabel: "Galeria", galleryVideo: "Vídeo", sortableLabel: "Lista ordenável", sortableHandle: "Reordenar", sortableHelp: "Aperte Espaço para pegar, e as setas para cima e para baixo para mover. Espaço solta, Esc devolve ao lugar.", sortableGrabbed: "Pego", sortableDropped: "Solto", sortableMoved: "Movido", sortableCanceled: "Devolvido", blockEditorLabel: "Blocos de conteúdo", blockLabel: "Bloco", blockRemove: "Remover bloco", uploadSending: "Enviando", uploadCancel: "Cancelar envio", uploadRetry: "Tentar envio novamente", uploadError: "Falha no envio", uploadCanceled: "Envio cancelado", uploadComplete: "Envio concluído", uploadPause: "Pausar envio", uploadResume: "Retomar envio", uploadPaused: "Pausado", uploadPending: "Aguardando", uploadChecksum: "Soma de verificação", uploadChecksumBad: "O servidor recebeu bytes diferentes dos enviados.", fileConflict: "Já existe um arquivo com este nome na fila", fileReplace: "Substituir", fileKeepBoth: "Manter os dois", fileSkip: "Pular", uploadReceipt: "Recibo", uploadReceiptCopy: "Copiar recibo", agentInspector: "Inspetor do agente", invocationLabel: "Invocação", invocationInput: "Entrada", invocationOutput: "Saída", taskQueueLabel: "Fila de tarefas", taskState: { queued: "Na fila", running: "Executando", completed: "Concluída", failed: "Falhou", blocked: "Bloqueada", paused: "Pausada" }, taskPriority: { low: "Baixa", medium: "Média", high: "Alta" }, approvalLabel: "Aprovação", approvalApprove: "Aprovar", approvalDeny: "Negar", approvalApproved: "Aprovado", approvalDenied: "Negado", approvalDeadline: "Decidir até", approvalRisk: { low: "Risco baixo", medium: "Risco médio", high: "Risco alto" }, permissionLabel: "Permissões de ferramenta", permissionAsk: "Perguntar", permissionAlways: "Sempre", permissionNever: "Nunca", eventStreamLabel: "Eventos", traceLabel: "Rastro", healthLabel: "Saúde", healthState: { operational: "Operando", degraded: "Degradado", down: "Fora do ar", maintenance: "Em manutenção", unknown: "Desconhecido" }, modelUsageLabel: "Consumo por modelo", usageMetric: { tokens: "Tokens", cost: "Custo", requests: "Chamadas" }, costMeterLabel: "Custo", costMeterSpent: "Gasto", costMeterRemaining: "restantes", costMeterExceeded: "Acima do limite", costMeterNear: "O gasto passou do limite brando.", costMeterOver: "O limite foi atingido. As próximas chamadas estão bloqueadas.", memoryLabel: "Livro-razão de memória", memoryProvenance: "De onde isto veio", memoryOperation: { added: "Guardada", updated: "Atualizada", recalled: "Lembrada", forgotten: "Esquecida" }, memoryScope: { episodic: "Episódica", semantic: "Semântica", procedural: "Procedural" }, agentMessageLabel: "Recados entre agentes", agentMessageTo: "para", agentMessageBroadcast: "todos os agentes", agentMessageReason: "Por que foi por aqui", agentMessageKind: { request: "Pedido", response: "Resposta", handoff: "Passagem", broadcast: "Difusão", error: "Erro" }, automationWhen: "Quando", automationThen: "Então", automationEnabled: "Ativa", automationLastRun: "Última execução", automationResult: { success: "Concluiu", failure: "Falhou" }, graphLabel: "Grafo de dependências", graphZoomIn: "Aproximar", graphZoomOut: "Afastar", graphFit: "Caber na tela", graphLegend: "Legenda", graphLegendKind: "Tipo de ligação", graphLegendStatus: "Estado", graphOverview: "Visão geral", graphConnections: "conexões", graphShow: "Mostrar", graphJoin: "Juntar", graphArrange: "Arrumar o mapa", graphUndo: "Desfazer", graphRedo: "Refazer", graphAlignLeft: "Alinhar à esquerda", graphAlignCenter: "Alinhar pelo centro", graphAlignRight: "Alinhar à direita", graphAlignTop: "Alinhar em cima", graphAlignMiddle: "Alinhar pelo meio", graphAlignBottom: "Alinhar embaixo", graphDistributeH: "Distribuir na horizontal", graphDistributeV: "Distribuir na vertical", graphPin: "Fixar no lugar", graphPinned: "fixo", graphRelayout: "Reorganizar", graphExpand: "Abrir", graphCollapse: "Fechar", graphHidden: "ocultos", graphEdge: "Ligação", graphEdgeHelp: "Enter escolhe a ligação.", graphHandle: "Ponto de ligação", graphNodeHelp: "Enter ou Espaço escolhe o nó. Escolhido, as setas o movem; com Shift, mais longe. Esc solta.", graphMoved: "Nó movido", agentState: { idle: "Ocioso", thinking: "Pensando", running: "Executando", paused: "Pausado", error: "Erro", completed: "Concluído" }, codeEditor: "Editor de código", chatLabel: "Conversa", chatMessage: "Mensagem", chatSend: "Enviar", chatAttach: "Anexar arquivo", chatAttachments: "Anexos", chatReplyTo: "Respondendo a", chatReplyCancel: "Cancelar resposta", chatEditing: "Editando mensagem", chatEditCancel: "Cancelar edição", chatSave: "Salvar", chatEdited: "editada", chatForwardedFrom: "Encaminhada de", qrCode: "Código QR", chartLabel: "Gráfico", copyCode: "Copiar código", codeBlockPreview: "Prévia", codeBlockCode: "Código", copied: "Copiado", linkCopied: "Link copiado", linkCopyFailed: "Não deu para copiar. Copie o link abaixo.", tocLabel: "Nesta página", navigationToggle: "Navegação", sidebarLabel: "Lateral", sidebarCollapse: "Recolher o menu", sidebarExpand: "Abrir o menu", bottomNavLabel: "Principal", themeToDark: "Mudar para o tema escuro", themeChoice: "Tema", themeLight: "Claro", themeDark: "Escuro", themeSystem: "Sistema", themeToLight: "Mudar para o tema claro", datePlaceholder: "Escolher data", dateRangePlaceholder: "Escolher período", colorPicker: "Seletor de cor", colorArea2D: "controle 2D", colorChannel: { hue: "Matiz", saturation: "Saturação", brightness: "Brilho", lightness: "Luminosidade", red: "Vermelho", green: "Verde", blue: "Azul", alpha: "Alfa" }, colorHue: { red: "vermelho", orange: "laranja", yellow: "amarelo", green: "verde", cyan: "ciano", blue: "azul", purple: "roxo", magenta: "magenta", pink: "rosa", brown: "marrom", gray: "cinza", white: "branco", black: "preto" }, colorTone: { veryDark: "muito escuro", dark: "escuro", light: "claro", veryLight: "muito claro", vivid: "vivo", pale: "pálido", grayish: "acinzentado" }, colorNameFormat: "{hue} {chroma} {lightness}", colorHex: "Código hex", colorSwatches: "Amostras", universalState: { waiting_user: "Esperando alguém agir.", waiting_approval: "Esperando aprovação.", waiting_dependency: "Esperando outra coisa terminar.", offline: "Sem conexão. Isto foi carregado antes.", stale: "Isto pode estar desatualizado.", partial: "Parte disto não pôde ser carregada.", degraded: "Funcionando com capacidade reduzida." } };
59
+ export const ptBR = { passwordShow: "Mostrar senha", passwordHide: "Ocultar senha", skipToContent: "Pular para o conteúdo", close: "Fechar", confirmCancel: "Cancelar", dataError: "Não foi possível carregar.", dataCrashed: "Algo deu errado aqui.", dataRetry: "Tentar de novo", dataEmpty: "Ainda não há nada aqui", confirmProceed: "Continuar", paginationLabel: "Paginação", paginationPage: "Página", previous: "Anterior", next: "Próxima", breadcrumbLabel: "Breadcrumb", tabsLabel: "Abas", optionsLabel: "Opções", tableLabel: "Tabela", commandLabel: "Paleta de comandos", commandPlaceholder: "Digite um comando…", commandHintMove: "mover", commandHintSelect: "abrir", commandHintClose: "fechar", dismissNotification: "Dispensar notificação", toolbarLabel: "Barra de ferramentas", loading: "Carregando", otpDigit: "Dígito", stepperLabel: "Etapas", increment: "Aumentar", decrement: "Diminuir", comboboxEmpty: "Nenhum resultado", comboboxClear: "Limpar seleção", comboboxOpen: "Abrir lista", comboboxRemove: "Remover", comboboxLoading: "Carregando…", fileDropPrompt: "Arraste arquivos aqui ou clique para selecionar", fileAdded: "Arquivo adicionado", fileRemoved: "Arquivo removido", fileRemove: "Remover", fileTooLarge: "Arquivo maior que o limite", fileWrongType: "Tipo de arquivo não aceito", treeLabel: "Árvore", notificationsLabel: "Notificações", notificationMarkAll: "Marcar todas como lidas", notificationEmpty: "Nenhuma notificação", notificationUnread: "Não lida", notificationNew: "novas notificações", dataGridFilter: "Filtrar", dataGridEmpty: "Nenhum resultado", dataGridSelectAll: "Selecionar todas as linhas", dataGridSelectRow: "Selecionar linha", dataGridSelected: "selecionadas", dataGridClearSelection: "Limpar seleção", dataGridBulkLabel: "Ações em lote", dataGridColumns: "Colunas", dataGridResize: "Redimensionar coluna", dataGridStale: "Mostrando dados que podem estar desatualizados.", dataGridPartial: "Algumas linhas não puderam ser carregadas. O que aparece está incompleto.", dataGridError: "Não foi possível carregar as linhas.", dataGridDetails: "Detalhes", dataGridDetailPanel: "Detalhe da linha", dataGridExport: "Exportar", dataGridExportRows: "linhas", dataGridExportFiltered: "linhas filtradas", dataGridExportSelected: "linhas selecionadas", mediaPlayer: "Reprodutor de mídia", mediaPlay: "Reproduzir", mediaPause: "Pausar", mediaMute: "Silenciar", mediaUnmute: "Ativar som", mediaSeek: "Posição da reprodução", mediaVolume: "Volume", mediaCaptionsShow: "Ativar legendas", mediaCaptionsHide: "Desativar legendas", mediaSkipBack: "Voltar 10 segundos", mediaSkipForward: "Avançar 10 segundos", mediaFullscreenEnter: "Tela cheia", mediaFullscreenExit: "Sair da tela cheia", mediaEmbedOpen: "Abrir o vídeo no site de origem", carouselLabel: "Carrossel", carouselSlide: "Slide", positionOf: "de", carouselPrev: "Slide anterior", carouselNext: "Próximo slide", galleryLabel: "Galeria", galleryVideo: "Vídeo", sortableLabel: "Lista ordenável", sortableHandle: "Reordenar", sortableHelp: "Aperte Espaço para pegar, e as setas para cima e para baixo para mover. Espaço solta, Esc devolve ao lugar.", sortableGrabbed: "Pego", sortableDropped: "Solto", sortableMoved: "Movido", sortableCanceled: "Devolvido", blockEditorLabel: "Blocos de conteúdo", blockLabel: "Bloco", blockRemove: "Remover bloco", uploadSending: "Enviando", uploadCancel: "Cancelar envio", uploadRetry: "Tentar envio novamente", uploadError: "Falha no envio", uploadCanceled: "Envio cancelado", uploadComplete: "Envio concluído", uploadPause: "Pausar envio", uploadResume: "Retomar envio", uploadPaused: "Pausado", uploadPending: "Aguardando", uploadChecksum: "Soma de verificação", uploadChecksumBad: "O servidor recebeu bytes diferentes dos enviados.", fileConflict: "Já existe um arquivo com este nome na fila", fileReplace: "Substituir", fileKeepBoth: "Manter os dois", fileSkip: "Pular", uploadReceipt: "Recibo", uploadReceiptCopy: "Copiar recibo", agentInspector: "Inspetor do agente", invocationLabel: "Invocação", invocationInput: "Entrada", invocationOutput: "Saída", taskQueueLabel: "Fila de tarefas", taskState: { queued: "Na fila", running: "Executando", completed: "Concluída", failed: "Falhou", blocked: "Bloqueada", paused: "Pausada" }, taskPriority: { low: "Baixa", medium: "Média", high: "Alta" }, approvalLabel: "Aprovação", approvalApprove: "Aprovar", approvalDeny: "Negar", approvalApproved: "Aprovado", approvalDenied: "Negado", approvalDeadline: "Decidir até", approvalRisk: { low: "Risco baixo", medium: "Risco médio", high: "Risco alto" }, permissionLabel: "Permissões de ferramenta", permissionAsk: "Perguntar", permissionAlways: "Sempre", permissionNever: "Nunca", eventStreamLabel: "Eventos", traceLabel: "Rastro", healthLabel: "Saúde", healthState: { operational: "Operando", degraded: "Degradado", down: "Fora do ar", maintenance: "Em manutenção", unknown: "Desconhecido" }, modelUsageLabel: "Consumo por modelo", usageMetric: { tokens: "Tokens", cost: "Custo", requests: "Chamadas" }, costMeterLabel: "Custo", costMeterSpent: "Gasto", costMeterRemaining: "restantes", costMeterExceeded: "Acima do limite", costMeterNear: "O gasto passou do limite brando.", costMeterOver: "O limite foi atingido. As próximas chamadas estão bloqueadas.", memoryLabel: "Livro-razão de memória", memoryProvenance: "De onde isto veio", memoryOperation: { added: "Guardada", updated: "Atualizada", recalled: "Lembrada", forgotten: "Esquecida" }, memoryScope: { episodic: "Episódica", semantic: "Semântica", procedural: "Procedural" }, agentMessageLabel: "Recados entre agentes", agentMessageTo: "para", agentMessageBroadcast: "todos os agentes", agentMessageReason: "Por que foi por aqui", agentMessageKind: { request: "Pedido", response: "Resposta", handoff: "Passagem", broadcast: "Difusão", error: "Erro" }, automationWhen: "Quando", automationThen: "Então", automationEnabled: "Ativa", automationLastRun: "Última execução", automationResult: { success: "Concluiu", failure: "Falhou" }, graphLabel: "Grafo de dependências", graphZoomIn: "Aproximar", graphZoomOut: "Afastar", graphFit: "Caber na tela", graphLegend: "Legenda", graphLegendKind: "Tipo de ligação", graphLegendStatus: "Estado", graphOverview: "Visão geral", graphConnections: "conexões", graphShow: "Mostrar", graphJoin: "Juntar", graphArrange: "Arrumar o mapa", graphUndo: "Desfazer", graphRedo: "Refazer", graphAlignLeft: "Alinhar à esquerda", graphAlignCenter: "Alinhar pelo centro", graphAlignRight: "Alinhar à direita", graphAlignTop: "Alinhar em cima", graphAlignMiddle: "Alinhar pelo meio", graphAlignBottom: "Alinhar embaixo", graphDistributeH: "Distribuir na horizontal", graphDistributeV: "Distribuir na vertical", graphPin: "Fixar no lugar", graphPinned: "fixo", graphRelayout: "Reorganizar", graphExpand: "Abrir", graphCollapse: "Fechar", graphHidden: "ocultos", graphEdge: "Ligação", graphEdgeHelp: "Enter escolhe a ligação.", graphHandle: "Ponto de ligação", graphNodeHelp: "Enter ou Espaço escolhe o nó. Escolhido, as setas o movem; com Shift, mais longe. Esc solta.", graphMoved: "Nó movido", agentState: { idle: "Ocioso", thinking: "Pensando", running: "Executando", paused: "Pausado", error: "Erro", completed: "Concluído" }, codeEditor: "Editor de código", chatLabel: "Conversa", chatMessage: "Mensagem", chatSend: "Enviar", chatAttach: "Anexar arquivo", chatAttachments: "Anexos", chatReplyTo: "Respondendo a", chatReplyCancel: "Cancelar resposta", chatEditing: "Editando mensagem", chatEditCancel: "Cancelar edição", chatSave: "Salvar", chatEdited: "editada", chatForwardedFrom: "Encaminhada de", qrCode: "Código QR", chartLabel: "Gráfico", copyCode: "Copiar código", codeBlockPreview: "Prévia", codeBlockCode: "Código", copied: "Copiado", linkCopied: "Link copiado", linkCopyFailed: "Não deu para copiar. Copie o link abaixo.", tocLabel: "Nesta página", navigationToggle: "Navegação", sidebarLabel: "Lateral", sidebarCollapse: "Recolher o menu", sidebarExpand: "Abrir o menu", bottomNavLabel: "Principal", themeToDark: "Mudar para o tema escuro", themeChoice: "Tema", themeLight: "Claro", themeDark: "Escuro", themeSystem: "Sistema", themeToLight: "Mudar para o tema claro", datePlaceholder: "Escolher data", dateRangePlaceholder: "Escolher período", colorPicker: "Seletor de cor", colorArea2D: "controle 2D", colorChannel: { hue: "Matiz", saturation: "Saturação", brightness: "Brilho", lightness: "Luminosidade", red: "Vermelho", green: "Verde", blue: "Azul", alpha: "Alfa" }, colorHue: { red: "vermelho", orange: "laranja", yellow: "amarelo", green: "verde", cyan: "ciano", blue: "azul", purple: "roxo", magenta: "magenta", pink: "rosa", brown: "marrom", gray: "cinza", white: "branco", black: "preto" }, colorTone: { veryDark: "muito escuro", dark: "escuro", light: "claro", veryLight: "muito claro", vivid: "vivo", pale: "pálido", grayish: "acinzentado" }, colorNameFormat: "{hue} {chroma} {lightness}", colorHex: "Código hex", colorSwatches: "Amostras", consentTitle: "Cookies neste site", consentReject: "Rejeitar cookies não necessários", consentAccept: "Aceitar todos os cookies", consentChoose: "Selecionar cookies", consentPreferences: "Preferências de cookies", consentSave: "Salvar minhas escolhas", consentRequired: "Sempre ativos", consentAccepted: "Você aceitou todos os cookies. Pode mudar a escolha quando quiser.", consentRejected: "Você rejeitou os cookies não necessários. Pode mudar a escolha quando quiser.", consentSaved: "Suas escolhas de cookies foram salvas. Pode mudá-las quando quiser.", consentHide: "Ocultar esta mensagem", universalState: { waiting_user: "Esperando alguém agir.", waiting_approval: "Esperando aprovação.", waiting_dependency: "Esperando outra coisa terminar.", offline: "Sem conexão. Isto foi carregado antes.", stale: "Isto pode estar desatualizado.", partial: "Parte disto não pôde ser carregada.", degraded: "Funcionando com capacidade reduzida." } };
60
60
  // Sprite de ícones: CONFIGURAÇÃO DE APLICAÇÃO, então entra pelo provider, uma vez.
61
61
  // Antes o default absoluto "/aurea-icons.svg" vivia no Icon e 15 componentes declaravam
62
62
  // e repassavam `spriteUrl` à mão — 52 sítios de código. Consequência: aplicação servida
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aurea-uds/react",
3
- "version": "0.35.0",
3
+ "version": "0.37.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",
@@ -90,6 +90,10 @@
90
90
  "types": "./dist/code-editor.d.ts",
91
91
  "import": "./dist/code-editor.js"
92
92
  },
93
+ "./code-highlight": {
94
+ "types": "./dist/code-highlight.d.ts",
95
+ "import": "./dist/code-highlight.js"
96
+ },
93
97
  "./data-grid": {
94
98
  "types": "./dist/data-grid.d.ts",
95
99
  "import": "./dist/data-grid.js"
@@ -127,9 +131,14 @@
127
131
  },
128
132
  "peerDependencies": {
129
133
  "@codemirror/language": "^6.12.4",
134
+ "@codemirror/legacy-modes": "^6.5.5",
130
135
  "@codemirror/state": "^6.7.1",
131
136
  "@codemirror/view": "^6.43.6",
137
+ "@lezer/css": "^1.3.9",
132
138
  "@lezer/highlight": "^1.2.3",
139
+ "@lezer/html": "^1.3.13",
140
+ "@lezer/javascript": "^1.5.6",
141
+ "@lezer/json": "^1.0.3",
133
142
  "@tanstack/react-table": "^8.21.3",
134
143
  "@tisoap/react-flow-smart-edge": "^5.0.0",
135
144
  "@xyflow/react": "^12.11.3",
@@ -181,13 +190,33 @@
181
190
  },
182
191
  "@tisoap/react-flow-smart-edge": {
183
192
  "optional": true
193
+ },
194
+ "@lezer/javascript": {
195
+ "optional": true
196
+ },
197
+ "@lezer/css": {
198
+ "optional": true
199
+ },
200
+ "@lezer/html": {
201
+ "optional": true
202
+ },
203
+ "@lezer/json": {
204
+ "optional": true
205
+ },
206
+ "@codemirror/legacy-modes": {
207
+ "optional": true
184
208
  }
185
209
  },
186
210
  "devDependencies": {
187
- "@codemirror/language": "^6.12.4",
211
+ "@codemirror/language": "^6.13.1",
212
+ "@codemirror/legacy-modes": "^6.5.5",
188
213
  "@codemirror/state": "^6.7.1",
189
214
  "@codemirror/view": "^6.43.6",
215
+ "@lezer/css": "^1.3.9",
190
216
  "@lezer/highlight": "^1.2.3",
217
+ "@lezer/html": "^1.3.13",
218
+ "@lezer/javascript": "^1.5.6",
219
+ "@lezer/json": "^1.0.3",
191
220
  "@tanstack/react-table": "8.21.3",
192
221
  "codemirror": "^6.0.2",
193
222
  "qr": "^0.6.0",