@aurea-uds/react 0.34.0 → 0.36.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/feedback-client.d.ts +25 -3
- package/dist/feedback-client.js +47 -2
- package/dist/feedback.d.ts +1 -1
- package/dist/feedback.js +1 -1
- package/dist/graph-geometria.d.ts +24 -0
- package/dist/graph-geometria.js +109 -0
- package/dist/graph.d.ts +4 -1
- package/dist/graph.js +133 -14
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/layout-client.d.ts +12 -2
- package/dist/layout-client.js +26 -10
- package/dist/markup.d.ts +43 -8
- package/dist/markup.js +22 -8
- package/dist/navigation.d.ts +1 -1
- package/dist/pure.d.ts +11 -0
- package/dist/pure.js +2 -2
- package/package.json +1 -1
|
@@ -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
|
-
|
|
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
|
-
|
|
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>;
|
package/dist/feedback-client.js
CHANGED
|
@@ -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(
|
|
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á
|
package/dist/feedback.d.ts
CHANGED
|
@@ -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";
|
|
@@ -39,6 +39,30 @@ export declare function remapear<T extends {
|
|
|
39
39
|
para: string;
|
|
40
40
|
n: number;
|
|
41
41
|
}[];
|
|
42
|
+
export declare const naGrade: (v: number, passo: number) => number;
|
|
43
|
+
export declare function rotaNaGrade(rota: readonly Ponto[], dDe: Ponto, dPara: Ponto): Ponto[];
|
|
44
|
+
export type Guia = {
|
|
45
|
+
eixo: "x" | "y";
|
|
46
|
+
em: number;
|
|
47
|
+
de: number;
|
|
48
|
+
ate: number;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* A ponta de uma linha ligada ao nó arrastado (o Victor, 17/10/2026: "todos consigo alinhar, menos esse — nunca fica
|
|
52
|
+
* reto"): a porta 1 fica a um terço do lado do Núcleo, e nem a borda nem o centro do outro nó caem embaixo dela. `meu` é
|
|
53
|
+
* onde a linha sai do nó arrastado, medido do canto dele; `outro`, onde ela chega no outro nó, no mapa. `eixo` é o que
|
|
54
|
+
* acerta para a linha ficar reta: `x` quando as duas pontas são de cima e de baixo; `y`, quando são dos lados.
|
|
55
|
+
*/
|
|
56
|
+
export type PontaDoArraste = {
|
|
57
|
+
meu: Ponto;
|
|
58
|
+
outro: Ponto;
|
|
59
|
+
eixo: "x" | "y";
|
|
60
|
+
};
|
|
61
|
+
export declare function guiasDoArraste(eu: Caixa, outros: readonly Caixa[], tolerancia: number, pontas?: readonly PontaDoArraste[]): {
|
|
62
|
+
x: number;
|
|
63
|
+
y: number;
|
|
64
|
+
guias: Guia[];
|
|
65
|
+
};
|
|
42
66
|
/** Tira os pontos repetidos e os do meio de um trecho reto: a ponte e o canto contam os trechos. */
|
|
43
67
|
export declare function simplificar(pontos: readonly Ponto[]): Ponto[];
|
|
44
68
|
/** O ponto no MEIO do comprimento — onde fica o rótulo e a pastilha da linha. */
|
package/dist/graph-geometria.js
CHANGED
|
@@ -204,6 +204,115 @@ export function remapear(arestas, rep) {
|
|
|
204
204
|
}
|
|
205
205
|
return saida;
|
|
206
206
|
}
|
|
207
|
+
// ── NA GRADE (MNT-28, 17/10/2026) ─────────────────────────────────────────────────────────────
|
|
208
|
+
// O arranjo automático põe os nós onde o motor quer (0, 270, 540…), fora da grade de 16 do modo de
|
|
209
|
+
// arrumar: o nó arrastado só voltava a 528 ou 544, e a linha ganhava um degrau (o Victor, comparando com
|
|
210
|
+
// o draw.io). Com a grade ligada, cada nó vai para o ponto da grade mais perto, e a rota em ângulo reto
|
|
211
|
+
// acompanha: a ponta anda com o nó, e a primeira e a última dobra corrigem só o eixo do trecho delas,
|
|
212
|
+
// para o trecho continuar reto. A reta que sai do eixo vira um degrau no meio.
|
|
213
|
+
export const naGrade = (v, passo) => Math.round(v / passo) * passo;
|
|
214
|
+
export function rotaNaGrade(rota, dDe, dPara) {
|
|
215
|
+
if (rota.length < 2)
|
|
216
|
+
return rota.map(p => ({ x: p.x, y: p.y }));
|
|
217
|
+
const p = rota.map(q => ({ x: q.x, y: q.y })), n = p.length - 1;
|
|
218
|
+
const deitado = (a, b) => Math.abs(a.y - b.y) < 0.5;
|
|
219
|
+
const h0 = deitado(rota[0], rota[1]), hN = deitado(rota[n - 1], rota[n]);
|
|
220
|
+
p[0] = { x: p[0].x + dDe.x, y: p[0].y + dDe.y };
|
|
221
|
+
p[n] = { x: p[n].x + dPara.x, y: p[n].y + dPara.y };
|
|
222
|
+
if (n === 1) {
|
|
223
|
+
if (h0 && Math.abs(p[0].y - p[1].y) >= 0.5) {
|
|
224
|
+
const mx = (p[0].x + p[1].x) / 2;
|
|
225
|
+
return simplificar([p[0], { x: mx, y: p[0].y }, { x: mx, y: p[1].y }, p[1]]);
|
|
226
|
+
}
|
|
227
|
+
if (!h0 && Math.abs(p[0].x - p[1].x) >= 0.5) {
|
|
228
|
+
const my = (p[0].y + p[1].y) / 2;
|
|
229
|
+
return simplificar([p[0], { x: p[0].x, y: my }, { x: p[1].x, y: my }, p[1]]);
|
|
230
|
+
}
|
|
231
|
+
return p;
|
|
232
|
+
}
|
|
233
|
+
p[1] = h0 ? { x: p[1].x, y: p[0].y } : { x: p[0].x, y: p[1].y };
|
|
234
|
+
p[n - 1] = hN ? { x: p[n - 1].x, y: p[n].y } : { x: p[n].x, y: p[n - 1].y };
|
|
235
|
+
return simplificar(p);
|
|
236
|
+
}
|
|
237
|
+
export function guiasDoArraste(eu, outros, tolerancia, pontas = []) {
|
|
238
|
+
const marcasX = (c) => [c.x, c.x + c.larg / 2, c.x + c.larg], marcasY = (c) => [c.y, c.y + c.alt / 2, c.y + c.alt];
|
|
239
|
+
let dx = 0, dy = 0, melhorX = Infinity, melhorY = Infinity;
|
|
240
|
+
let retaX, retaY;
|
|
241
|
+
const mx = marcasX(eu), my = marcasY(eu);
|
|
242
|
+
for (const o of outros) {
|
|
243
|
+
const ox = marcasX(o), oy = marcasY(o);
|
|
244
|
+
for (let i = 0; i < 3; i++) {
|
|
245
|
+
const ex = ox[i] - mx[i], ey = oy[i] - my[i];
|
|
246
|
+
if (Math.abs(ex) <= tolerancia && Math.abs(ex) < melhorX) {
|
|
247
|
+
melhorX = Math.abs(ex);
|
|
248
|
+
dx = ex;
|
|
249
|
+
}
|
|
250
|
+
if (Math.abs(ey) <= tolerancia && Math.abs(ey) < melhorY) {
|
|
251
|
+
melhorY = Math.abs(ey);
|
|
252
|
+
dy = ey;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// A linha reta vem DEPOIS e ganha no empate: com a mesma distância, endireitar a linha vale mais que alinhar a caixa.
|
|
257
|
+
for (const p of pontas) {
|
|
258
|
+
if (p.eixo === "x") {
|
|
259
|
+
const e = p.outro.x - (eu.x + p.meu.x);
|
|
260
|
+
if (Math.abs(e) <= tolerancia && Math.abs(e) <= melhorX) {
|
|
261
|
+
melhorX = Math.abs(e);
|
|
262
|
+
dx = e;
|
|
263
|
+
retaX = p;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
const e = p.outro.y - (eu.y + p.meu.y);
|
|
268
|
+
if (Math.abs(e) <= tolerancia && Math.abs(e) <= melhorY) {
|
|
269
|
+
melhorY = Math.abs(e);
|
|
270
|
+
dy = e;
|
|
271
|
+
retaY = p;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
const novo = { ...eu, x: eu.x + dx, y: eu.y + dy };
|
|
276
|
+
if (retaX || retaY) {
|
|
277
|
+
// A guia da linha reta corre por cima da própria linha, de uma ponta à outra.
|
|
278
|
+
const guias = [];
|
|
279
|
+
if (retaX) {
|
|
280
|
+
const y0 = novo.y + retaX.meu.y;
|
|
281
|
+
guias.push({ eixo: "x", em: retaX.outro.x, de: Math.min(y0, retaX.outro.y), ate: Math.max(y0, retaX.outro.y) });
|
|
282
|
+
}
|
|
283
|
+
if (retaY) {
|
|
284
|
+
const x0 = novo.x + retaY.meu.x;
|
|
285
|
+
guias.push({ eixo: "y", em: retaY.outro.y, de: Math.min(x0, retaY.outro.x), ate: Math.max(x0, retaY.outro.x) });
|
|
286
|
+
}
|
|
287
|
+
const resto = guiasDeAlinhamento(novo, outros, retaX ? Infinity : melhorX, retaY ? Infinity : melhorY);
|
|
288
|
+
return { x: novo.x, y: novo.y, guias: [...guias, ...resto] };
|
|
289
|
+
}
|
|
290
|
+
return { x: novo.x, y: novo.y, guias: guiasDeAlinhamento(novo, outros, melhorX, melhorY) };
|
|
291
|
+
}
|
|
292
|
+
function guiasDeAlinhamento(novo, outros, melhorX, melhorY) {
|
|
293
|
+
const marcasX = (c) => [c.x, c.x + c.larg / 2, c.x + c.larg], marcasY = (c) => [c.y, c.y + c.alt / 2, c.y + c.alt];
|
|
294
|
+
// UMA guia por eixo: com o mesmo tamanho, alinhar o topo alinha também o meio e a base, e três linhas juntas
|
|
295
|
+
// não dizem nada. Vale a do centro, se ele alinhou; senão, a da borda. Ela vai de ponta a ponta de quem alinhou.
|
|
296
|
+
const guias = [];
|
|
297
|
+
const umaGuia = (eixo, marcas) => {
|
|
298
|
+
const minhas = marcas(novo);
|
|
299
|
+
for (const i of [1, 0, 2]) {
|
|
300
|
+
const juntos = outros.filter(o => Math.abs(marcas(o)[i] - minhas[i]) < 0.5);
|
|
301
|
+
if (!juntos.length)
|
|
302
|
+
continue;
|
|
303
|
+
const todos = [novo, ...juntos];
|
|
304
|
+
guias.push(eixo === "x"
|
|
305
|
+
? { eixo, em: minhas[i], de: Math.min(...todos.map(c => c.y)), ate: Math.max(...todos.map(c => c.y + c.alt)) }
|
|
306
|
+
: { eixo, em: minhas[i], de: Math.min(...todos.map(c => c.x)), ate: Math.max(...todos.map(c => c.x + c.larg)) });
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
if (melhorX < Infinity)
|
|
311
|
+
umaGuia("x", marcasX);
|
|
312
|
+
if (melhorY < Infinity)
|
|
313
|
+
umaGuia("y", marcasY);
|
|
314
|
+
return guias;
|
|
315
|
+
}
|
|
207
316
|
// ── O TRAÇADO (MNT-12.1 e 12.3) ───────────────────────────────────────────────────────────────
|
|
208
317
|
/** Tira os pontos repetidos e os do meio de um trecho reto: a ponte e o canto contam os trechos. */
|
|
209
318
|
export function simplificar(pontos) {
|
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
|
|
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
|
@@ -39,12 +39,12 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
39
39
|
// Quem importa a folha é o CONSUMIDOR, uma vez, como já importa o `@aurea-uds/core/css`: um
|
|
40
40
|
// `import "…css"` dentro deste módulo quebraria em Node puro e o build daqui é `tsc` só.
|
|
41
41
|
import React from "react";
|
|
42
|
-
import { ReactFlow, ReactFlowProvider, Background, BaseEdge, EdgeLabelRenderer, EdgeText, Handle, MiniMap, Panel, Position, SelectionMode, applyNodeChanges, getBezierPath, getSmoothStepPath, useNodesInitialized, useOnViewportChange, useReactFlow, useStore } from "@xyflow/react";
|
|
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
44
|
import { Icon } from "./system.js";
|
|
45
45
|
import { Badge } from "./markup.js";
|
|
46
46
|
import { IconButton, Toolbar, ToolbarButton, ToolbarSeparator } from "./actions.js";
|
|
47
|
-
import { alinhar, distribuir, subarvores, recolher, remapear, simplificar, pontes, tracado, meioDoTracado, ladoDoTrecho, rotaCruza, bordaNaDirecao, rotulosQueSomem, contornoDeNuvem } from "./graph-geometria.js";
|
|
47
|
+
import { alinhar, distribuir, subarvores, recolher, remapear, simplificar, pontes, tracado, meioDoTracado, ladoDoTrecho, rotaCruza, bordaNaDirecao, rotulosQueSomem, contornoDeNuvem, naGrade, rotaNaGrade, guiasDoArraste } from "./graph-geometria.js";
|
|
48
48
|
// ── O layout ─────────────────────────────────────────────────────────────────────────────
|
|
49
49
|
// O motor recebe `x`/`y` PRONTOS: ele não posiciona nada. Sem isto, um grafo sem coordenadas
|
|
50
50
|
// empilha tudo em (0,0) — que foi a medição que quase derrubou a escolha do motor.
|
|
@@ -63,6 +63,8 @@ const LARGURA = 180, ALTURA = 52, VAO_X = 90, VAO_Y = 24;
|
|
|
63
63
|
const CABECA_DO_GRUPO = 40, RECHEIO_DO_GRUPO = 16;
|
|
64
64
|
// A grade do modo de arrumar: `--space-4` (16). As setas andam um passo dela; com Shift, quatro.
|
|
65
65
|
const GRADE = 16;
|
|
66
|
+
// As guias do arraste (MNT-28): o nó encaixa no vizinho a até `--space-2` (8) dele, em unidade do mapa.
|
|
67
|
+
const TOLERANCIA_DA_GUIA = 8;
|
|
66
68
|
// A ponte no cruzamento: meia elipse de raio `--radius-xs` (6) — o tamanho do salto do draw.io.
|
|
67
69
|
const RAIO_DA_PONTE = 6;
|
|
68
70
|
// O desvio de linhas (`@tisoap/react-flow-smart-edge`): folga em volta do nó e malha da busca, as duas
|
|
@@ -169,6 +171,7 @@ const LADO_ELK = { top: "NORTH", right: "EAST", bottom: "SOUTH", left: "WEST" };
|
|
|
169
171
|
// E no nó com porta, a linha SEM porta vai a uma porta "de base", no meio do lado de entrada ou de
|
|
170
172
|
// saída: medido no protótipo, sem ela o arrumador ligava a linha no CANTO do nó (o 0,0 da caixa).
|
|
171
173
|
let avisouSemElk = false;
|
|
174
|
+
let avisouFaixa = false;
|
|
172
175
|
let elkNaTela = null;
|
|
173
176
|
// FORA DA TELA PRINCIPAL (MNT-19.1): o `elk.bundled.js` roda na própria tela (é um "falso trabalhador").
|
|
174
177
|
// Com `layoutWorker`, o APP entrega o trabalhador de verdade — o jeito de criar um trabalhador muda de
|
|
@@ -222,13 +225,36 @@ async function arrumarComElk(elk, e) {
|
|
|
222
225
|
}
|
|
223
226
|
arestas = arvore;
|
|
224
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
|
+
}
|
|
225
251
|
const comPortas = new Set(e.algoritmo === "layered" ? e.folhas.filter(f => f.portas.length).map(f => f.id) : []);
|
|
226
252
|
const noElk = (f) => {
|
|
227
253
|
const opcoes = {};
|
|
228
254
|
if (f.raiz && e.algoritmo === "layered")
|
|
229
255
|
opcoes["elk.layered.layering.layerConstraint"] = "FIRST";
|
|
230
|
-
if (
|
|
231
|
-
opcoes["elk.
|
|
256
|
+
if (porFaixa && !f.pai)
|
|
257
|
+
opcoes["elk.partitioning.partition"] = String(f.camada);
|
|
232
258
|
if (!comPortas.has(f.id))
|
|
233
259
|
return { id: f.id, width: f.larg, height: f.alt, layoutOptions: opcoes };
|
|
234
260
|
opcoes["elk.portConstraints"] = "FIXED_POS";
|
|
@@ -250,7 +276,8 @@ async function arrumarComElk(elk, e) {
|
|
|
250
276
|
const recheio = `[top=${RECHEIO_DO_GRUPO + CABECA_DO_GRUPO},left=${RECHEIO_DO_GRUPO},bottom=${RECHEIO_DO_GRUPO},right=${RECHEIO_DO_GRUPO}]`;
|
|
251
277
|
if (hierarquia)
|
|
252
278
|
for (const g of e.grupos)
|
|
253
|
-
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)) } : {}) } });
|
|
254
281
|
const dentro = (pai) => (pai && caixas.get(pai)) || raiz;
|
|
255
282
|
if (hierarquia)
|
|
256
283
|
for (const g of e.grupos)
|
|
@@ -263,6 +290,7 @@ async function arrumarComElk(elk, e) {
|
|
|
263
290
|
...(e.algoritmo === "layered" ? { "elk.algorithm": "layered", "elk.direction": vertical ? "DOWN" : "RIGHT",
|
|
264
291
|
"elk.layered.spacing.nodeNodeBetweenLayers": String(VAO_X),
|
|
265
292
|
"elk.layered.nodePlacement.strategy": "BRANDES_KOEPF", "elk.layered.nodePlacement.bk.fixedAlignment": "BALANCED",
|
|
293
|
+
...(porFaixa ? { "elk.partitioning.activate": "true" } : {}),
|
|
266
294
|
...(hierarquia ? { "elk.hierarchyHandling": "INCLUDE_CHILDREN" } : {}) }
|
|
267
295
|
: e.algoritmo === "mrtree" ? { "elk.algorithm": "mrtree", "elk.direction": vertical ? "DOWN" : "RIGHT" }
|
|
268
296
|
: { "elk.algorithm": "radial" }) };
|
|
@@ -652,8 +680,8 @@ export function DependencyGraph({ nodes, edges, label, selectedId, onSelect, con
|
|
|
652
680
|
const algoritmo = layout === "layered" ? "layered" : layout === "tree" ? "mrtree" : layout === "radial" ? "radial" : null;
|
|
653
681
|
const entradaElk = React.useMemo(() => algoritmo ? { algoritmo, orientacao: orientation,
|
|
654
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 })),
|
|
655
|
-
grupos: [...abertos].sort((a, b) => profundidade(a) - profundidade(b)).map(id => ({ id, pai: paiAberto(id) })),
|
|
656
|
-
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]);
|
|
657
685
|
const chaveElk = React.useMemo(() => entradaElk ? JSON.stringify(entradaElk) : "", [entradaElk]);
|
|
658
686
|
// A arrumação chega DEPOIS (é assíncrona e o pacote é opcional); até lá, e no servidor, a simples.
|
|
659
687
|
const [elk, setElk] = React.useState(null);
|
|
@@ -694,7 +722,33 @@ export function DependencyGraph({ nodes, edges, label, selectedId, onSelect, con
|
|
|
694
722
|
// `entradaElk` muda junto com a chave; a chave é o que diz se mudou DE VERDADE.
|
|
695
723
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
696
724
|
}, [chaveElk]);
|
|
697
|
-
|
|
725
|
+
// MNT-28: com a grade ligada, o arranjo automático JÁ na grade — o motor e a arrumação simples —, e a rota do
|
|
726
|
+
// motor acompanha o nó (`rotaNaGrade`). Assim o nó arrastado volta exatamente à linha dos outros.
|
|
727
|
+
const naGradeLigada = editavel && grid;
|
|
728
|
+
const elkVisto = React.useMemo(() => {
|
|
729
|
+
if (!elk || !naGradeLigada)
|
|
730
|
+
return elk;
|
|
731
|
+
const posicoes = new Map(), delta = new Map();
|
|
732
|
+
for (const [id, p] of elk.posicoes) {
|
|
733
|
+
const q = { x: naGrade(p.x, GRADE), y: naGrade(p.y, GRADE) };
|
|
734
|
+
posicoes.set(id, q);
|
|
735
|
+
delta.set(id, { x: q.x - p.x, y: q.y - p.y });
|
|
736
|
+
}
|
|
737
|
+
const pontas = new Map((entradaElk?.arestas ?? []).map(a => [a.id, a])), zero = { x: 0, y: 0 };
|
|
738
|
+
const rotas = new Map();
|
|
739
|
+
for (const [id, r] of elk.rotas) {
|
|
740
|
+
const a = pontas.get(id);
|
|
741
|
+
rotas.set(id, a ? rotaNaGrade(r, delta.get(a.de) ?? zero, delta.get(a.para) ?? zero) : r);
|
|
742
|
+
}
|
|
743
|
+
return { posicoes, rotas };
|
|
744
|
+
}, [elk, naGradeLigada, entradaElk]);
|
|
745
|
+
const autoDe = React.useCallback((id) => {
|
|
746
|
+
const doMotor = elkVisto?.posicoes.get(id);
|
|
747
|
+
if (doMotor)
|
|
748
|
+
return doMotor;
|
|
749
|
+
const a = automatico.posicoes.get(id) ?? { x: 0, y: 0 };
|
|
750
|
+
return naGradeLigada ? { x: naGrade(a.x, GRADE), y: naGrade(a.y, GRADE) } : a;
|
|
751
|
+
}, [elkVisto, automatico, naGradeLigada]);
|
|
698
752
|
// ── ONDE CADA UM ESTÁ (coordenada ABSOLUTA) ──────────────────────────────────────────────────
|
|
699
753
|
const posFinal = React.useMemo(() => {
|
|
700
754
|
const p = new Map();
|
|
@@ -821,7 +875,72 @@ export function DependencyGraph({ nodes, edges, label, selectedId, onSelect, con
|
|
|
821
875
|
const confirmar = React.useRef(() => { });
|
|
822
876
|
const abertosAgora = React.useRef(abertos);
|
|
823
877
|
abertosAgora.current = abertos;
|
|
824
|
-
|
|
878
|
+
// ── AS GUIAS DO ARRASTE (MNT-28) ───────────────────────────────────────────────────────────────
|
|
879
|
+
// Um nó só, arrastado no modo de arrumar: ele encaixa na borda ou no centro do vizinho mais perto
|
|
880
|
+
// (`guiasDoArraste`), e a guia aparece. A posição encaixada vale também ao soltar — no fim do arraste o
|
|
881
|
+
// motor manda a posição DELE, e a que fica é a nossa.
|
|
882
|
+
const [guias, setGuias] = React.useState([]);
|
|
883
|
+
const agora = React.useRef({ caixas, paiAberto, ocultos, editavel });
|
|
884
|
+
agora.current = { caixas, paiAberto, ocultos, editavel };
|
|
885
|
+
const encaixado = React.useRef(new Map());
|
|
886
|
+
// As pontas das linhas do nó arrastado, para ele encaixar onde a linha fica RETA (o Victor, 17/10/2026: a linha da
|
|
887
|
+
// porta 1 do Núcleo "nunca fica reta"). A mesma conta do traçado: a alça, a porta e o afastamento das paralelas.
|
|
888
|
+
const pontasDe = React.useRef(() => []);
|
|
889
|
+
pontasDe.current = id => {
|
|
890
|
+
const alca = (no, porta, tipo) => {
|
|
891
|
+
const n = porId.get(no), c = caixas.get(no);
|
|
892
|
+
if (!n || !c)
|
|
893
|
+
return undefined;
|
|
894
|
+
const lista = alcasDoNo(abertos.has(no) || contemFilhos.has(no) ? { ...n, ports: undefined } : n, orientation, { larg: c.larg, alt: c.alt });
|
|
895
|
+
return (porta && lista.find(a => a.id === porta && a.type === tipo)) || lista.find(a => !a.id && a.type === tipo);
|
|
896
|
+
};
|
|
897
|
+
const deitada = (a) => a.position === Position.Left || a.position === Position.Right;
|
|
898
|
+
const saida = [];
|
|
899
|
+
desenhadas.forEach(({ item: e }, i) => {
|
|
900
|
+
if ((e.from !== id && e.to !== id) || e.from === e.to || ocultos.has(e.from) || ocultos.has(e.to))
|
|
901
|
+
return;
|
|
902
|
+
const sou = e.from === id, outro = sou ? e.to : e.from, cm = caixas.get(id), co = caixas.get(outro);
|
|
903
|
+
const am = alca(id, sou ? e.fromPort : e.toPort, sou ? "source" : "target"), ao = alca(outro, sou ? e.toPort : e.fromPort, sou ? "target" : "source");
|
|
904
|
+
if (!cm || !co || !am || !ao || deitada(am) !== deitada(ao))
|
|
905
|
+
return;
|
|
906
|
+
const desl = ident[i].deslocamento, ddx = vertical ? desl : 0, ddy = vertical ? 0 : desl;
|
|
907
|
+
const pm = pontoDaAlca(cm, am), po = pontoDaAlca(co, ao);
|
|
908
|
+
saida.push({ meu: { x: pm.x - cm.x + ddx, y: pm.y - cm.y + ddy }, outro: { x: po.x + ddx, y: po.y + ddy }, eixo: deitada(am) ? "y" : "x" });
|
|
909
|
+
});
|
|
910
|
+
return saida;
|
|
911
|
+
};
|
|
912
|
+
const comGuias = React.useCallback((mudancas) => {
|
|
913
|
+
const { caixas: cx, paiAberto: paiDe, ocultos: oc, editavel: ed } = agora.current, grupos = abertosAgora.current;
|
|
914
|
+
const arrastes = mudancas.filter((c) => c.type === "position" && !!c.dragging && !!c.position);
|
|
915
|
+
let saida = mudancas;
|
|
916
|
+
const c = arrastes.length === 1 ? arrastes[0] : undefined, eu = c ? cx.get(c.id) : undefined;
|
|
917
|
+
if (ed && c && eu && !grupos.has(c.id)) {
|
|
918
|
+
const pai = paiDe(c.id), cp = pai ? cx.get(pai) : undefined, ox = cp?.x ?? 0, oy = cp?.y ?? 0;
|
|
919
|
+
const outros = [...cx].filter(([id]) => id !== c.id && !oc.has(id) && !grupos.has(id)).map(([, x]) => x);
|
|
920
|
+
const r = guiasDoArraste({ ...eu, x: c.position.x + ox, y: c.position.y + oy }, outros, TOLERANCIA_DA_GUIA, pontasDe.current(c.id));
|
|
921
|
+
const rel = { x: r.x - ox, y: r.y - oy };
|
|
922
|
+
encaixado.current.set(c.id, rel);
|
|
923
|
+
saida = saida.map(m => m === c ? { ...c, position: rel } : m);
|
|
924
|
+
setGuias(g => g.length === r.guias.length && g.every((x, i) => x.eixo === r.guias[i].eixo && x.em === r.guias[i].em && x.de === r.guias[i].de && x.ate === r.guias[i].ate) ? g : r.guias);
|
|
925
|
+
}
|
|
926
|
+
else if (arrastes.length)
|
|
927
|
+
setGuias(g => g.length ? [] : g);
|
|
928
|
+
if (mudancas.some(m => m.type === "position" && !m.dragging)) {
|
|
929
|
+
saida = saida.map(m => {
|
|
930
|
+
if (m.type !== "position" || m.dragging)
|
|
931
|
+
return m;
|
|
932
|
+
const e = encaixado.current.get(m.id);
|
|
933
|
+
if (!e)
|
|
934
|
+
return m;
|
|
935
|
+
encaixado.current.delete(m.id);
|
|
936
|
+
return { ...m, position: e };
|
|
937
|
+
});
|
|
938
|
+
setGuias(g => g.length ? [] : g);
|
|
939
|
+
}
|
|
940
|
+
return saida;
|
|
941
|
+
}, []);
|
|
942
|
+
const aoMudarNos = React.useCallback((mudancasDoMotor) => {
|
|
943
|
+
const mudancas = comGuias(mudancasDoMotor);
|
|
825
944
|
setNosVivos(anteriores => applyNodeChanges(mudancas, anteriores).map(semAlcasDeclaradas));
|
|
826
945
|
const dims = mudancas.filter(c => c.type === "dimensions" && !!c.dimensions && !abertosAgora.current.has(c.id));
|
|
827
946
|
if (dims.length)
|
|
@@ -841,7 +960,7 @@ export function DependencyGraph({ nodes, edges, label, selectedId, onSelect, con
|
|
|
841
960
|
const soltos = mudancas.filter((c) => c.type === "position" && !c.dragging && !!c.position);
|
|
842
961
|
if (soltos.length)
|
|
843
962
|
confirmar.current(soltos);
|
|
844
|
-
}, []);
|
|
963
|
+
}, [comGuias]);
|
|
845
964
|
// ── O DESFAZER (MNT-13.5) E O AVISO PARA O APP GUARDAR (MNT-13.6) ─────────────────────────────
|
|
846
965
|
const pilha = React.useRef({ lista: [], ponteiro: 0 });
|
|
847
966
|
const [, setVersaoDaPilha] = React.useState(0);
|
|
@@ -1008,8 +1127,8 @@ export function DependencyGraph({ nodes, edges, label, selectedId, onSelect, con
|
|
|
1008
1127
|
}
|
|
1009
1128
|
if (edgeShape !== "step")
|
|
1010
1129
|
return;
|
|
1011
|
-
const doElk =
|
|
1012
|
-
const noLugar = (no) => { const a =
|
|
1130
|
+
const doElk = elkVisto?.rotas.get(id);
|
|
1131
|
+
const noLugar = (no) => { const a = elkVisto?.posicoes.get(no), c = caixas.get(no); return !!a && !!c && Math.abs(a.x - c.x) < 0.5 && Math.abs(a.y - c.y) < 0.5; };
|
|
1013
1132
|
if (doElk && noLugar(e.from) && noLugar(e.to) && naBorda(doElk[0], cs) && naBorda(doElk[doElk.length - 1], ct) && !rotaCruza(doElk, menos(e.from, e.to))) {
|
|
1014
1133
|
mapa.set(id, doElk);
|
|
1015
1134
|
return;
|
|
@@ -1035,7 +1154,7 @@ export function DependencyGraph({ nodes, edges, label, selectedId, onSelect, con
|
|
|
1035
1154
|
pendentes.push({ id, de: e.from, para: e.to, s: sp, t: tp, ls: as.position, lt: at.position, chave });
|
|
1036
1155
|
});
|
|
1037
1156
|
return { mapa, pendentes, obstaculos };
|
|
1038
|
-
}, [desenhadas, ident, caixas, abertos, ocultos, movendo, porId, contemFilhos, orientation, layout, edgeShape,
|
|
1157
|
+
}, [desenhadas, ident, caixas, abertos, ocultos, movendo, porId, contemFilhos, orientation, layout, edgeShape, elkVisto, desvios, vertical]);
|
|
1039
1158
|
const chavePendentes = tracados.pendentes.map(p => `${p.id}@${p.chave}`).join("|");
|
|
1040
1159
|
React.useEffect(() => {
|
|
1041
1160
|
if (!tracados.pendentes.length || movendo.size)
|
|
@@ -1257,7 +1376,7 @@ export function DependencyGraph({ nodes, edges, label, selectedId, onSelect, con
|
|
|
1257
1376
|
// a fluidez. O valor é a extensão do próprio layout, então no servidor o grafo cabe exato.
|
|
1258
1377
|
const estilo = { ...style, ...(height ? { blockSize: height } : null), "--graph-node-w": `${m.larg}px` };
|
|
1259
1378
|
return _jsx("div", { ref: raiz, className: cx("dependency-graph", className), style: estilo, "data-text": textSize === "md" ? undefined : textSize, "data-contrast": highContrast ? "high" : undefined, "data-editable": editavel || undefined, role: "group", "aria-label": label ?? s.graphLabel, ...props, children: _jsx(ReactFlowProvider, { initialNodes: nosDoMotor, initialEdges: arestasDoMotor, fitView: true, initialWidth: automatico.extensao.larg, initialHeight: automatico.extensao.alt, children: _jsxs(ReactFlow, { nodes: nosVivos, onNodesChange: aoMudarNos, edges: arestasDoMotor, nodeTypes: TIPOS, edgeTypes: TIPOS_DE_ARESTA, fitView: true, proOptions: { hideAttribution: false }, minZoom: ESCALA_MINIMA, nodesDraggable: editavel || !!onNodeMove, nodesConnectable: !!connectable, elementsSelectable: editavel, nodesFocusable: editavel, edgesFocusable: !!onEdgeSelect, disableKeyboardA11y: !editavel, selectionOnDrag: editavel, panOnDrag: editavel ? BOTOES_DE_ARRASTAR : true, selectionMode: SelectionMode.Partial, multiSelectionKeyCode: TECLAS_DE_SOMAR, deleteKeyCode: null, snapToGrid: editavel && grid, snapGrid: [GRADE, GRADE], onlyRenderVisibleElements: !!visibleOnly, ariaLabelConfig: rotulosDoMotor, onSelectionChange: editavel ? aoMudarEscolha : undefined, onNodeMouseEnter: onNodeHover ? (_, no) => onNodeHover(no.id) : undefined, onNodeMouseLeave: onNodeHover ? () => onNodeHover(null) : undefined, onNodeContextMenu: onNodeContextMenu ? (ev, no) => { ev.preventDefault(); onNodeContextMenu(no.id, { x: ev.clientX, y: ev.clientY }); } : undefined, onEdgeClick: onEdgeSelect ? (_, a) => onEdgeSelect(a.id) : undefined, onConnect: onConnect ? c => { if (c.source && c.target)
|
|
1260
|
-
onConnect({ from: c.source, to: c.target, fromPort: c.sourceHandle ?? undefined, toPort: c.targetHandle ?? undefined }); } : undefined, children: [_jsx(Background, { gap: editavel && grid ? GRADE : undefined }), _jsx(Comandos, { raiz: raiz, teclado: teclado, focusId: focusId, pedidoDeCaber: pedidoDeCaber, controls: !!controls, apiRef: apiRef, linhas: linhas, forma: edgeShape, titulo: label ?? s.graphLabel, desenho: tracados, editavel: editavel, barra: barra, acoes: acoes }), minimap && _jsx(MiniMap, { pannable: true, zoomable: true, ariaLabel: s.graphOverview, className: "graph-minimap" }), legend && (legenda.tipos.length > 0 || legenda.estados.length > 0) && _jsx(Panel, { position: "bottom-left", children: _jsxs("div", { className: "graph-legend", role: "group", "aria-label": s.graphLegend, children: [legenda.tipos.length > 0 && _jsxs(_Fragment, { children: [legenda.estados.length > 0 && _jsx("p", { className: "graph-legend-title", id: `${idDaLegenda}-tipo`, children: s.graphLegendKind }), _jsx("ul", { "aria-labelledby": legenda.estados.length > 0 ? `${idDaLegenda}-tipo` : undefined, children: legenda.tipos.map(t => _jsxs("li", { children: [_jsx(AmostraDaLinha, { padrao: t.padrao, peso: t.peso, marca: t.marca }), _jsx("span", { children: t.nome })] }, t.nome)) })] }), legenda.estados.length > 0 && _jsxs(_Fragment, { children: [legenda.tipos.length > 0 && _jsx("p", { className: "graph-legend-title", id: `${idDaLegenda}-estado`, children: s.graphLegendStatus }), _jsx("ul", { "aria-labelledby": legenda.tipos.length > 0 ? `${idDaLegenda}-estado` : undefined, children: legenda.estados.map(e => _jsxs("li", { children: [_jsx(AmostraDaLinha, { tom: e.tom, marca: e.marca }), _jsx("span", { children: e.nome })] }, e.nome)) })] })] }) })] }) }) });
|
|
1379
|
+
onConnect({ from: c.source, to: c.target, fromPort: c.sourceHandle ?? undefined, toPort: c.targetHandle ?? undefined }); } : undefined, children: [_jsx(Background, { gap: editavel && grid ? GRADE : undefined }), guias.length > 0 && _jsx(ViewportPortal, { children: guias.map(g => _jsx("div", { className: g.eixo === "x" ? "graph-guide graph-guide-x" : "graph-guide graph-guide-y", "aria-hidden": "true", style: g.eixo === "x" ? { transform: `translate(${g.em}px, ${g.de}px)`, blockSize: g.ate - g.de } : { transform: `translate(${g.de}px, ${g.em}px)`, inlineSize: g.ate - g.de } }, `${g.eixo}${g.em}`)) }), _jsx(Comandos, { raiz: raiz, teclado: teclado, focusId: focusId, pedidoDeCaber: pedidoDeCaber, controls: !!controls, apiRef: apiRef, linhas: linhas, forma: edgeShape, titulo: label ?? s.graphLabel, desenho: tracados, editavel: editavel, barra: barra, acoes: acoes }), minimap && _jsx(MiniMap, { pannable: true, zoomable: true, ariaLabel: s.graphOverview, className: "graph-minimap" }), legend && (legenda.tipos.length > 0 || legenda.estados.length > 0) && _jsx(Panel, { position: "bottom-left", children: _jsxs("div", { className: "graph-legend", role: "group", "aria-label": s.graphLegend, children: [legenda.tipos.length > 0 && _jsxs(_Fragment, { children: [legenda.estados.length > 0 && _jsx("p", { className: "graph-legend-title", id: `${idDaLegenda}-tipo`, children: s.graphLegendKind }), _jsx("ul", { "aria-labelledby": legenda.estados.length > 0 ? `${idDaLegenda}-tipo` : undefined, children: legenda.tipos.map(t => _jsxs("li", { children: [_jsx(AmostraDaLinha, { padrao: t.padrao, peso: t.peso, marca: t.marca }), _jsx("span", { children: t.nome })] }, t.nome)) })] }), legenda.estados.length > 0 && _jsxs(_Fragment, { children: [legenda.tipos.length > 0 && _jsx("p", { className: "graph-legend-title", id: `${idDaLegenda}-estado`, children: s.graphLegendStatus }), _jsx("ul", { "aria-labelledby": legenda.tipos.length > 0 ? `${idDaLegenda}-estado` : undefined, children: legenda.estados.map(e => _jsxs("li", { children: [_jsx(AmostraDaLinha, { tom: e.tom, marca: e.marca }), _jsx("span", { children: e.nome })] }, e.nome)) })] })] }) })] }) }) });
|
|
1261
1380
|
}
|
|
1262
1381
|
/** O primeiro alvo de Tab de um nó no mapa de leitura: o botão dele; sem ele, o de fechar. */
|
|
1263
1382
|
function ancoraDoNo(raiz, id) {
|
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";
|
package/dist/layout-client.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type HTMLAttributes, type RefAttributes, type ReactNode } from "react";
|
|
2
2
|
import { type Orientation, type Responsive } from "./pure.js";
|
|
3
|
-
import { type HeaderVariant, type SidebarVariant, type SidebarScrollbar, type SidebarItem } from "./navigation.js";
|
|
4
|
-
export declare function AppShell({ brand, navigation, navItems, currentNavId, navLabel, topbar, topbarVariant, topbarDivider, sidebarVariant, sidebarScrollbar, sidebarCollapsed, sidebarCollapsible, defaultSidebarCollapsed, onSidebarCollapsedChange, contentVariant, aside, asideLabel, asideVariant, children, className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement> & {
|
|
3
|
+
import { type HeaderVariant, type HeaderTab, type SidebarVariant, type SidebarScrollbar, type SidebarItem } from "./navigation.js";
|
|
4
|
+
export declare function AppShell({ brand, navigation, navItems, currentNavId, navLabel, topbar, topbarVariant, topbarDivider, topbarTabs, topbarCurrentTab, topbarTabsLabel, layout, sidebarVariant, sidebarScrollbar, sidebarCollapsed, sidebarCollapsible, defaultSidebarCollapsed, onSidebarCollapsedChange, contentVariant, aside, asideLabel, asideVariant, children, className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement> & {
|
|
5
5
|
brand: ReactNode;
|
|
6
6
|
navigation?: ReactNode;
|
|
7
7
|
navItems?: SidebarItem[];
|
|
@@ -11,6 +11,16 @@ export declare function AppShell({ brand, navigation, navItems, currentNavId, na
|
|
|
11
11
|
topbarVariant?: Exclude<HeaderVariant, "pill">;
|
|
12
12
|
topbarDivider?: boolean;
|
|
13
13
|
sidebarVariant?: SidebarVariant;
|
|
14
|
+
/** O arranjo (lote T, 17/10/2026): `"app"` (o padrão, o de sempre) ou `"docs"`, o da documentação da referência — um
|
|
15
|
+
* bloco CENTRALIZADO de 1400 com a lateral de 220, o texto e o índice de 268 (de 1280 para cima), a barra de cima de 56
|
|
16
|
+
* com a linha das áreas (`topbarTabs`) embaixo. A lateral fica onde a variante dela mandar (`plain`: sem caixa). */
|
|
17
|
+
layout?: "app" | "docs";
|
|
18
|
+
/** A segunda linha da barra de cima: as áreas do site, com ícone (o `tabs` do `Header`). */
|
|
19
|
+
topbarTabs?: HeaderTab[];
|
|
20
|
+
/** O `id` da área atual da segunda linha. */
|
|
21
|
+
topbarCurrentTab?: string;
|
|
22
|
+
/** O nome da segunda linha para o leitor de tela. Padrão: `"Sections"`. */
|
|
23
|
+
topbarTabsLabel?: string;
|
|
14
24
|
/** 0.32.0: a barra de rolagem da lateral da esquerda — o `scrollbar` da `Sidebar`. Padrão `hover` (clara, só com o
|
|
15
25
|
* ponteiro em cima); `visible` é a barra sempre à vista. */
|
|
16
26
|
sidebarScrollbar?: SidebarScrollbar;
|
package/dist/layout-client.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
100
|
-
const aoMudar = (e) => {
|
|
104
|
+
const fechar = (id) => (e) => {
|
|
101
105
|
if (!e.matches)
|
|
102
106
|
return;
|
|
103
|
-
const gaveta = document.getElementById(
|
|
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
|
-
|
|
111
|
-
|
|
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
|
|
@@ -146,9 +155,10 @@ function useLargura(query) {
|
|
|
146
155
|
return () => mq.removeEventListener?.("change", avisar);
|
|
147
156
|
}, () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(query).matches, () => false);
|
|
148
157
|
}
|
|
149
|
-
export function AppShell({ brand, navigation, navItems, currentNavId, navLabel, topbar, topbarVariant = "floating", topbarDivider, sidebarVariant, sidebarScrollbar, sidebarCollapsed, sidebarCollapsible, defaultSidebarCollapsed, onSidebarCollapsedChange, contentVariant = "surface", aside, asideLabel, asideVariant, children, className, ...props }) {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
@@ -101,7 +101,7 @@ export interface GridItemProps extends DivProps {
|
|
|
101
101
|
/** O item da grade que sabe quantas colunas ocupa (GAR-03). Mora em `Grid.Item`, como `Card.Media`. */
|
|
102
102
|
declare function GridItem({ span, className, ...props }: GridItemProps): React.JSX.Element;
|
|
103
103
|
/** A largura máxima do `Container`, pelos nomes da escala de pontos. `xl` (1280) é o padrão. */
|
|
104
|
-
export type ContainerSize = "sm" | "md" | "lg" | "xl" | "2xl" | "full";
|
|
104
|
+
export type ContainerSize = "sm" | "md" | "lg" | "xl" | "2xl" | "docs" | "full";
|
|
105
105
|
export interface ContainerProps extends HTMLAttributes<HTMLDivElement>, RefAttributes<HTMLDivElement> {
|
|
106
106
|
/** Até onde o conteúdo cresce: `sm` 640 · `md` 768 · `lg` 1024 · `xl` 1280 (padrão) · `2xl` 1536 · `full` sem teto. */
|
|
107
107
|
size?: ContainerSize;
|
|
@@ -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
|
-
/**
|
|
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 {
|
|
@@ -348,8 +366,25 @@ export interface HeaderProps extends HTMLAttributes<HTMLElement>, RefAttributes<
|
|
|
348
366
|
menuLabel?: string;
|
|
349
367
|
/** O `id` do painel do celular. Padrão: `"aurea-header-menu"`. Troque só se a página tiver dois cabeçalhos de site. */
|
|
350
368
|
menuId?: string;
|
|
369
|
+
/**
|
|
370
|
+
* A SEGUNDA LINHA (lote T, 17/10/2026): as áreas do site, cada uma com o ícone, como a linha das áreas da documentação da
|
|
371
|
+
* referência. A atual (`currentTab`) ganha `aria-current="page"` e o traço embaixo. Fica por último na ordem do Tab.
|
|
372
|
+
*/
|
|
373
|
+
tabs?: HeaderTab[];
|
|
374
|
+
/** O `id` da área atual da segunda linha. */
|
|
375
|
+
currentTab?: string;
|
|
376
|
+
/** O nome da segunda linha para o leitor de tela. Padrão: `"Sections"`. */
|
|
377
|
+
tabsLabel?: string;
|
|
378
|
+
}
|
|
379
|
+
/** Uma área da segunda linha do `Header`: o nome, o endereço e, se quiser, o ícone (o desenho que o app passa). */
|
|
380
|
+
export interface HeaderTab {
|
|
381
|
+
id: string;
|
|
382
|
+
label: ReactNode;
|
|
383
|
+
href?: string;
|
|
384
|
+
icon?: ReactNode;
|
|
385
|
+
render?: SidebarItem["render"];
|
|
351
386
|
}
|
|
352
|
-
export declare function Header({ variant, divider, brand, items, current, actions, maxWidth, itemsJustify, size, blurred, menuActions, navLabel, menuLabel, menuId, children, className, ...props }: HeaderProps): React.JSX.Element;
|
|
387
|
+
export declare function Header({ variant, divider, brand, items, current, actions, maxWidth, itemsJustify, size, blurred, menuActions, navLabel, menuLabel, menuId, tabs, currentTab, tabsLabel, children, className, ...props }: HeaderProps): React.JSX.Element;
|
|
353
388
|
/** @deprecated `Topbar` é o nome antigo do `Header` (07/10/2026). Continua funcionando, igual; use `Header`. */
|
|
354
389
|
export declare function Topbar(props: HeaderProps): React.JSX.Element;
|
|
355
390
|
export declare function Kbd({ children, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement>): React.JSX.Element;
|
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
|
-
|
|
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.
|
|
@@ -196,10 +206,14 @@ function linksDoHeader(items, current) {
|
|
|
196
206
|
return _jsx("li", { children: it.render ? fundirRender(it.render, p, "a") : _jsx("a", { href: it.href, ...p }) }, it.id);
|
|
197
207
|
}) });
|
|
198
208
|
}
|
|
199
|
-
export function Header({ variant = "floating", divider, brand, items, current, actions, maxWidth, itemsJustify = "end", size = "md", blurred, menuActions, navLabel = "Main", menuLabel = "Menu", menuId = "aurea-header-menu", children, className, ...props }) {
|
|
200
|
-
const site = !!items && items.length > 0;
|
|
201
|
-
const miolo = _jsxs(_Fragment, { children: [brand != null && _jsx("div", { className: "brand", children: brand }), site && _jsx("nav", { className: "topbar-nav", "aria-label": navLabel, children: linksDoHeader(items, current) }), children, actions != null && _jsx("div", { className: "topbar-actions", children: actions }), site && _jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "btn btn-ghost btn-icon topbar-menu-toggle", popoverTarget: menuId, "aria-label": menuLabel, children: _jsx("span", { className: "topbar-menu-icon", "aria-hidden": "true" }) }), _jsxs("nav", { id: menuId, popover: "auto", className: "topbar-menu-panel", "aria-label": navLabel, children: [linksDoHeader(items, current), menuActions != null && _jsx("div", { className: "topbar-menu-actions", children: menuActions })] })] })
|
|
202
|
-
|
|
209
|
+
export function Header({ variant = "floating", divider, brand, items, current, actions, maxWidth, itemsJustify = "end", size = "md", blurred, menuActions, navLabel = "Main", menuLabel = "Menu", menuId = "aurea-header-menu", tabs, currentTab, tabsLabel = "Sections", children, className, ...props }) {
|
|
210
|
+
const site = !!items && items.length > 0, comAbas = !!tabs && tabs.length > 0;
|
|
211
|
+
const miolo = _jsxs(_Fragment, { children: [brand != null && _jsx("div", { className: "brand", children: brand }), site && _jsx("nav", { className: "topbar-nav", "aria-label": navLabel, children: linksDoHeader(items, current) }), children, actions != null && _jsx("div", { className: "topbar-actions", children: actions }), site && _jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "btn btn-ghost btn-icon topbar-menu-toggle", popoverTarget: menuId, "aria-label": menuLabel, children: _jsx("span", { className: "topbar-menu-icon", "aria-hidden": "true" }) }), _jsxs("nav", { id: menuId, popover: "auto", className: "topbar-menu-panel", "aria-label": navLabel, children: [linksDoHeader(items, current), menuActions != null && _jsx("div", { className: "topbar-menu-actions", children: menuActions })] })] }), comAbas && _jsx("nav", { className: "topbar-tabs", "aria-label": tabsLabel, children: tabs.map(t => {
|
|
212
|
+
const p = { className: "topbar-tab", "aria-current": t.id === currentTab ? "page" : undefined,
|
|
213
|
+
children: _jsxs(_Fragment, { children: [t.icon != null && _jsx("span", { className: "topbar-tab-icon", "aria-hidden": "true", children: t.icon }), _jsx("span", { children: t.label })] }) };
|
|
214
|
+
return _jsx(React.Fragment, { children: t.render ? fundirRender(t.render, p, "a") : _jsx("a", { href: t.href, ...p }) }, t.id);
|
|
215
|
+
}) })] });
|
|
216
|
+
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 });
|
|
203
217
|
}
|
|
204
218
|
/** @deprecated `Topbar` é o nome antigo do `Header` (07/10/2026). Continua funcionando, igual; use `Header`. */
|
|
205
219
|
export function Topbar(props) { return _jsx(Header, { ...props }); }
|
package/dist/navigation.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from "./navigation-client.js";
|
|
2
|
-
export { Header, Topbar, type HeaderVariant, type HeaderProps, type TopbarVariant } from "./markup.js";
|
|
2
|
+
export { Header, Topbar, type HeaderVariant, type HeaderProps, type HeaderTab, type TopbarVariant } from "./markup.js";
|
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
|