@aurea-uds/react 0.50.0 → 0.52.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 +7 -6
- package/dist/code-highlight.js +4 -1
- package/dist/data-grid.js +23 -2
- package/dist/disclosure.d.ts +5 -1
- package/dist/disclosure.js +4 -2
- package/dist/feedback-client.js +5 -5
- package/dist/graph.js +2 -1
- package/dist/layout-client.d.ts +9 -2
- package/dist/layout-client.js +6 -5
- package/dist/markup.d.ts +5 -3
- package/dist/markup.js +10 -3
- package/dist/navigation-client.d.ts +5 -1
- package/dist/navigation-client.js +24 -4
- package/dist/pure.d.ts +1 -0
- package/dist/pure.js +4 -0
- package/dist/system.js +2 -2
- package/package.json +1 -1
package/dist/agents.js
CHANGED
|
@@ -19,6 +19,7 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
19
19
|
// verbal. Aqui as ações entram como nó, e quem monta o botão sabe o que ele faz.
|
|
20
20
|
import React from "react";
|
|
21
21
|
import { cx, useAureaStrings } from "./internal.js";
|
|
22
|
+
import { proprio } from "./pure.js";
|
|
22
23
|
import { Icon } from "./system.js";
|
|
23
24
|
import { Status, Badge, Progress, Alert } from "./feedback.js";
|
|
24
25
|
import { Avatar } from "./identity.js";
|
|
@@ -38,7 +39,7 @@ const ESTADO = {
|
|
|
38
39
|
// exatamente o que a Parte J existe para impedir, um nível acima.
|
|
39
40
|
export function AgentStatus({ state = "idle", label, className, ...props }) {
|
|
40
41
|
const s = useAureaStrings();
|
|
41
|
-
return _jsx(Status, { variant: ESTADO
|
|
42
|
+
return _jsx(Status, { variant: proprio(ESTADO, state), className: className, "data-state": state, ...props, children: label ?? proprio(s.agentState, state) });
|
|
42
43
|
}
|
|
43
44
|
// AgentCard — a identidade do agente: quem é, em que estado está, o que sabe fazer.
|
|
44
45
|
export function AgentCard({ name, description, avatarSrc, model, state, capabilities, actions, className, ...props }) {
|
|
@@ -93,7 +94,7 @@ const TAREFA = {
|
|
|
93
94
|
// aqui faria a fila responder por quatro contratos e nenhum deles direito.
|
|
94
95
|
export function TaskQueue({ tasks, label, onRetry, className, ...props }) {
|
|
95
96
|
const s = useAureaStrings();
|
|
96
|
-
return _jsx("ol", { className: cx("task-queue", className), "aria-label": label ?? s.taskQueueLabel, ...props, children: tasks.map(t => _jsxs("li", { className: "task-item", "data-state": t.state, children: [_jsxs("div", { className: "task-line", children: [_jsx("span", { className: "task-title", children: t.title }), t.priority && _jsx(Badge, { variant: t.priority === "high" ? "warning" : "neutral", children: s.taskPriority[t.priority] }), _jsx(Status, { variant: TAREFA
|
|
97
|
+
return _jsx("ol", { className: cx("task-queue", className), "aria-label": label ?? s.taskQueueLabel, ...props, children: tasks.map(t => _jsxs("li", { className: "task-item", "data-state": t.state, children: [_jsxs("div", { className: "task-line", children: [_jsx("span", { className: "task-title", children: t.title }), t.priority && _jsx(Badge, { variant: t.priority === "high" ? "warning" : "neutral", children: s.taskPriority[t.priority] }), _jsx(Status, { variant: proprio(TAREFA, t.state), children: proprio(s.taskState, t.state) }), t.state === "failed" && onRetry && _jsx(IconButton, { variant: "ghost", size: "sm", icon: "arrow-counter-clockwise", label: `${s.uploadRetry} ${t.title}`, onClick: () => onRetry(t) })] }), t.description && _jsx("p", { className: "task-desc", children: t.description }), t.state === "running" && t.progress != null && _jsx(Progress, { value: Math.round(t.progress * 100), label: t.title })] }, t.id)) });
|
|
97
98
|
}
|
|
98
99
|
// HumanApproval — o portão: o que vai acontecer, e a decisão de uma pessoa.
|
|
99
100
|
export function HumanApproval({ title, description, details, risk, reasoning, deadline, decision, onApprove, onDeny, className, ...props }) {
|
|
@@ -169,7 +170,7 @@ const SAUDE = {
|
|
|
169
170
|
// HealthMatrix — o que está de pé, numa grade.
|
|
170
171
|
export function HealthMatrix({ entries, label, className, ...props }) {
|
|
171
172
|
const s = useAureaStrings();
|
|
172
|
-
return _jsx("ul", { className: cx("health-matrix", className), "aria-label": label ?? s.healthLabel, ...props, children: entries.map(e => _jsxs("li", { className: "health-cell", "data-state": e.state, children: [_jsx("span", { className: "health-name", children: e.name }), _jsx(Status, { variant: SAUDE
|
|
173
|
+
return _jsx("ul", { className: cx("health-matrix", className), "aria-label": label ?? s.healthLabel, ...props, children: entries.map(e => _jsxs("li", { className: "health-cell", "data-state": e.state, children: [_jsx("span", { className: "health-name", children: e.name }), _jsx(Status, { variant: proprio(SAUDE, e.state), children: proprio(s.healthState, e.state) }), e.detail && _jsx("span", { className: "hint", children: e.detail })] }, e.id)) });
|
|
173
174
|
}
|
|
174
175
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
175
176
|
// H.e — custo e memória: quanto se consumiu, contra que teto, e o que ficou guardado.
|
|
@@ -259,7 +260,7 @@ const LANCAMENTO = {
|
|
|
259
260
|
// ordenar e filtrar o razão compõe as duas coisas na aplicação — o exemplo do catálogo mostra.
|
|
260
261
|
export function MemoryLedger({ records, label, className, ...props }) {
|
|
261
262
|
const s = useAureaStrings();
|
|
262
|
-
return _jsx("ol", { className: cx("memory-ledger", className), "aria-label": label ?? s.memoryLabel, ...props, children: records.map(r => _jsxs("li", { className: "memory-entry", "data-operation": r.operation, "data-scope": r.scope, children: [_jsxs("div", { className: "memory-line", children: [_jsx(Badge, { variant: LANCAMENTO
|
|
263
|
+
return _jsx("ol", { className: cx("memory-ledger", className), "aria-label": label ?? s.memoryLabel, ...props, children: records.map(r => _jsxs("li", { className: "memory-entry", "data-operation": r.operation, "data-scope": r.scope, children: [_jsxs("div", { className: "memory-line", children: [_jsx(Badge, { variant: proprio(LANCAMENTO, r.operation), children: proprio(s.memoryOperation, r.operation) }), _jsx(Badge, { children: proprio(s.memoryScope, r.scope) }), _jsx("span", { className: "memory-content", children: r.content }), r.time && _jsx("time", { className: "memory-time", children: r.time })] }), (r.source || r.details?.length) && _jsxs("details", { className: "memory-provenance", children: [_jsx("summary", { children: s.memoryProvenance }), r.source && _jsx("p", { className: "memory-source", children: r.source }), !!r.details?.length && _jsx(DataList, { items: r.details })] })] }, r.id)) });
|
|
263
264
|
}
|
|
264
265
|
const RECADO = {
|
|
265
266
|
request: "info", response: "success", handoff: "primary", broadcast: "neutral", error: "danger",
|
|
@@ -279,7 +280,7 @@ export function InterAgentMessage({ messages, label, className, ...props }) {
|
|
|
279
280
|
const s = useAureaStrings();
|
|
280
281
|
return _jsx("ol", { className: cx("agent-messages", className), "aria-label": label ?? s.agentMessageLabel, ...props, children: messages.map(m => {
|
|
281
282
|
const destino = m.to ?? s.agentMessageBroadcast;
|
|
282
|
-
return _jsxs("li", { className: "agent-message", "data-kind": m.kind ?? "handoff", children: [_jsxs("div", { className: "agent-message-line", children: [_jsxs("span", { className: "agent-message-route", role: "group", "aria-label": `${m.from} ${s.agentMessageTo} ${destino}`, children: [_jsx("strong", { children: m.from }), _jsx(Icon, { name: "arrow-right", size: "sm", className: "agent-message-arrow" }), m.to ? _jsx("strong", { children: m.to }) : _jsx("span", { className: "hint", children: destino })] }), _jsx(Badge, { variant: RECADO
|
|
283
|
+
return _jsxs("li", { className: "agent-message", "data-kind": m.kind ?? "handoff", children: [_jsxs("div", { className: "agent-message-line", children: [_jsxs("span", { className: "agent-message-route", role: "group", "aria-label": `${m.from} ${s.agentMessageTo} ${destino}`, children: [_jsx("strong", { children: m.from }), _jsx(Icon, { name: "arrow-right", size: "sm", className: "agent-message-arrow" }), m.to ? _jsx("strong", { children: m.to }) : _jsx("span", { className: "hint", children: destino })] }), _jsx(Badge, { variant: proprio(RECADO, m.kind ?? "handoff"), children: proprio(s.agentMessageKind, m.kind ?? "handoff") }), m.time && _jsx("time", { className: "agent-message-time", children: m.time })] }), _jsx("p", { className: "agent-message-body", children: m.body }), (m.reason || m.details?.length) && _jsxs("details", { className: "agent-message-why", children: [_jsx("summary", { children: s.agentMessageReason }), m.reason && _jsx("p", { className: "agent-message-reason", children: m.reason }), !!m.details?.length && _jsx(DataList, { items: m.details })] })] }, m.id);
|
|
283
284
|
}) });
|
|
284
285
|
}
|
|
285
286
|
// AutomationCard — a regra que roda sozinha: QUANDO isto, ENTÃO aquilo.
|
|
@@ -300,5 +301,5 @@ export function AutomationCard({ name, description, trigger, action, enabled, on
|
|
|
300
301
|
const s = useAureaStrings();
|
|
301
302
|
// `data-enabled` só quando LIGADA: o `false` saía como `data-enabled="false"` e escapava da regra que faz a regra
|
|
302
303
|
// 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
|
|
304
|
+
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: proprio(s.automationResult, lastResult) }), lastRun && _jsxs("span", { className: "hint", children: [s.automationLastRun, ": ", lastRun] }), actions] }), !lastRun && !lastResult && actions && _jsx("footer", { className: "automation-foot", children: actions })] });
|
|
304
305
|
}
|
package/dist/code-highlight.js
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
// (o check 19 do `validate.py` cobra que só este arquivo e o do editor importam o `@lezer/`).
|
|
15
15
|
import { highlightCode as colorirArvore, tagHighlighter, tags as t } from "@lezer/highlight";
|
|
16
16
|
import { parser as js } from "@lezer/javascript";
|
|
17
|
+
import { proprio } from "./pure.js";
|
|
17
18
|
import { parser as css } from "@lezer/css";
|
|
18
19
|
import { parser as html } from "@lezer/html";
|
|
19
20
|
import { parser as json } from "@lezer/json";
|
|
@@ -38,12 +39,14 @@ const ANALISADORES = {
|
|
|
38
39
|
css, html, json,
|
|
39
40
|
};
|
|
40
41
|
let bash;
|
|
42
|
+
// A língua vem de fora (a cerca de um texto em markdown): só vale a que é chave DA tabela — "constructor" devolvia a
|
|
43
|
+
// função do `Object.prototype` e derrubava a tela (31/10/2026, a auditoria de segurança).
|
|
41
44
|
// O bash vem do modo antigo do CodeMirror (o Lezer não tem gramática de shell); ele só é montado quando pedido.
|
|
42
45
|
function analisador(lingua) {
|
|
43
46
|
const l = lingua.toLowerCase();
|
|
44
47
|
if (l === "bash" || l === "sh" || l === "shell")
|
|
45
48
|
return bash ??= StreamLanguage.define(shell).parser;
|
|
46
|
-
return ANALISADORES
|
|
49
|
+
return proprio(ANALISADORES, l);
|
|
47
50
|
}
|
|
48
51
|
/** As línguas que `highlightCode` colore. Com outra, ele devolve `null` e o `CodeBlock` mostra o texto puro. */
|
|
49
52
|
export const highlightLanguages = ["bash", "css", "html", "javascript", "js", "json", "jsx", "sh", "shell", "ts", "tsx", "typescript"];
|
package/dist/data-grid.js
CHANGED
|
@@ -8,6 +8,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
8
8
|
import React from "react";
|
|
9
9
|
import { useReactTable, getCoreRowModel, getSortedRowModel, getFilteredRowModel, getPaginationRowModel, getFacetedRowModel, getFacetedUniqueValues, flexRender } from "@tanstack/react-table";
|
|
10
10
|
import { cx, useAureaStrings, stateSeverity } from "./internal.js";
|
|
11
|
+
import { proprio } from "./pure.js";
|
|
11
12
|
import { Icon } from "./system.js";
|
|
12
13
|
import { Button, Toolbar, ToolbarButton, ToolbarSeparator } from "./actions.js";
|
|
13
14
|
import { Input, SearchField, MultiCombobox } from "./inputs.js";
|
|
@@ -152,9 +153,29 @@ export function DataGrid({ data, columns, label, filterable, pageSize, selectabl
|
|
|
152
153
|
// A função acima precisa da tabela, e a tabela é o que esta chamada devolve: a referência fecha o
|
|
153
154
|
// círculo. Ela é lida só quando o motor filtra, que é sempre depois da primeira montagem.
|
|
154
155
|
const tabelaRef = React.useRef(null);
|
|
156
|
+
// Um nome de coluna que vem de fora (o link, `?sort=constructor`) e é nome do `Object.prototype` derrubava o motor, que
|
|
157
|
+
// procura a coluna num objeto comum (31/10/2026, a auditoria de segurança). Do estado que o motor recebe sai só o que
|
|
158
|
+
// é um desses nomes E não é coluna declarada; o nome que não existe continua com o aviso do próprio motor.
|
|
159
|
+
const idsDeclarados = React.useMemo(() => {
|
|
160
|
+
const ids = new Set();
|
|
161
|
+
const ver = (cs) => {
|
|
162
|
+
for (const c of cs) {
|
|
163
|
+
const d = c;
|
|
164
|
+
const id = d.id ?? d.accessorKey ?? (typeof d.header === "string" ? d.header : undefined);
|
|
165
|
+
if (id)
|
|
166
|
+
ids.add(id);
|
|
167
|
+
if (d.columns)
|
|
168
|
+
ver(d.columns);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
ver(colunas);
|
|
172
|
+
return ids;
|
|
173
|
+
}, [colunas]);
|
|
174
|
+
const sortingDoMotor = React.useMemo(() => sorting.filter(o => idsDeclarados.has(o.id) || !(o.id in Object.prototype)), [sorting, idsDeclarados]);
|
|
175
|
+
const filtrosDoMotor = React.useMemo(() => columnFilters.filter(f => idsDeclarados.has(f.id) || !(f.id in Object.prototype)), [columnFilters, idsDeclarados]);
|
|
155
176
|
const table = useReactTable({
|
|
156
177
|
data, columns: colunas, getRowId,
|
|
157
|
-
state: { sorting, globalFilter, rowSelection, columnFilters, columnVisibility, columnSizing, ...(paginated ? { pagination } : {}) },
|
|
178
|
+
state: { sorting: sortingDoMotor, globalFilter, rowSelection, columnFilters: filtrosDoMotor, columnVisibility, columnSizing, ...(paginated ? { pagination } : {}) },
|
|
158
179
|
onSortingChange: setSorting,
|
|
159
180
|
onGlobalFilterChange: setGlobalFilter,
|
|
160
181
|
onColumnFiltersChange: setColumnFilters,
|
|
@@ -375,7 +396,7 @@ export function DataGrid({ data, columns, label, filterable, pageSize, selectabl
|
|
|
375
396
|
// ganha de mais geral; o universal entra para os quatro estados que a grade não tinha.
|
|
376
397
|
const carregando = state === "loading";
|
|
377
398
|
const universal = state && state !== "loading" && state !== "error" ? state : null;
|
|
378
|
-
const recado = state && !carregando ? (stateMessage ?? (state === "stale" ? s.dataGridStale : state === "partial" ? s.dataGridPartial : state === "error" ? s.dataGridError : s.universalState
|
|
399
|
+
const recado = state && !carregando ? (stateMessage ?? (state === "stale" ? s.dataGridStale : state === "partial" ? s.dataGridPartial : state === "error" ? s.dataGridError : proprio(s.universalState, state))) : null;
|
|
379
400
|
// O marcador vai na GRADE, não no recado: quem está obsoleto é a tabela, e o `Alert` é só
|
|
380
401
|
// como ela conta isso. Achado pelo check 30 na primeira execução dele — eu tinha marcado o
|
|
381
402
|
// recado, e com `state="loading"` não há recado nenhum, então o estado não chegava ao DOM.
|
package/dist/disclosure.d.ts
CHANGED
|
@@ -7,9 +7,13 @@ export interface AccordionItem {
|
|
|
7
7
|
/** O item que não abre: anunciado como desligado e fora do Tab. */
|
|
8
8
|
disabled?: boolean;
|
|
9
9
|
}
|
|
10
|
-
export declare function Accordion({ items, variant, multiple, defaultValue, className }: {
|
|
10
|
+
export declare function Accordion({ items, variant, multiple, defaultValue, indicator, size, className }: {
|
|
11
11
|
items: AccordionItem[];
|
|
12
12
|
variant?: AccordionVariant;
|
|
13
|
+
/** O desenho de abrir: `"chevron"` (o padrão, a setinha) ou `"plus"` (o "+" numa bolinha, que vira "×" quando abre). */
|
|
14
|
+
indicator?: "chevron" | "plus";
|
|
15
|
+
/** A altura da linha: `"md"` (o padrão) ou `"lg"` (60, com a letra do texto). */
|
|
16
|
+
size?: "md" | "lg";
|
|
13
17
|
/** Deixa vários itens abertos ao mesmo tempo. Sem isto, abrir um fecha o outro. */
|
|
14
18
|
multiple?: boolean;
|
|
15
19
|
/** Os itens que começam abertos (o `id` de cada um). */
|
package/dist/disclosure.js
CHANGED
|
@@ -8,9 +8,11 @@ import { Collapsible as BaseCollapsible } from "@base-ui/react/collapsible";
|
|
|
8
8
|
import { cx } from "./internal.js";
|
|
9
9
|
import { soOValor } from "./pure.js";
|
|
10
10
|
import { Icon } from "./system.js";
|
|
11
|
-
|
|
11
|
+
// O SITE B (30/10/2026, protótipo): `indicator="plus"` troca a setinha pelo "+" numa bolinha, que gira e vira o "×"
|
|
12
|
+
// amarelo quando abre; `size="lg"` é a linha de 60 com a letra do texto (16), a das perguntas do desenho aprovado.
|
|
13
|
+
export function Accordion({ items, variant = "default", multiple = false, defaultValue, indicator = "chevron", size = "md", className }) {
|
|
12
14
|
const grupo = React.useId();
|
|
13
|
-
return _jsx("div", { className: cx("accordion", variant === "surface" && "accordion-surface", className), children: items.map(i => _jsxs("details", { className: "accordion-item", name: multiple ? undefined : grupo, open: defaultValue?.includes(i.id) || undefined, children: [_jsxs("summary", { "aria-disabled": i.disabled || undefined, tabIndex: i.disabled ? -1 : undefined, onClick: i.disabled ? (e) => e.preventDefault() : undefined, children: [_jsx("span", { className: "accordion-title", children: i.title }), _jsx("span", { className: "accordion-chevron", "aria-hidden": "true" })] }), _jsx("div", { className: "accordion-content", children: i.content })] }, i.id)) });
|
|
15
|
+
return _jsx("div", { className: cx("accordion", variant === "surface" && "accordion-surface", indicator === "plus" && "accordion-plus", size === "lg" && "accordion-lg", className), children: items.map(i => _jsxs("details", { className: "accordion-item", name: multiple ? undefined : grupo, open: defaultValue?.includes(i.id) || undefined, children: [_jsxs("summary", { "aria-disabled": i.disabled || undefined, tabIndex: i.disabled ? -1 : undefined, onClick: i.disabled ? (e) => e.preventDefault() : undefined, children: [_jsx("span", { className: "accordion-title", children: i.title }), _jsx("span", { className: "accordion-chevron", "aria-hidden": "true" })] }), _jsx("div", { className: "accordion-content", children: i.content })] }, i.id)) });
|
|
14
16
|
}
|
|
15
17
|
// COLLAPSIBLE — uma seção que abre e fecha, com o estado do lado de quem usa.
|
|
16
18
|
//
|
package/dist/feedback-client.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
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
|
-
import { peleDoEixo } from "./pure.js";
|
|
5
|
+
import { peleDoEixo, proprio } from "./pure.js";
|
|
6
6
|
// internal → system → actions → feedback → inputs → navigation → layout → data-display → resto.
|
|
7
7
|
import React from "react";
|
|
8
8
|
import { Popover as BasePopover } from "@base-ui/react/popover";
|
|
@@ -30,7 +30,7 @@ import { Skeleton, Badge, Switch } from "./markup.js";
|
|
|
30
30
|
// seis caem na gravidade. Quem passa os dois manda, porque só o consumidor sabe se aquele
|
|
31
31
|
// "esperando" dele é grave. E o rótulo é o do consumidor, como sempre foi: a string universal
|
|
32
32
|
// entra só quando não há filho, para o componente não passar a inventar texto.
|
|
33
|
-
export function Status({ variant, state, children, className, ...props }) { const s = useAureaStrings(); const v = variant ?? (state ? (state === "offline" ? "offline" : stateSeverity(state)) : "neutral"); return _jsxs("span", { className: cx("status", v !== "neutral" && `status-${v}`, className), "data-state": state, ...props, children: [_jsx("i", { className: "status-dot", "aria-hidden": "true" }), _jsx("span", { className: "status-label", children: children ?? (state ? s.universalState
|
|
33
|
+
export function Status({ variant, state, children, className, ...props }) { const s = useAureaStrings(); const v = variant ?? (state ? (state === "offline" ? "offline" : stateSeverity(state)) : "neutral"); return _jsxs("span", { className: cx("status", v !== "neutral" && `status-${v}`, className), "data-state": state, ...props, children: [_jsx("i", { className: "status-dot", "aria-hidden": "true" }), _jsx("span", { className: "status-label", children: children ?? (state ? proprio(s.universalState, state) : null) })] }); }
|
|
34
34
|
// O ícone é FUNÇÃO da variante, como o `role` já era. A referência congelada desenha o alerta
|
|
35
35
|
// com ele em toda variante, e um sistema que faz o consumidor lembrar qual glifo significa
|
|
36
36
|
// "perigo" acaba com quatro respostas diferentes para a mesma pergunta. `icon` sobrepõe quando o
|
|
@@ -55,14 +55,14 @@ const ICONE_DA_VARIANTE = { info: "info",
|
|
|
55
55
|
// "esperando" dele é grave.
|
|
56
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
|
|
57
57
|
// para baixo do texto, na mesma coluna (a referência repete o botão; aqui ele só muda de lugar).
|
|
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
|
|
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 ?? proprio(ICONE_DA_VARIANTE, v) ?? "info", weight: icon ? undefined : "fill" }), _jsxs("div", { children: [title && _jsx("strong", { children: title }), children ?? (state ? proprio(s.universalState, state) : null)] }), action != null && _jsx("div", { className: "alert-action", children: action }), onDismiss ? _jsx(CloseButton, { onClick: onDismiss }) : _jsx("span", {})] }); }
|
|
59
59
|
export function Banner(props) {
|
|
60
60
|
if (props.variant === "consent")
|
|
61
61
|
return _jsx(BannerConsent, { ...props });
|
|
62
62
|
const { variant, state, title, icon, onDismiss, children, className, categories: _c, value: _v, onConsent: _o, ...rest } = props;
|
|
63
63
|
const s = useAureaStrings();
|
|
64
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
|
|
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 ? proprio(s.universalState, state) : null)] }), onDismiss ? _jsx(IconButton, { variant: "ghost", size: "sm", icon: "x", label: s.close, onClick: onDismiss }) : _jsx("span", {})] });
|
|
66
66
|
}
|
|
67
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
68
|
// tem a peça aberta; as regras vêm de duas fontes primárias, lidas em 19/10/2026:
|
|
@@ -144,7 +144,7 @@ function CorpoDoDataState({ state, message, skeleton, emptyTitle, emptyIcon, act
|
|
|
144
144
|
return caixa(_jsxs(_Fragment, { children: [_jsx(Alert, { variant: stateSeverity(state), state: state, children: message }), conteudo()] }));
|
|
145
145
|
return caixa(conteudo());
|
|
146
146
|
}
|
|
147
|
-
export function EmptyState({ icon = "file", title, titleAs: TitleTag = "h3", description, action, state }) { const s = useAureaStrings(); const desc = description ?? (state ? s.universalState
|
|
147
|
+
export function EmptyState({ icon = "file", title, titleAs: TitleTag = "h3", description, action, state }) { const s = useAureaStrings(); const desc = description ?? (state ? proprio(s.universalState, state) : null); return _jsxs("div", { className: "empty-state", "data-state": state, children: [_jsx(Icon, { name: icon, size: "xl" }), _jsx(TitleTag, { className: "empty-title", children: title }), desc && _jsx("p", { className: "muted", children: desc }), action] }); }
|
|
148
148
|
function groupNotifications(items) {
|
|
149
149
|
const out = [];
|
|
150
150
|
for (const it of items) {
|
package/dist/graph.js
CHANGED
|
@@ -41,6 +41,7 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
41
41
|
import React from "react";
|
|
42
42
|
import { ReactFlow, ReactFlowProvider, Background, BaseEdge, EdgeLabelRenderer, EdgeText, Handle, MiniMap, Panel, Position, SelectionMode, ViewportPortal, applyNodeChanges, getBezierPath, getSmoothStepPath, useNodesInitialized, useOnViewportChange, useReactFlow, useStore } from "@xyflow/react";
|
|
43
43
|
import { cx, useAureaStrings } from "./internal.js";
|
|
44
|
+
import { proprio } from "./pure.js";
|
|
44
45
|
import { Icon } from "./system.js";
|
|
45
46
|
import { Badge } from "./markup.js";
|
|
46
47
|
import { Button, IconButton, Toolbar, ToolbarButton, ToolbarSeparator } from "./actions.js";
|
|
@@ -537,7 +538,7 @@ function paraDrawio(nos, linhas, forma, titulo) {
|
|
|
537
538
|
if (!ids.has(e.from) || !ids.has(e.to))
|
|
538
539
|
return;
|
|
539
540
|
const id = `e-${i}`;
|
|
540
|
-
const estilo = `endArrow=none;html=0;${forma === "step" ? "edgeStyle=orthogonalEdgeStyle;rounded=1;" : "curved=1;"}${TRACO_DRAWIO
|
|
541
|
+
const estilo = `endArrow=none;html=0;${forma === "step" ? "edgeStyle=orthogonalEdgeStyle;rounded=1;" : "curved=1;"}${proprio(TRACO_DRAWIO, e.pattern ?? "solid") ?? ""}strokeWidth=${proprio(PESO_DRAWIO, e.weight ?? "regular") ?? 1};`;
|
|
541
542
|
const dobras = rota && rota.length > 2 ? `<Array as="points">${rota.slice(1, -1).map(p => `<mxPoint x="${Math.round(p.x)}" y="${Math.round(p.y)}"/>`).join("")}</Array>` : "";
|
|
542
543
|
celulas.push(`<mxCell id="${id}" value="${XML(e.label ?? "")}" style="${estilo}" edge="1" parent="1" source="${XML(`n-${e.from}`)}" target="${XML(`n-${e.to}`)}"><mxGeometry relative="1" as="geometry">${dobras}</mxGeometry></mxCell>`);
|
|
543
544
|
// O nome da porta na ponta: o rótulo-filho da linha, a 80% do caminho para cada lado (o idioma do draw.io).
|
package/dist/layout-client.d.ts
CHANGED
|
@@ -3,14 +3,14 @@ import { type Orientation, type Responsive } from "./pure.js";
|
|
|
3
3
|
import { type IconButtonProps } from "./actions.js";
|
|
4
4
|
import { type HeaderVariant, type HeaderTab, type SidebarVariant, type SidebarScrollbar, type SidebarEntry, type SidebarCollapsible, type SidebarIndicator } from "./navigation.js";
|
|
5
5
|
declare function AppShellSidebarToggle(props: Omit<IconButtonProps, "icon" | "label" | "onClick" | "variant">): React.JSX.Element;
|
|
6
|
-
export declare function AppShell({ brand, navigation, navItems, currentNavId, navLabel, topbar, topbarVariant, topbarDivider, topbarTabs, topbarCurrentTab, topbarTabsLabel, topbarTabsEnd, layout, sidebarVariant, sidebarScrollbar, sidebarFooter, sidebarCollapsed, sidebarCollapsible, sidebarToggle, sidebarShortcut, sidebarIndicator, sidebarPanel, sidebarContrast, defaultSidebarCollapsed, onSidebarCollapsedChange, contentVariant, aside, asideLabel, asideVariant, children, className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement> & {
|
|
6
|
+
export declare function AppShell({ brand, navigation, navItems, currentNavId, navLabel, topbar, topbarVariant, topbarDivider, topbarTabs, topbarCurrentTab, topbarTabsLabel, topbarTabsEnd, topbarActions, topbarBlurred, layout, sidebarVariant, sidebarScrollbar, sidebarFooter, sidebarCollapsed, sidebarCollapsible, sidebarToggle, sidebarShortcut, sidebarIndicator, sidebarPanel, sidebarContrast, defaultSidebarCollapsed, onSidebarCollapsedChange, contentVariant, aside, asideLabel, asideVariant, children, className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement> & {
|
|
7
7
|
brand: ReactNode;
|
|
8
8
|
navigation?: ReactNode;
|
|
9
9
|
navItems?: SidebarEntry[];
|
|
10
10
|
currentNavId?: string;
|
|
11
11
|
navLabel?: string;
|
|
12
12
|
topbar?: ReactNode;
|
|
13
|
-
topbarVariant?:
|
|
13
|
+
topbarVariant?: HeaderVariant;
|
|
14
14
|
topbarDivider?: boolean;
|
|
15
15
|
sidebarVariant?: SidebarVariant;
|
|
16
16
|
/** O arranjo (lote T, 17/10/2026): `"app"` (o padrão, o de sempre) ou `"docs"`, o da documentação da referência — um
|
|
@@ -30,6 +30,13 @@ export declare function AppShell({ brand, navigation, navItems, currentNavId, na
|
|
|
30
30
|
topbarTabsLabel?: string;
|
|
31
31
|
/** A ponta da linha das áreas (o `tabsEnd` do `Header`): a chave Web | Native da documentação. */
|
|
32
32
|
topbarTabsEnd?: ReactNode;
|
|
33
|
+
/** A PONTA DA BARRA DE CIMA (MNT-37): o que fica na outra ponta, longe da marca e do `topbar` — a chave de tema, a
|
|
34
|
+
* conta, o sino. É o `actions` do `Header`. No `layout="sidebar"` a barra do conteúdo passa a existir também quando o app
|
|
35
|
+
* passa só isto; no `"docs"`, o botão da gaveta continua o último, depois delas. */
|
|
36
|
+
topbarActions?: ReactNode;
|
|
37
|
+
/** O site B (30/10/2026): o fundo da barra de cima que EMBAÇA o que passa por baixo — o `blurred` do `Header`, na
|
|
38
|
+
* `flush` e na `pill`. */
|
|
39
|
+
topbarBlurred?: boolean;
|
|
33
40
|
/** 0.32.0: a barra de rolagem da lateral da esquerda — o `scrollbar` da `Sidebar`. Padrão `hover` (clara, só com o
|
|
34
41
|
* ponteiro em cima); `visible` é a barra sempre à vista. */
|
|
35
42
|
sidebarScrollbar?: SidebarScrollbar;
|
package/dist/layout-client.js
CHANGED
|
@@ -59,7 +59,8 @@ function focoDaGaveta(e) {
|
|
|
59
59
|
// API pública intacta: as props seguem brand/navigation/topbar. O que mudou é ONDE a
|
|
60
60
|
// marca sai — no topo, não na lateral. `topbarVariant` escolhe a pele do topo; o shell
|
|
61
61
|
// precisa saber porque a lateral se encaixa abaixo dele (o `flush` não tem folga em
|
|
62
|
-
// cima, então ela sobe um --space-4).
|
|
62
|
+
// cima, então ela sobe um --space-4). ~~`pill` é cabeçalho de site — não é pra shell.~~ Desde o site B (30/10/2026), a
|
|
63
|
+
// `pill` entra no shell: a cápsula da largura do bloco, que flutua a --space-4 do alto (o `maxWidth` do `Header`).
|
|
63
64
|
// A lateral RECOLHE em tela estreita: o <aside> é um popover nativo e o botão é o invoker. O
|
|
64
65
|
// navegador entrega Escape, clique fora e o `aria-expanded` no disparador. Era o achado A8: em
|
|
65
66
|
// 375px o `h1` da página começava 4,6 telas abaixo, depois dos 65 itens da navegação.
|
|
@@ -166,7 +167,7 @@ function ProvedorDaLateral({ ligado, children, ...p }) {
|
|
|
166
167
|
return ligado ? _jsx(Sidebar.Provider, { id: SHELL_NAV_ID, ...p, children: children }) : _jsx(_Fragment, { children: children });
|
|
167
168
|
}
|
|
168
169
|
function AppShellSidebarToggle(props) { return _jsx(Sidebar.Toggle, { ...props }); }
|
|
169
|
-
export function AppShell({ brand, navigation, navItems, currentNavId, navLabel, topbar, topbarVariant = "floating", topbarDivider, topbarTabs, topbarCurrentTab, topbarTabsLabel, topbarTabsEnd, layout = "app", sidebarVariant, sidebarScrollbar, sidebarFooter, sidebarCollapsed, sidebarCollapsible, sidebarToggle = "edge", sidebarShortcut = true, sidebarIndicator, sidebarPanel, sidebarContrast, defaultSidebarCollapsed, onSidebarCollapsedChange, contentVariant = "surface", aside, asideLabel, asideVariant, children, className, ...props }) {
|
|
170
|
+
export function AppShell({ brand, navigation, navItems, currentNavId, navLabel, topbar, topbarVariant = "floating", topbarDivider, topbarTabs, topbarCurrentTab, topbarTabsLabel, topbarTabsEnd, topbarActions, topbarBlurred, layout = "app", sidebarVariant, sidebarScrollbar, sidebarFooter, sidebarCollapsed, sidebarCollapsible, sidebarToggle = "edge", sidebarShortcut = true, sidebarIndicator, sidebarPanel, sidebarContrast, defaultSidebarCollapsed, onSidebarCollapsedChange, contentVariant = "surface", aside, asideLabel, asideVariant, children, className, ...props }) {
|
|
170
171
|
const s = useAureaStrings();
|
|
171
172
|
const docs = layout === "docs", lateral = layout === "sidebar";
|
|
172
173
|
useGavetaFechaNoDesktop(docs);
|
|
@@ -223,9 +224,9 @@ export function AppShell({ brand, navigation, navItems, currentNavId, navLabel,
|
|
|
223
224
|
// 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
|
|
224
225
|
// vizinhos e fora da linha deles (medido a 375, sem toque; com toque, todos sobem para 44).
|
|
225
226
|
const botaoDaGaveta = _jsx(IconButton, { className: "nav-toggle", icon: "list", label: s.navigationToggle, popoverTarget: SHELL_NAV_ID, ...(docs ? { size: "sm" } : {}) });
|
|
226
|
-
return _jsx("div", { className: cx("app-shell", layout === "docs" && "app-shell-docs", lateral && "app-shell-lateral", !lateral && topbarVariant === "flush" && "app-shell-flush", recolhe && "app-shell-collapsible", aside != null && "app-shell-with-aside", className), ...props, children: _jsxs(ProvedorDaLateral, { ligado: recolhe, collapsed: efetiva, onCollapsedChange: definir, collapsible: forma, shortcut: sidebarShortcut, children: [_jsx("a", { className: "skip-link", href: `#${SHELL_MAIN_ID}`, children: s.skipToContent }), !lateral && _jsxs(Header, { variant: topbarVariant, divider: topbarDivider, tabs: topbarTabs, currentTab: topbarCurrentTab, tabsLabel: topbarTabsLabel, tabsEnd: topbarTabsEnd, ...(docs ? { maxWidth: "docs", size: "sm" } : {}), brand: docs ? brand : _jsxs(_Fragment, { children: [botaoDaGaveta, brand] }), children: [topbar, docs && botaoDaGaveta] }), recolhe && !lateral && sidebarToggle !== "none" && _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, collapsible: forma, indicator: sidebarIndicator, panel: sidebarPanel, contrast: sidebarContrast, items: navItems, current: currentNavId, label: navLabel, onToggle: focoDaGaveta, header: lateral ? brand : undefined, footer: sidebarFooter, 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" })] }) }), lateral
|
|
227
|
-
? _jsxs("div", { className: "app-shell-column", children: [topbar != null
|
|
228
|
-
? _jsx(Header, { variant: "flush", size: "sm", divider: topbarDivider, brand: _jsxs(_Fragment, { children: [botaoDaGaveta, sidebarToggle !== "none" && _jsx(AppShellSidebarToggle, {})] }), children: topbar })
|
|
227
|
+
return _jsx("div", { className: cx("app-shell", layout === "docs" && "app-shell-docs", lateral && "app-shell-lateral", !lateral && topbarVariant === "flush" && "app-shell-flush", !lateral && topbarVariant === "pill" && "app-shell-pill", recolhe && "app-shell-collapsible", aside != null && "app-shell-with-aside", className), ...props, children: _jsxs(ProvedorDaLateral, { ligado: recolhe, collapsed: efetiva, onCollapsedChange: definir, collapsible: forma, shortcut: sidebarShortcut, children: [_jsx("a", { className: "skip-link", href: `#${SHELL_MAIN_ID}`, children: s.skipToContent }), !lateral && _jsxs(Header, { variant: topbarVariant, divider: topbarDivider, tabs: topbarTabs, currentTab: topbarCurrentTab, tabsLabel: topbarTabsLabel, tabsEnd: topbarTabsEnd, ...(docs ? { maxWidth: "docs", ...(topbarVariant === "pill" ? {} : { size: "sm" }) } : topbarVariant === "pill" ? { maxWidth: "full" } : {}), blurred: topbarBlurred, brand: docs ? brand : _jsxs(_Fragment, { children: [botaoDaGaveta, brand] }), actions: topbarActions != null ? _jsxs(_Fragment, { children: [topbarActions, docs && botaoDaGaveta] }) : undefined, children: [topbar, docs && topbarActions == null && botaoDaGaveta] }), recolhe && !lateral && sidebarToggle !== "none" && _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, collapsible: forma, indicator: sidebarIndicator, panel: sidebarPanel, contrast: sidebarContrast, items: navItems, current: currentNavId, label: navLabel, onToggle: focoDaGaveta, header: lateral ? brand : undefined, footer: sidebarFooter, 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" })] }) }), lateral
|
|
228
|
+
? _jsxs("div", { className: "app-shell-column", children: [topbar != null || topbarActions != null
|
|
229
|
+
? _jsx(Header, { variant: "flush", size: "sm", divider: topbarDivider, brand: _jsxs(_Fragment, { children: [botaoDaGaveta, sidebarToggle !== "none" && _jsx(AppShellSidebarToggle, {})] }), actions: topbarActions, children: topbar })
|
|
229
230
|
: _jsxs("div", { className: "app-shell-narrow-bar", children: [botaoDaGaveta, brand] }), _jsx("main", { id: SHELL_MAIN_ID, tabIndex: -1, className: cx("content", contentVariant === "plain" && "content-plain"), children: children })] })
|
|
230
231
|
: _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 })] }) });
|
|
231
232
|
}
|
package/dist/markup.d.ts
CHANGED
|
@@ -346,7 +346,8 @@ export interface HeaderProps extends HTMLAttributes<HTMLElement>, RefAttributes<
|
|
|
346
346
|
current?: string;
|
|
347
347
|
/** O que fica do lado direito: busca, botão de ação, conta. Fica na barra também no celular. */
|
|
348
348
|
actions?: ReactNode;
|
|
349
|
-
/** Até onde o miolo da barra cresce, pela escala do `Container` (`sm` 640 … `2xl` 1536, `full`).
|
|
349
|
+
/** Até onde o miolo da barra cresce, pela escala do `Container` (`sm` 640 … `2xl` 1536, `full`). Na `pill` (o site B,
|
|
350
|
+
* 30/10/2026), a cápsula passa a ser o miolo, da largura do `Container`, e não do conteúdo. */
|
|
350
351
|
maxWidth?: ContainerSize;
|
|
351
352
|
/**
|
|
352
353
|
* Onde ficam os links (14/10/2026): `"end"` (o padrão) logo antes das ações, na outra ponta da marca; `"start"`
|
|
@@ -360,8 +361,9 @@ export interface HeaderProps extends HTMLAttributes<HTMLElement>, RefAttributes<
|
|
|
360
361
|
*/
|
|
361
362
|
size?: "md" | "sm";
|
|
362
363
|
/**
|
|
363
|
-
*
|
|
364
|
-
* da referência. Quem pede menos transparência no sistema, ou o navegador sem desfoque,
|
|
364
|
+
* Na `flush` (15/10/2026) e na `pill` (o site B, 30/10/2026): o fundo transparente que EMBAÇA o que passa por baixo,
|
|
365
|
+
* como o topo da página inicial da referência. Quem pede menos transparência no sistema, ou o navegador sem desfoque,
|
|
366
|
+
* recebe o fundo cheio.
|
|
365
367
|
*/
|
|
366
368
|
blurred?: boolean;
|
|
367
369
|
/** O que entra no MENU DO CELULAR, embaixo dos links (15/10/2026): o GitHub, a conta. Na barra larga não aparece. */
|
package/dist/markup.js
CHANGED
|
@@ -217,7 +217,7 @@ export function Header({ variant = "floating", divider, brand, items, current, a
|
|
|
217
217
|
// Sem o encaixe, a marcação de sempre; com ele, a linha das áreas e a ponta numa mesma faixa.
|
|
218
218
|
return tabsEnd == null ? abas : _jsxs("div", { className: "topbar-tabs-row", children: [abas, _jsx("div", { className: "topbar-tabs-end", children: tabsEnd })] });
|
|
219
219
|
})()] });
|
|
220
|
-
return _jsx("header", { className: cx("topbar", `topbar-${variant}`, divider && variant === "flush" && "topbar-divider", site && "topbar-site", site && itemsJustify === "start" && "topbar-items-start", size === "sm" && "topbar-sm", blurred && variant === "flush" && "topbar-blurred", maxWidth && "topbar-contained", comAbas && "topbar-with-tabs", className), ...props, children: maxWidth ? _jsx("div", { className: cx("container", maxWidth !== "xl" && `container-${maxWidth}`, "topbar-inner"), children: miolo }) : miolo });
|
|
220
|
+
return _jsx("header", { className: cx("topbar", `topbar-${variant}`, divider && variant === "flush" && "topbar-divider", site && "topbar-site", site && itemsJustify === "start" && "topbar-items-start", size === "sm" && "topbar-sm", blurred && (variant === "flush" || variant === "pill") && "topbar-blurred", maxWidth && "topbar-contained", comAbas && "topbar-with-tabs", className), ...props, children: maxWidth ? _jsx("div", { className: cx("container", maxWidth !== "xl" && `container-${maxWidth}`, "topbar-inner"), children: miolo }) : miolo });
|
|
221
221
|
}
|
|
222
222
|
/** @deprecated `Topbar` é o nome antigo do `Header` (07/10/2026). Continua funcionando, igual; use `Header`. */
|
|
223
223
|
export function Topbar(props) { return _jsx(Header, { ...props }); }
|
|
@@ -291,6 +291,13 @@ export function Link({ external, disabled, href, target, rel, className, childre
|
|
|
291
291
|
// Transparente quando o texto diz alfa abaixo de 1 (hex de 4 ou 8 dígitos, `rgba()`, `hsla()`…). Cor de token ou
|
|
292
292
|
// `oklch()` a marcação não lê: fica sem xadrez.
|
|
293
293
|
const transparente = (cor) => { const c = parseColor(cor); return c !== null && c.a < 1; };
|
|
294
|
+
// A cor só entra no estilo quando É uma cor (31/10/2026, a auditoria de segurança): o texto ia cru para a variável, e
|
|
295
|
+
// no HTML do servidor um ";" abria regras novas (cobrir a tela, buscar imagem de outro endereço). Aceita o que a ficha
|
|
296
|
+
// promete — hex, nome, as funções de cor do CSS e `var(--token)` — e nada com ";", chaves, barra invertida, aspas,
|
|
297
|
+
// comentário ou outra função (`url(`). Recusada, a variável não se escreve: a amostra fica sem cor, e o nome continua.
|
|
298
|
+
// (O `parseColor` não serve de filtro: ele não lê `oklch()` nem `var()`, que a ficha promete.)
|
|
299
|
+
const COR_DE_CSS = /^(?:#[0-9a-f]{3,8}|[a-z]+|(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch|color)\([^;{}\\"'()]*\)|var\(--[\w-]+\))$/i;
|
|
300
|
+
const corDeCss = (cor) => { const c = cor.trim(); return COR_DE_CSS.test(c) && !c.includes("/*") ? c : undefined; };
|
|
294
301
|
export function ColorSwatch(props) {
|
|
295
302
|
if ("options" in props) {
|
|
296
303
|
const { options, name, label, value, defaultValue, onChange, layout = "grid", indicator, showLabels, size = "md", disabled, id, className } = props;
|
|
@@ -302,14 +309,14 @@ export function ColorSwatch(props) {
|
|
|
302
309
|
return _jsx("div", { role: "radiogroup", "aria-label": label, id: id, "aria-disabled": disabled || undefined, className: cx("color-swatch-picker", size !== "md" && `color-swatch-picker-${size}`, layout === "stack" && "color-swatch-picker-stack", showLabels && "color-swatch-picker-labels", className), children: options.map((o) => {
|
|
303
310
|
const op = typeof o === "string" ? { color: o } : o;
|
|
304
311
|
const cor = parseColor(op.color), rgb = cor && hsbToRgb(cor);
|
|
305
|
-
const circulo = (Tag, key) => _jsxs(Tag, { className: cx("color-swatch-option", rgb && contrastingInk(rgb) === "dark" && "color-swatch-option-dark"), style: { ["--color-swatch-current"]: op.color }, children: [_jsx("input", { type: "radio", className: "color-swatch-input", name: name, value: op.color, "aria-label": op.label ?? op.color, checked: value === undefined ? undefined : value === op.color, defaultChecked: value === undefined ? defaultValue === op.color : undefined, disabled: disabled || op.disabled, ...(onChange ? { onChange } : {}) }), _jsx("span", { className: cx("color-swatch", cor && cor.a < 1 && "color-swatch-alpha"), "aria-hidden": "true" }), indicator != null && _jsx("span", { className: "color-swatch-indicator", "aria-hidden": "true", children: indicator })] }, key);
|
|
312
|
+
const circulo = (Tag, key) => _jsxs(Tag, { className: cx("color-swatch-option", rgb && contrastingInk(rgb) === "dark" && "color-swatch-option-dark"), style: { ["--color-swatch-current"]: corDeCss(op.color) }, children: [_jsx("input", { type: "radio", className: "color-swatch-input", name: name, value: op.color, "aria-label": op.label ?? op.color, checked: value === undefined ? undefined : value === op.color, defaultChecked: value === undefined ? defaultValue === op.color : undefined, disabled: disabled || op.disabled, ...(onChange ? { onChange } : {}) }), _jsx("span", { className: cx("color-swatch", cor && cor.a < 1 && "color-swatch-alpha"), "aria-hidden": "true" }), indicator != null && _jsx("span", { className: "color-swatch-indicator", "aria-hidden": "true", children: indicator })] }, key);
|
|
306
313
|
return showLabels
|
|
307
314
|
? _jsxs("label", { className: "color-swatch-item", children: [circulo("span"), _jsx("span", { className: "color-swatch-name", "aria-hidden": "true", children: op.label ?? op.color })] }, op.color)
|
|
308
315
|
: circulo("label", op.color);
|
|
309
316
|
}) });
|
|
310
317
|
}
|
|
311
318
|
const { color, size = "md", label, className, style, ...resto } = props;
|
|
312
|
-
return _jsx("span", { role: "img", "aria-label": label ?? color, className: cx("color-swatch", size !== "md" && `color-swatch-${size}`, transparente(color) && "color-swatch-alpha", className), style: { ...style, ["--color-swatch-current"]: color }, ...resto });
|
|
319
|
+
return _jsx("span", { role: "img", "aria-label": label ?? color, className: cx("color-swatch", size !== "md" && `color-swatch-${size}`, transparente(color) && "color-swatch-alpha", className), style: { ...style, ["--color-swatch-current"]: corDeCss(color) }, ...resto });
|
|
313
320
|
}
|
|
314
321
|
export function ProgressCircle({ value, min = 0, max = 100, size = "md", tone = "brand", label, className, ...props }) {
|
|
315
322
|
const semTotal = value == null || Number.isNaN(value);
|
|
@@ -64,10 +64,14 @@ export interface TocItem {
|
|
|
64
64
|
label: string;
|
|
65
65
|
sub?: boolean;
|
|
66
66
|
}
|
|
67
|
-
export declare function TableOfContents({ items, current, label, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement> & {
|
|
67
|
+
export declare function TableOfContents({ items, current, label, progress, indicator, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement> & {
|
|
68
68
|
items: TocItem[];
|
|
69
69
|
current?: string;
|
|
70
70
|
label?: string;
|
|
71
|
+
/** O anel de leitura no lugar do ícone do nome: quanto da página já rolou, em anel e em número. */
|
|
72
|
+
progress?: boolean;
|
|
73
|
+
/** O desenho do item atual: `"line"` (o padrão, o traço do lado) ou `"segment"` (a cápsula levantada, como a da `Sidebar`). */
|
|
74
|
+
indicator?: "line" | "segment";
|
|
71
75
|
}): React.JSX.Element;
|
|
72
76
|
export interface TreeNode {
|
|
73
77
|
id: string;
|
|
@@ -11,7 +11,7 @@ import { Dialog as BaseDialog } from "@base-ui/react/dialog";
|
|
|
11
11
|
import { Popover as BasePopover } from "@base-ui/react/popover";
|
|
12
12
|
import { useValorResponsivo } from "./responsivo-runtime.js";
|
|
13
13
|
import { cx, fundirRender, useAureaStrings, usePortalContainer } from "./internal.js";
|
|
14
|
-
import { Kbd } from "./markup.js";
|
|
14
|
+
import { Kbd, ProgressCircle } from "./markup.js";
|
|
15
15
|
import { Icon } from "./system.js";
|
|
16
16
|
import { Button, IconButton } from "./actions.js";
|
|
17
17
|
import { Badge, Spinner } from "./feedback.js";
|
|
@@ -62,11 +62,29 @@ export function Pagination({ page, total, onPageChange, variant = "numbers", sum
|
|
|
62
62
|
? _jsx("li", { children: _jsx("span", { className: "pagination-ellipsis", "aria-hidden": "true", children: "\u2026" }) }, `e${i}`)
|
|
63
63
|
: _jsx("li", { children: item(p, p, { atual: p === page, rotulo: `${s.paginationPage} ${p}` }) }, p)), _jsx("li", { children: proxima })] })] });
|
|
64
64
|
}
|
|
65
|
-
|
|
65
|
+
//
|
|
66
|
+
// O SITE B (30/10/2026, protótipo): `progress` troca o ícone do nome pelo ANEL DE LEITURA — quanto da página já rolou, no
|
|
67
|
+
// anel (o `ProgressCircle`) e em número, na ponta da linha. É enfeite de leitura: o anel e o número ficam fora do leitor
|
|
68
|
+
// de tela (o que importa a ele é a seção atual, que o `aria-current` já diz).
|
|
69
|
+
export function TableOfContents({ items, current, label, progress, indicator = "line", className, ...props }) {
|
|
66
70
|
const s = useAureaStrings();
|
|
67
71
|
const meu = React.useRef(null);
|
|
68
72
|
const observado = useSecaoEmVista(items, current === undefined, meu);
|
|
69
73
|
const atual = current ?? observado;
|
|
74
|
+
const [lido, setLido] = React.useState(0);
|
|
75
|
+
const Rotulo = progress ? "div" : "p";
|
|
76
|
+
React.useEffect(() => {
|
|
77
|
+
if (!progress || typeof window === "undefined")
|
|
78
|
+
return;
|
|
79
|
+
const ler = () => {
|
|
80
|
+
const alto = document.documentElement.scrollHeight - window.innerHeight;
|
|
81
|
+
setLido(alto > 0 ? Math.round(Math.min(1, Math.max(0, window.scrollY / alto)) * 100) : 100);
|
|
82
|
+
};
|
|
83
|
+
ler();
|
|
84
|
+
window.addEventListener("scroll", ler, { passive: true });
|
|
85
|
+
window.addEventListener("resize", ler);
|
|
86
|
+
return () => { window.removeEventListener("scroll", ler); window.removeEventListener("resize", ler); };
|
|
87
|
+
}, [progress]);
|
|
70
88
|
// O `ref` do consumidor continua chegando: em React 19 ele é prop comum, então espalhá-lo por
|
|
71
89
|
// `...props` depois do nosso o sobrescreveria em silêncio. Os dois são atendidos aqui.
|
|
72
90
|
const refDele = props.ref;
|
|
@@ -74,7 +92,9 @@ export function TableOfContents({ items, current, label, className, ...props })
|
|
|
74
92
|
return _jsxs("nav", { ref: n => { meu.current = n; if (typeof refDele === "function")
|
|
75
93
|
refDele(n);
|
|
76
94
|
else if (refDele)
|
|
77
|
-
refDele.current = n; }, className: cx("toc",
|
|
95
|
+
refDele.current = n; }, className: cx("toc", indicator === "segment" && "toc-segment", className), "aria-label": label ?? s.tocLabel, ...resto, children: [_jsxs(Rotulo, { className: cx("toc-label", progress && "toc-label-progress"), children: [progress
|
|
96
|
+
? _jsx("span", { className: "toc-progress", "aria-hidden": "true", children: _jsx(ProgressCircle, { value: lido, size: "lg", label: label ?? s.tocLabel }) })
|
|
97
|
+
: _jsx("span", { className: "toc-label-icon", "aria-hidden": "true" }), label ?? s.tocLabel, progress && _jsxs("span", { className: "toc-progress-value", "aria-hidden": "true", children: [lido, "%"] })] }), items.map(i => _jsx("a", { href: `#${i.id}`, className: cx(i.sub && "toc-sub"), ...(i.id === atual ? { "aria-current": "true" } : {}), children: i.label }, i.id))] });
|
|
78
98
|
}
|
|
79
99
|
/** Qual dos `items` está na faixa de leitura, observando o documento. Devolve `undefined` até o
|
|
80
100
|
* primeiro cálculo — e em SSR, onde não há documento para observar.
|
|
@@ -270,7 +290,7 @@ function SidebarGroup({ item, filhos, lid, ctx }) {
|
|
|
270
290
|
? _jsxs("button", { id: lid, type: "button", className: "sidebar-group-label sidebar-group-toggle", "aria-expanded": aberto, "aria-controls": lid + "-lista", onClick: () => setAberto(v => !v), children: [_jsx("span", { children: item.label }), _jsx(Icon, { name: aberto ? "caret-down" : direita ? "caret-left" : "caret-right", size: "sm", className: "sidebar-group-caret" })] })
|
|
271
291
|
: _jsx("p", { id: lid, className: cx("sidebar-group-label", ctx.collapsed && "sr-only"), children: item.label });
|
|
272
292
|
const lista = sidebarList(filhos, ctx, false, lid);
|
|
273
|
-
return _jsxs("li", { children: [acao || dobra ? _jsxs("div", { className: "sidebar-group-head", children: [nome, acao && _jsx("span", { className: "sidebar-group-action", children: item.action })] }) : nome, dobra ? _jsx("div", { id: lid + "-lista", hidden: !aberto, children: lista }) : lista] });
|
|
293
|
+
return _jsxs("li", { children: [acao || dobra ? _jsxs("div", { className: "sidebar-group-head", children: [nome, acao && _jsx("span", { className: "sidebar-group-action", children: item.action })] }) : nome, dobra ? _jsx("div", { id: lid + "-lista", className: "sidebar-group-list", hidden: !aberto, children: lista }) : lista] });
|
|
274
294
|
}
|
|
275
295
|
// A GAVETA FECHA AO ESCOLHER (A-06, 23/09/2026). Abaixo de lg a lateral do `AppShell` é popover,
|
|
276
296
|
// e a biblioteca a abria e NUNCA a fechava por código: `hidePopover` tinha zero ocorrências. O
|
package/dist/pure.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ReactElement } from "react";
|
|
2
2
|
export declare const cx: (...v: Array<string | false | null | undefined>) => string;
|
|
3
|
+
export declare const proprio: <V>(tabela: Readonly<Partial<Record<string, V>>>, chave: string | null | undefined) => V | undefined;
|
|
3
4
|
export declare function fundirRender(render: ReactElement | undefined, props: {
|
|
4
5
|
className?: string;
|
|
5
6
|
} & Record<string, unknown>, padrao?: string): ReactElement;
|
package/dist/pure.js
CHANGED
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
// `.ts` aqui seria um arquivo que gate nenhum enxerga.
|
|
17
17
|
import { cloneElement, createElement } from "react";
|
|
18
18
|
export const cx = (...v) => v.filter(Boolean).join(" ");
|
|
19
|
+
// O valor de uma tabela só quando a chave é DELA (31/10/2026, a auditoria de segurança). Tabela escrita como objeto
|
|
20
|
+
// comum herda o `Object.prototype`: uma chave que vem de fora ("constructor", "__proto__", "toString") devolvia a
|
|
21
|
+
// função dele — no realce do `CodeBlock`, isso derrubava a tela. Interno: o barril não o publica.
|
|
22
|
+
export const proprio = (tabela, chave) => chave != null && Object.hasOwn(tabela, chave) ? tabela[chave] : undefined;
|
|
19
23
|
// ── `render`: a superfície é da Aurea, o ELEMENTO é de quem consome ───────────────────────────
|
|
20
24
|
//
|
|
21
25
|
// Nasceu do `G-A11Y-11`. O `Card` oferecia `variant="interactive"` — ponteiro de mão, elevação
|
package/dist/system.js
CHANGED
|
@@ -7,7 +7,7 @@ import React from "react";
|
|
|
7
7
|
import { Toast as BaseToast } from "@base-ui/react/toast";
|
|
8
8
|
import { Tooltip as BaseTooltip } from "@base-ui/react/tooltip";
|
|
9
9
|
import { DirectionProvider } from "@base-ui/react/direction-provider";
|
|
10
|
-
import { peleDoEixo } from "./pure.js";
|
|
10
|
+
import { peleDoEixo, proprio } from "./pure.js";
|
|
11
11
|
import { cx, StringsContext, SpriteContext, PortalContext, ThemeContext, DensityContext, DentroDoProviderContext, avisosAncorados, usePortalContainer, defaultStrings, defaultSpriteUrl, useSpriteUrl, useAureaStrings } from "./internal.js";
|
|
12
12
|
// `theme` e `density` seguem a convenção controlado/não-controlado do resto da biblioteca
|
|
13
13
|
// (`Toggle`, `ToggleGroup`): passe `theme` para mandar, `defaultTheme` para semear, e ouça por
|
|
@@ -186,7 +186,7 @@ function AureaToastList({ placement }) {
|
|
|
186
186
|
const arrasto = [placement.startsWith("top") ? "up" : "down", "right"];
|
|
187
187
|
return _jsx(_Fragment, { children: toasts.map(t => {
|
|
188
188
|
const tipo = t.type === "error" ? "danger" : t.type;
|
|
189
|
-
return _jsxs(BaseToast.Root, { toast: t, swipeDirection: arrasto, className: cx("toast", tipo && `toast-${tipo}`), children: [_jsxs(BaseToast.Content, { className: "toast-content", children: [_jsx("span", { className: "toast-indicator", "aria-hidden": "true", children: tipo === "loading" ? _jsx("span", { className: "spinner" }) : _jsx(Icon, { name: ICONE_DO_AVISO
|
|
189
|
+
return _jsxs(BaseToast.Root, { toast: t, swipeDirection: arrasto, className: cx("toast", tipo && `toast-${tipo}`), children: [_jsxs(BaseToast.Content, { className: "toast-content", children: [_jsx("span", { className: "toast-indicator", "aria-hidden": "true", children: tipo === "loading" ? _jsx("span", { className: "spinner" }) : _jsx(Icon, { name: proprio(ICONE_DO_AVISO, tipo) ?? "info" }) }), _jsxs("div", { className: "toast-text", children: [_jsx(BaseToast.Title, { className: "toast-title", render: _jsx("strong", {}) }), t.description ? _jsx(BaseToast.Description, { className: "toast-description" }) : null] }), t.actionProps ? _jsx(BaseToast.Action, { className: "btn btn-tertiary btn-sm toast-action" }) : null] }), _jsx(BaseToast.Close, { className: "btn btn-tertiary close-button toast-close", "aria-label": s.dismissNotification, children: _jsx("span", { children: _jsx(Icon, { name: "x", weight: "bold" }) }) })] }, t.id);
|
|
190
190
|
}) });
|
|
191
191
|
}
|
|
192
192
|
function AureaToastViewport({ placement }) {
|