@aurea-uds/react 0.25.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions.d.ts +20 -2
- package/dist/actions.js +66 -3
- package/dist/code-client.d.ts +2 -1
- package/dist/code-client.js +18 -2
- package/dist/data-display.d.ts +1 -1
- package/dist/feedback.d.ts +1 -1
- package/dist/file-input.js +6 -1
- package/dist/index.d.ts +1 -1
- package/dist/internal.d.ts +1 -0
- package/dist/internal.js +5 -0
- package/dist/markup.d.ts +24 -7
- package/dist/markup.js +12 -6
- package/dist/media-client.d.ts +9 -1
- package/dist/media-client.js +17 -6
- package/dist/pure.d.ts +3 -0
- package/dist/pure.js +2 -2
- package/dist/system.js +39 -2
- package/package.json +1 -1
package/dist/actions.d.ts
CHANGED
|
@@ -51,6 +51,22 @@ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>, Re
|
|
|
51
51
|
*/
|
|
52
52
|
pressed?: boolean;
|
|
53
53
|
kbd?: string;
|
|
54
|
+
/**
|
|
55
|
+
* GAR-14 (0.28.0): o botão COMPARTILHA. Ele pergunta ao navegador se sabe compartilhar este link
|
|
56
|
+
* (`navigator.canShare`) — detectar o recurso, e não adivinhar o aparelho, é o padrão da web. Sabe
|
|
57
|
+
* (celular; Chrome, Edge e Safari no computador): abre a janela do aparelho, e cancelar não é erro.
|
|
58
|
+
* Não sabe: copia o link e mostra "Link copiado" preso ao botão, com a medida dele. A cópia falhou:
|
|
59
|
+
* avisa e mostra o link selecionado. O aviso fala com o leitor de tela nos dois casos.
|
|
60
|
+
* Sem `url`, é o endereço da página. O aviso precisa do `AureaProvider` (ou do `aurea.js` na página).
|
|
61
|
+
* Só vale no `<button>`: com `href` ou `render`, é ignorado.
|
|
62
|
+
*/
|
|
63
|
+
share?: ButtonShareData;
|
|
64
|
+
}
|
|
65
|
+
/** O que o `Button share` compartilha (GAR-14). Os nomes são os do `navigator.share` da web. */
|
|
66
|
+
export interface ButtonShareData {
|
|
67
|
+
url?: string;
|
|
68
|
+
title?: string;
|
|
69
|
+
text?: string;
|
|
54
70
|
}
|
|
55
71
|
export declare const Button: React.ForwardRefExoticComponent<Omit<ButtonProps, "ref"> & RefAttributes<HTMLButtonElement>>;
|
|
56
72
|
interface ToggleBase {
|
|
@@ -79,7 +95,7 @@ export interface IconButtonProps extends Omit<ButtonProps, "children"> {
|
|
|
79
95
|
icon: IconName;
|
|
80
96
|
}
|
|
81
97
|
export declare const IconButton: React.ForwardRefExoticComponent<Omit<IconButtonProps, "ref"> & RefAttributes<HTMLButtonElement>>;
|
|
82
|
-
export interface ThemeToggleProps extends Omit<IconButtonProps, "icon" | "label" | "onClick" | "variant" | "appearance" | "tone" | "href" | "target" | "rel" | "download" | "render" | "kbd" | "loading" | "leadingIcon" | "trailingIcon" | "fullWidth"> {
|
|
98
|
+
export interface ThemeToggleProps extends Omit<IconButtonProps, "icon" | "label" | "onClick" | "variant" | "appearance" | "tone" | "href" | "target" | "rel" | "download" | "render" | "kbd" | "loading" | "leadingIcon" | "trailingIcon" | "fullWidth" | "share"> {
|
|
83
99
|
}
|
|
84
100
|
export declare const ThemeToggle: React.ForwardRefExoticComponent<Omit<ThemeToggleProps, "ref"> & RefAttributes<HTMLButtonElement>>;
|
|
85
101
|
export declare function ButtonGroup({ label, orientation, className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement> & {
|
|
@@ -94,7 +110,9 @@ export declare function ToolbarGroup({ label, className, ...props }: HTMLAttribu
|
|
|
94
110
|
label?: string;
|
|
95
111
|
}): React.JSX.Element;
|
|
96
112
|
export declare function ToolbarSeparator({ className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>): React.JSX.Element;
|
|
97
|
-
export
|
|
113
|
+
export interface ToolbarButtonProps extends Omit<ButtonProps, "share"> {
|
|
114
|
+
}
|
|
115
|
+
export declare const ToolbarButton: React.ForwardRefExoticComponent<Omit<ToolbarButtonProps, "ref"> & RefAttributes<HTMLButtonElement>>;
|
|
98
116
|
export declare function ToggleGroup({ value, defaultValue, onValueChange, multiple, orientation, disabled, label, className, children }: {
|
|
99
117
|
value?: string[];
|
|
100
118
|
defaultValue?: string[];
|
package/dist/actions.js
CHANGED
|
@@ -9,7 +9,7 @@ import { useValorResponsivo } from "./responsivo-runtime.js";
|
|
|
9
9
|
import { Toolbar as BaseToolbar } from "@base-ui/react/toolbar";
|
|
10
10
|
import { Toggle as BaseToggle } from "@base-ui/react/toggle";
|
|
11
11
|
import { ToggleGroup as BaseToggleGroup } from "@base-ui/react/toggle-group";
|
|
12
|
-
import { cx, useAureaStrings } from "./internal.js";
|
|
12
|
+
import { cx, useAureaStrings, DentroDoProviderContext, avisosAncorados } from "./internal.js";
|
|
13
13
|
import { Kbd } from "./markup.js";
|
|
14
14
|
import { Icon, useAureaTheme } from "./system.js";
|
|
15
15
|
// O dicionário que desachata o enum. É a ÚNICA fonte da correspondência: o gate do
|
|
@@ -42,10 +42,58 @@ export function buttonSkin(variant, appearance, tone) {
|
|
|
42
42
|
const antiga = CLASSE_ANTIGA.get(`${a}/${t}`);
|
|
43
43
|
return antiga ? `btn-${antiga}` : cx(`btn-${a}`, `btn-tone-${t}`);
|
|
44
44
|
}
|
|
45
|
+
// GAR-14 (0.28.0) · o compartilhar do `Button`, a contraparte React do `share` do `aurea.js` — a mesma
|
|
46
|
+
// regra nos dois: detectar o recurso; `AbortError` (a pessoa cancelou) não diz nada; sem o recurso,
|
|
47
|
+
// copiar e avisar preso ao botão; a cópia falhou, avisar e mostrar o link. Fora do `AureaProvider`, o
|
|
48
|
+
// aviso é do `aurea.js`, quando ele está na página; sem nenhum dos dois, o botão ainda compartilha e
|
|
49
|
+
// copia, mas não tem como avisar — e diz isso uma vez no console, em vez de ficar mudo.
|
|
50
|
+
let avisouSemProvider = false;
|
|
51
|
+
async function compartilhar(botao, dados, s, dentroDoProvider) {
|
|
52
|
+
const url = dados.url ?? window.location.href;
|
|
53
|
+
const pacote = { url, ...(dados.title ? { title: dados.title } : null), ...(dados.text ? { text: dados.text } : null) };
|
|
54
|
+
const vanilla = window.Aurea;
|
|
55
|
+
if (!dentroDoProvider && vanilla?.share) {
|
|
56
|
+
vanilla.share(botao);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const avisar = (falhou) => {
|
|
60
|
+
if (!dentroDoProvider) {
|
|
61
|
+
if (!avisouSemProvider) {
|
|
62
|
+
avisouSemProvider = true;
|
|
63
|
+
console.error("Aurea: o <Button share> copiou o link, mas não tem como avisar — ponha o <AureaProvider> em volta do app (ou carregue o aurea.js na página).");
|
|
64
|
+
}
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// A distância do botão é a mesma do `Tooltip` e do `Popover` (8 = `--space-2`).
|
|
68
|
+
avisosAncorados.add({ title: falhou ? s.linkCopyFailed : s.linkCopied, type: falhou ? "danger" : "success",
|
|
69
|
+
timeout: falhou ? 0 : 1500, data: { url: falhou ? url : undefined },
|
|
70
|
+
positionerProps: { anchor: botao, side: "bottom", align: "start", sideOffset: 8 } });
|
|
71
|
+
};
|
|
72
|
+
const sabeCompartilhar = typeof navigator.share === "function" && (typeof navigator.canShare !== "function" || navigator.canShare(pacote));
|
|
73
|
+
if (sabeCompartilhar) {
|
|
74
|
+
try {
|
|
75
|
+
await navigator.share(pacote);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
if (e?.name === "AbortError")
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
if (typeof navigator.clipboard?.writeText !== "function")
|
|
85
|
+
throw new Error("sem área de transferência");
|
|
86
|
+
await navigator.clipboard.writeText(url);
|
|
87
|
+
avisar(false);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
avisar(true);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
45
93
|
// type="button" por default: o default do HTML é submit, e um "Cancelar"/"Remover"
|
|
46
94
|
// dentro de <form> dispararia a ação principal (auditoria 18/07/2026, ALTO 1).
|
|
47
95
|
// Quem quer submeter passa type="submit" explícito (como o MessageComposer faz).
|
|
48
|
-
export const Button = forwardRef(function Button({ variant, appearance, tone, size = "md", loading, leadingIcon, trailingIcon, className, children, disabled, type = "button", href, fullWidth, grow, target, rel, download, pressed, kbd, onClick, onClickCapture, "aria-disabled": ariaDisabled, render, ...props }, ref) {
|
|
96
|
+
export const Button = forwardRef(function Button({ variant, appearance, tone, size = "md", loading, leadingIcon, trailingIcon, className, children, disabled, type = "button", href, fullWidth, grow, target, rel, download, pressed, kbd, onClick, onClickCapture, "aria-disabled": ariaDisabled, render, share, ...props }, ref) {
|
|
49
97
|
// G-AXIS-04 — `size` aceita valor simples, responsivo por viewport ou adaptativo por container.
|
|
50
98
|
// SOMATIVO por construção: valor simples continua emitindo `btn-sm`, byte por byte a mesma classe
|
|
51
99
|
// de antes, e por isso nenhuma baseline se mexe. Só o valor responsivo entra pela camada genérica
|
|
@@ -74,6 +122,21 @@ export const Button = forwardRef(function Button({ variant, appearance, tone, si
|
|
|
74
122
|
const inerte = ariaDisabled === true || ariaDisabled === "true";
|
|
75
123
|
const off = disabled || loading;
|
|
76
124
|
const shared = { "aria-keyshortcuts": kbd || undefined, "aria-busy": loading || undefined };
|
|
125
|
+
// GAR-14: o `share` emite a mesma marcação que o `aurea.js` lê ([data-aurea-share]) — o catálogo
|
|
126
|
+
// estático não hidrata, e é ela que faz o botão funcionar lá. Os textos vão junto, na língua do app.
|
|
127
|
+
const s = useAureaStrings();
|
|
128
|
+
const dentroDoProvider = React.useContext(DentroDoProviderContext);
|
|
129
|
+
const marcaDoShare = share ? { "data-aurea-share": "", "data-aurea-share-url": share.url, "data-aurea-share-title": share.title,
|
|
130
|
+
"data-aurea-share-text": share.text, "data-aurea-share-copied": s.linkCopied, "data-aurea-share-failed": s.linkCopyFailed } : undefined;
|
|
131
|
+
// O clique do app roda primeiro; se ele cancelar (`preventDefault`), o botão não compartilha. O
|
|
132
|
+
// `preventDefault` daqui avisa o `aurea.js` de que o clique já foi atendido.
|
|
133
|
+
const aoClicarNoShare = share ? (e) => {
|
|
134
|
+
onClick?.(e);
|
|
135
|
+
if (e.defaultPrevented)
|
|
136
|
+
return;
|
|
137
|
+
e.preventDefault();
|
|
138
|
+
void compartilhar(e.currentTarget, share, s, dentroDoProvider);
|
|
139
|
+
} : onClick;
|
|
77
140
|
// AUD-0004 (12/08/2026): o ramo de LINK desabilitado tirava o `href` e punha `aria-disabled`, e
|
|
78
141
|
// deixava o `onClick` passar intacto — então um link "desabilitado" continuava executando a ação
|
|
79
142
|
// ao ser clicado, e o `loading` também. Não há `disabled` em `<a>`: quem tem de barrar a ativação
|
|
@@ -92,7 +155,7 @@ export const Button = forwardRef(function Button({ variant, appearance, tone, si
|
|
|
92
155
|
}
|
|
93
156
|
if (href !== undefined)
|
|
94
157
|
return _jsx("a", { ref: ref, className: cls, target: target, rel: rel, download: download, ...shared, ...props, ...(off ? { "aria-disabled": true } : { href }), ...eventos, children: inner });
|
|
95
|
-
return _jsx("button", { ref: ref, type: type, className: cls, disabled: off, "aria-disabled": inerte || undefined, "aria-pressed": pressed, ...shared, ...(inerte ? { onClick: bloqueia, onClickCapture: bloqueia } : { onClick, onClickCapture }), ...props, children: inner });
|
|
158
|
+
return _jsx("button", { ref: ref, type: type, className: cls, disabled: off, "aria-disabled": inerte || undefined, "aria-pressed": pressed, ...shared, ...marcaDoShare, ...(inerte ? { onClick: bloqueia, onClickCapture: bloqueia } : { onClick: aoClicarNoShare, onClickCapture }), ...props, children: inner });
|
|
96
159
|
});
|
|
97
160
|
function temConteudoVisivel(children) {
|
|
98
161
|
const itens = React.Children.toArray(children);
|
package/dist/code-client.d.ts
CHANGED
package/dist/code-client.js
CHANGED
|
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
// Fase 9 (achado A5): este arquivo saiu do index.tsx de 970 linhas. Um módulo por categoria
|
|
4
4
|
// do registry — a taxonomia já existia e é gateada. A ordem de import entre eles é um DAG:
|
|
5
5
|
// internal → system → actions → feedback → inputs → navigation → layout → data-display → resto.
|
|
6
|
+
import React from "react";
|
|
6
7
|
import { cx, useAureaStrings } from "./internal.js";
|
|
7
8
|
import { Icon } from "./system.js";
|
|
8
9
|
// copyable: o gatilho é marcado com data-aurea-copy e o COMPORTAMENTO mora no aurea.js do
|
|
@@ -19,6 +20,21 @@ export function CodeBlock({ children, language = "text", copyable, className })
|
|
|
19
20
|
const pre = _jsx("pre", { className: cx("code-block", !copyable && className), "data-language": language, tabIndex: 0, children: _jsx("code", { children: children }) });
|
|
20
21
|
if (!copyable)
|
|
21
22
|
return pre;
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
// 0.28.0: o "copiado" é dito ao leitor de tela. Com o `aurea.js` na página, é ele quem diz (pelo
|
|
24
|
+
// texto do `data-aurea-copy-done`, na língua do app); sem ele, a região de status daqui.
|
|
25
|
+
const [copiado, setCopiado] = React.useState(false);
|
|
26
|
+
const onCopy = (e) => {
|
|
27
|
+
e.stopPropagation();
|
|
28
|
+
const vanilla = window.Aurea;
|
|
29
|
+
if (vanilla?.copy) {
|
|
30
|
+
vanilla.copy(e.currentTarget);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
// Sem área de transferência (ou sem promessa), não há o que avisar — e não pode quebrar o clique.
|
|
34
|
+
const copia = navigator.clipboard?.writeText(children);
|
|
35
|
+
if (typeof copia?.then !== "function")
|
|
36
|
+
return;
|
|
37
|
+
void copia.then(() => { setCopiado(true); setTimeout(() => setCopiado(false), 1500); }, () => { });
|
|
38
|
+
};
|
|
39
|
+
return _jsxs("div", { className: cx("code-block-wrap", className), "data-aurea-copy-scope": true, children: [_jsx("span", { className: "sr-only", role: "status", "aria-live": "polite", children: copiado ? s.copied : "" }), _jsxs("button", { type: "button", className: cx("btn btn-icon btn-ghost copy-code", copiado && "is-done"), "data-aurea-copy": true, "data-aurea-copy-done": s.copied, "aria-label": s.copyCode, onClick: onCopy, children: [_jsx(Icon, { name: "copy", size: "sm", className: "c-copy" }), _jsx(Icon, { name: "check", size: "sm", className: "c-done" })] }), pre] });
|
|
24
40
|
}
|
package/dist/data-display.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from "./data-display-client.js";
|
|
2
|
-
export { Kbd, KPI, DataList, Timeline, Prose, Text, Heading, Paragraph, Code, type TextProps, type HeadingProps, type ParagraphProps, type CodeProps, type TypographyType, type TypographyColor, type TypographyWeight, type TypographyAlign, type HeadingLevel, type ParagraphSize } from "./markup.js";
|
|
2
|
+
export { Kbd, KPI, DataList, Timeline, Prose, Text, Heading, Paragraph, Code, type KPIProps, type KPIDirection, type KPITone, type KPIVariant, type TextProps, type HeadingProps, type ParagraphProps, type CodeProps, type TypographyType, type TypographyColor, type TypographyWeight, type TypographyAlign, type HeadingLevel, type ParagraphSize } from "./markup.js";
|
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 BadgeEmphasis, type BadgeSize, type BadgePlacement, type BadgeProps, type ProgressProps, type ProgressTone } from "./markup.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";
|
package/dist/file-input.js
CHANGED
|
@@ -285,5 +285,10 @@ export function FileInput({ accept, maxSize, multiple, onFilesChange, upload, la
|
|
|
285
285
|
// pelos docs não altera baseline — a justificativa antiga estava invertida).
|
|
286
286
|
const pct = Math.round(progress * 100);
|
|
287
287
|
return _jsxs("li", { className: "file-item", children: [previa ? _jsx("img", { className: "file-thumb", src: previa, alt: "" }) : _jsx(Icon, { name: "file-text" }), _jsx("span", { className: "file-name", children: name }), status === "uploading" ? _jsxs(_Fragment, { children: [_jsx("div", { className: "progress file-progress", role: "progressbar", "aria-label": `${s.uploadSending} ${name}`, "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": pct, children: _jsx("span", { style: { width: `${pct}%` } }) }), _jsx(IconButton, { variant: "ghost", size: "sm", icon: "pause", label: `${s.uploadPause} ${name}`, onClick: () => pausar(id) }), _jsx(IconButton, { variant: "ghost", size: "sm", icon: "x", label: `${s.uploadCancel} ${name}`, onClick: () => abortId(id) })] }) : status === "paused" ? _jsxs(_Fragment, { children: [_jsxs("span", { className: "file-size", children: [s.uploadPaused, " \u00B7 ", Math.round(progress * 100), "%"] }), _jsx(IconButton, { variant: "ghost", size: "sm", icon: "play", label: `${s.uploadResume} ${name}`, onClick: () => retomar({ id, file, name, bytes, status, progress, restored }) }), _jsx(IconButton, { variant: "ghost", size: "sm", icon: "x", label: `${s.fileRemove} ${name}`, onClick: () => remove(id) })] }) : (status === "error" || status === "canceled") ? _jsxs(_Fragment, { children: [_jsx("span", { className: "field-error", children: erro ?? (status === "error" ? s.uploadError : s.uploadCanceled) }), file && _jsx(IconButton, { variant: "ghost", size: "sm", icon: "arrow-counter-clockwise", label: `${s.uploadRetry} ${name}`, onClick: () => startUpload(id, file) }), _jsx(IconButton, { variant: "ghost", size: "sm", icon: "x", label: `${s.fileRemove} ${name}`, onClick: () => remove(id) })] }) : _jsxs(_Fragment, { children: [status === "done" && _jsx(Icon, { name: "check-circle", weight: "fill" }), _jsx("span", { className: "file-size", children: formatSize(bytes) }), soma && _jsx("span", { className: "file-checksum", title: `${s.uploadChecksum}: ${soma}`, children: soma.slice(0, 8) }), _jsx(IconButton, { variant: "ghost", size: "sm", icon: "x", label: `${s.fileRemove} ${name}`, onClick: () => remove(id) })] })] }, id);
|
|
288
|
-
}) }), conflitos.map((c, i) => _jsxs("div", { className: "file-conflict", role: "alert", children: [_jsxs("span", { children: [s.fileConflict, ": ", _jsx("strong", { children: c.file.name })] }), _jsx(Button, { size: "sm", variant: "secondary", onClick: () => resolverConflito(i, "replace"), children: s.fileReplace }), _jsx(Button, { size: "sm", variant: "secondary", onClick: () => resolverConflito(i, "both"), children: s.fileKeepBoth }), _jsx(Button, { size: "sm", variant: "ghost", onClick: () => resolverConflito(i, "skip"), children: s.fileSkip })] }, `c${i}`)), recibo.length > 0 && !emVoo && _jsxs("div", { className: "file-receipt", children: [_jsxs("div", { className: "file-receipt-head", children: [_jsx("strong", { children: s.uploadReceipt }), _jsx(Button, { size: "sm", variant: "ghost", leadingIcon: "copy", onClick: () =>
|
|
288
|
+
}) }), conflitos.map((c, i) => _jsxs("div", { className: "file-conflict", role: "alert", children: [_jsxs("span", { children: [s.fileConflict, ": ", _jsx("strong", { children: c.file.name })] }), _jsx(Button, { size: "sm", variant: "secondary", onClick: () => resolverConflito(i, "replace"), children: s.fileReplace }), _jsx(Button, { size: "sm", variant: "secondary", onClick: () => resolverConflito(i, "both"), children: s.fileKeepBoth }), _jsx(Button, { size: "sm", variant: "ghost", onClick: () => resolverConflito(i, "skip"), children: s.fileSkip })] }, `c${i}`)), recibo.length > 0 && !emVoo && _jsxs("div", { className: "file-receipt", children: [_jsxs("div", { className: "file-receipt-head", children: [_jsx("strong", { children: s.uploadReceipt }), _jsx(Button, { size: "sm", variant: "ghost", leadingIcon: "copy", onClick: () => {
|
|
289
|
+
const copia = navigator.clipboard?.writeText(reciboTexto);
|
|
290
|
+
if (typeof copia?.then !== "function")
|
|
291
|
+
return;
|
|
292
|
+
void copia.then(() => { setAnnounce(""); setTimeout(() => setAnnounce(s.copied), 100); }, () => { });
|
|
293
|
+
}, children: s.uploadReceiptCopy })] }), _jsx("ul", { children: recibo.map(r => _jsxs("li", { children: [r.name, " \u00B7 ", r.status === "done" ? s.uploadComplete : r.status === "canceled" ? s.uploadCanceled : s.uploadError, r.finishedAt ? ` · ${r.finishedAt}` : ""] }, r.id)) })] }), rejected.map((r, n) => _jsxs("span", { id: `${inputId}-rejeitado-${n}`, className: "field-error", children: [r.reason, ": ", r.file.name] }, n)), _jsx("span", { className: "sr-only", role: "status", "aria-live": "polite", children: announce })] });
|
|
289
294
|
}
|
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, AvatarGroup, LogStream, MediaPlayerShell, Header, Topbar, Kbd, Textarea, Checkbox, Radio, Switch, Range, formatBadgeCount, type BadgeVariant, type BadgeEmphasis, type BadgeSize, type BadgePlacement, type BadgeProps, type ProgressProps, type ProgressTone, type AvatarSize, type HeaderVariant, type HeaderProps, type TopbarVariant, type SectionVariant, type SectionFooterGroup, type TextProps, type HeadingProps, type ParagraphProps, type CodeProps, type TypographyType, type TypographyColor, type TypographyWeight, type TypographyAlign, type HeadingLevel, type ParagraphSize } from "./markup.js";
|
|
5
|
+
export { AspectRatio, InputGroup, InputGroupAddon, Label, Card, Stack, Cluster, Grid, Container, Section, KPI, DataList, Timeline, Prose, Text, Heading, Paragraph, Code, Badge, Progress, Skeleton, AvatarGroup, LogStream, MediaPlayerShell, Header, Topbar, Kbd, Textarea, Checkbox, Radio, Switch, Range, formatBadgeCount, type BadgeVariant, type 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 TextProps, type HeadingProps, type ParagraphProps, type CodeProps, type TypographyType, type TypographyColor, type TypographyWeight, type TypographyAlign, type HeadingLevel, type ParagraphSize } from "./markup.js";
|
|
6
6
|
export * from "./system.js";
|
|
7
7
|
export * from "./actions.js";
|
|
8
8
|
export * from "./feedback.js";
|
package/dist/internal.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ export declare const useDensity: () => {
|
|
|
27
27
|
setDensity: (d: AureaDensity) => void;
|
|
28
28
|
};
|
|
29
29
|
export declare const DentroDoProviderContext: React.Context<boolean>;
|
|
30
|
+
export declare const avisosAncorados: import("@base-ui/react").ToastManager<any>;
|
|
30
31
|
export declare const PortalContext: React.Context<HTMLElement | null | undefined>;
|
|
31
32
|
export declare const usePortalContainer: () => HTMLElement | null | undefined;
|
|
32
33
|
export interface Reordenavel<E extends HTMLElement> {
|
package/dist/internal.js
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
// Kbd mora aqui por dependência, não por categoria: o Button precisa dele e ele não precisa de
|
|
16
16
|
// ninguém. A casa pública dele continua sendo `/data-display`, que o reexporta.
|
|
17
17
|
import { createContext, useContext, useEffect, useRef, useState } from "react";
|
|
18
|
+
import { Toast as BaseToast } from "@base-ui/react/toast";
|
|
18
19
|
import { defaultStrings, defaultSpriteUrl } from "./pure.js";
|
|
19
20
|
export { cx, fundirRender, defaultStrings, ptBR, defaultSpriteUrl, universalStates, stateSeverity } from "./pure.js";
|
|
20
21
|
export const StringsContext = createContext(defaultStrings);
|
|
@@ -59,6 +60,10 @@ export const useDensity = () => useContext(DensityContext);
|
|
|
59
60
|
// NÃO distingue "sem provider" de "provider que ainda não adotou tema". Só um booleano que
|
|
60
61
|
// apenas o provider fornece distingue.
|
|
61
62
|
export const DentroDoProviderContext = createContext(false);
|
|
63
|
+
// GAR-14 (0.28.0): o gerenciador dos avisos PRESOS a um botão (o "Link copiado" do `Button share`).
|
|
64
|
+
// Separado do da pilha, como a documentação do motor manda; o hospedeiro é o `AvisosAncorados` do
|
|
65
|
+
// `system.tsx`, montado pelo `AureaProvider` de fora. Mora aqui para não sair no barril público.
|
|
66
|
+
export const avisosAncorados = BaseToast.createToastManager();
|
|
62
67
|
export const PortalContext = createContext(undefined);
|
|
63
68
|
export const usePortalContainer = () => useContext(PortalContext);
|
|
64
69
|
export function useReorder({ count, order, onReorder, rowSelector, handleSelector }) {
|
package/dist/markup.d.ts
CHANGED
|
@@ -2,7 +2,8 @@ import React, { type HTMLAttributes, type InputHTMLAttributes, type ReactElement
|
|
|
2
2
|
import { type Responsive } from "./pure.js";
|
|
3
3
|
import type { ComponentSize } from "./actions.js";
|
|
4
4
|
import type { SidebarItem } from "./navigation-client.js";
|
|
5
|
-
export type
|
|
5
|
+
export type BadgeCategory = "red" | "orange" | "green" | "teal" | "cyan" | "blue" | "violet" | "pink";
|
|
6
|
+
export type BadgeVariant = "neutral" | "primary" | "info" | "success" | "warning" | "danger" | "running" | "paused" | "offline" | "review" | BadgeCategory;
|
|
6
7
|
export type AvatarSize = "sm" | "md" | "lg";
|
|
7
8
|
export type HeaderVariant = "floating" | "flush" | "pill";
|
|
8
9
|
/** @deprecated `Topbar` é o nome antigo do `Header` (07/10/2026). O tipo continua valendo; use `HeaderVariant`. */
|
|
@@ -141,11 +142,24 @@ export interface SectionProps extends HTMLAttributes<HTMLElement>, RefAttributes
|
|
|
141
142
|
* quando ela for uma região que o leitor de tela deva listar.
|
|
142
143
|
*/
|
|
143
144
|
export declare function Section({ surface, spacing, theme, variant, brand, links, legal, maxWidth, navLabel, children, className, ...props }: SectionProps): React.JSX.Element;
|
|
144
|
-
export
|
|
145
|
+
export type KPIDirection = "up" | "down" | "flat";
|
|
146
|
+
export type KPITone = "success" | "danger" | "neutral";
|
|
147
|
+
export type KPIVariant = "card" | "plain";
|
|
148
|
+
export interface KPIProps extends HTMLAttributes<HTMLDivElement>, RefAttributes<HTMLDivElement> {
|
|
145
149
|
label: ReactNode;
|
|
146
150
|
value: ReactNode;
|
|
151
|
+
/** A mudança, como texto do domínio ("+8% no mês"). */
|
|
147
152
|
trend?: ReactNode;
|
|
148
|
-
|
|
153
|
+
/** Para onde foi. Desenha a seta, pinta a tendência e diz a palavra ao leitor de tela. */
|
|
154
|
+
direction?: KPIDirection;
|
|
155
|
+
/** A cor da tendência. Padrão: alta = `success`, baixa = `danger`, estável = `neutral`. */
|
|
156
|
+
tone?: KPITone;
|
|
157
|
+
/** A palavra que o leitor de tela ouve antes da tendência. Padrão em inglês: "Up", "Down", "No change". */
|
|
158
|
+
directionLabel?: string;
|
|
159
|
+
/** `plain` tira a caixa: o número dentro de um cartão que já existe. */
|
|
160
|
+
variant?: KPIVariant;
|
|
161
|
+
}
|
|
162
|
+
export declare function KPI({ label, value, trend, direction, tone, directionLabel, variant, className, ...props }: KPIProps): React.JSX.Element;
|
|
149
163
|
export declare function DataList({ items }: {
|
|
150
164
|
items: Array<{
|
|
151
165
|
term: ReactNode;
|
|
@@ -162,7 +176,7 @@ export declare function Timeline({ items }: {
|
|
|
162
176
|
export declare function Prose({ className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>): React.JSX.Element;
|
|
163
177
|
export type TypographyType = "body" | "body-sm" | "body-xs" | "code" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
|
|
164
178
|
export type TypographyColor = "default" | "muted";
|
|
165
|
-
export type TypographyWeight = "normal" | "medium" | "semibold" | "bold";
|
|
179
|
+
export type TypographyWeight = "normal" | "medium" | "semibold" | "bold" | "extrabold";
|
|
166
180
|
export type TypographyAlign = "start" | "center" | "end" | "justify";
|
|
167
181
|
export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
168
182
|
export type ParagraphSize = "base" | "sm" | "xs";
|
|
@@ -171,19 +185,22 @@ interface TypographyBase {
|
|
|
171
185
|
color?: TypographyColor;
|
|
172
186
|
weight?: TypographyWeight;
|
|
173
187
|
truncate?: boolean;
|
|
188
|
+
/** GAR-16 (0.28.0): algarismos da mesma largura — para número que alinha em coluna (preço, ano,
|
|
189
|
+
* ficha técnica) ou que muda na tela. Desligado por padrão: no texto corrido o "1" estreito é o certo. */
|
|
190
|
+
numeric?: boolean;
|
|
174
191
|
}
|
|
175
192
|
export interface TextProps extends Omit<HTMLAttributes<HTMLSpanElement>, "color">, RefAttributes<HTMLSpanElement>, TypographyBase {
|
|
176
193
|
type?: TypographyType;
|
|
177
194
|
}
|
|
178
|
-
export declare function Text({ type, align, color, weight, truncate, className, ...props }: TextProps): React.JSX.Element;
|
|
195
|
+
export declare function Text({ type, align, color, weight, truncate, numeric, className, ...props }: TextProps): React.JSX.Element;
|
|
179
196
|
export interface HeadingProps extends Omit<HTMLAttributes<HTMLHeadingElement>, "color">, RefAttributes<HTMLHeadingElement>, TypographyBase {
|
|
180
197
|
level?: HeadingLevel;
|
|
181
198
|
}
|
|
182
|
-
export declare function Heading({ level, align, color, weight, truncate, className, ...props }: HeadingProps): React.JSX.Element;
|
|
199
|
+
export declare function Heading({ level, align, color, weight, truncate, numeric, className, ...props }: HeadingProps): React.JSX.Element;
|
|
183
200
|
export interface ParagraphProps extends Omit<HTMLAttributes<HTMLParagraphElement>, "color">, RefAttributes<HTMLParagraphElement>, TypographyBase {
|
|
184
201
|
size?: ParagraphSize;
|
|
185
202
|
}
|
|
186
|
-
export declare function Paragraph({ size, align, color, weight, truncate, className, ...props }: ParagraphProps): React.JSX.Element;
|
|
203
|
+
export declare function Paragraph({ size, align, color, weight, truncate, numeric, className, ...props }: ParagraphProps): React.JSX.Element;
|
|
187
204
|
export interface CodeProps extends Omit<HTMLAttributes<HTMLElement>, "color">, RefAttributes<HTMLElement>, TypographyBase {
|
|
188
205
|
}
|
|
189
206
|
export declare function Code({ align, color, weight, truncate, className, ...props }: CodeProps): React.JSX.Element;
|
package/dist/markup.js
CHANGED
|
@@ -88,8 +88,14 @@ export function Section({ surface = "background", spacing = "md", theme, variant
|
|
|
88
88
|
? fundirRender(it.render, { className: "section-footer-link", children: it.label }, "a")
|
|
89
89
|
: _jsx("a", { className: "section-footer-link", href: it.href, children: it.label }) }, it.id)) })] }, n)) }), children] }), legal != null && _jsx("div", { className: "section-footer-legal", children: legal })] }) });
|
|
90
90
|
}
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
const TOM_DA_DIRECAO = { up: "success", down: "danger", flat: "neutral" };
|
|
92
|
+
const PALAVRA_DA_DIRECAO = { up: "Up", down: "Down", flat: "No change" };
|
|
93
|
+
export function KPI({ label, value, trend, direction, tone, directionLabel, variant = "card", className, ...props }) {
|
|
94
|
+
const tom = direction ? (tone ?? TOM_DA_DIRECAO[direction]) : undefined;
|
|
95
|
+
const miolo = _jsxs(_Fragment, { children: [_jsx("span", { className: "muted", children: label }), _jsx("strong", { children: value }), (trend || trend === 0 || direction) && _jsxs("small", { className: direction ? cx("kpi-trend", `kpi-trend-${direction}`, `kpi-tone-${tom}`) : undefined, children: [direction && _jsx("span", { className: "kpi-trend-icon", "aria-hidden": "true" }), direction && _jsx("span", { className: "sr-only", children: directionLabel ?? PALAVRA_DA_DIRECAO[direction] }), trend] })] });
|
|
96
|
+
return variant === "plain" ? _jsx("div", { className: cx("kpi", className), ...props, children: miolo })
|
|
97
|
+
: _jsx(Card, { className: cx("kpi", className), ...props, children: miolo });
|
|
98
|
+
}
|
|
93
99
|
export function DataList({ items }) { return _jsx("dl", { className: "data-list", children: items.map((i, n) => _jsxs(React.Fragment, { children: [_jsx("dt", { children: i.term }), _jsx("dd", { children: i.value })] }, n)) }); }
|
|
94
100
|
export function Timeline({ items }) { return _jsx("ol", { className: "timeline", children: items.map((i, n) => _jsxs("li", { children: [_jsx("span", { className: "timeline-dot" }), _jsxs("div", { children: [_jsx("strong", { children: i.title }), i.description && _jsx("p", { children: i.description }), i.time && _jsx("small", { className: "muted", children: i.time })] })] }, n)) }); }
|
|
95
101
|
// Prose (item L5): UMA LINHA, e é para ser mesmo — quem transforma Markdown em elementos é o
|
|
@@ -98,11 +104,11 @@ export function Timeline({ items }) { return _jsx("ol", { className: "timeline",
|
|
|
98
104
|
// `dangerouslySetInnerHTML` tem de SANITIZAR antes. A Aurea desenha o texto; ela não pode decidir
|
|
99
105
|
// o que é seguro renderizar. Está dito na ficha, em voz alta.
|
|
100
106
|
export function Prose({ className, ...props }) { return _jsx("div", { className: cx("prose", className), ...props }); }
|
|
101
|
-
const tipografia = (tipo, { align, color, weight, truncate }, className) => cx("typography", `typography-${tipo}`, color === "muted" && "typography-muted", weight && `typography-weight-${weight}`, align && `typography-align-${align}`, truncate && "typography-truncate", className);
|
|
102
|
-
export function Text({ type = "body", align, color, weight, truncate, className, ...props }) { return _jsx("span", { className: tipografia(type, { align, color, weight, truncate }, className), ...props }); }
|
|
107
|
+
const tipografia = (tipo, { align, color, weight, truncate, numeric }, className) => cx("typography", `typography-${tipo}`, color === "muted" && "typography-muted", weight && `typography-weight-${weight}`, align && `typography-align-${align}`, truncate && "typography-truncate", numeric && "typography-numeric", className);
|
|
108
|
+
export function Text({ type = "body", align, color, weight, truncate, numeric, className, ...props }) { return _jsx("span", { className: tipografia(type, { align, color, weight, truncate, numeric }, className), ...props }); }
|
|
103
109
|
// O nível decide o elemento E o tamanho, como na referência: um `h2` tem a cara de título 2.
|
|
104
|
-
export function Heading({ level = 1, align, color, weight, truncate, className, ...props }) { const Tag = `h${level}`; return _jsx(Tag, { className: tipografia(`h${level}`, { align, color, weight, truncate }, className), ...props }); }
|
|
105
|
-
export function Paragraph({ size = "base", align, color, weight, truncate, className, ...props }) { return _jsx("p", { className: tipografia(size === "base" ? "body" : `body-${size}`, { align, color, weight, truncate }, className), ...props }); }
|
|
110
|
+
export function Heading({ level = 1, align, color, weight, truncate, numeric, className, ...props }) { const Tag = `h${level}`; return _jsx(Tag, { className: tipografia(`h${level}`, { align, color, weight, truncate, numeric }, className), ...props }); }
|
|
111
|
+
export function Paragraph({ size = "base", align, color, weight, truncate, numeric, className, ...props }) { return _jsx("p", { className: tipografia(size === "base" ? "body" : `body-${size}`, { align, color, weight, truncate, numeric }, className), ...props }); }
|
|
106
112
|
export function Code({ align, color, weight, truncate, className, ...props }) { return _jsx("code", { className: tipografia("code", { align, color, weight, truncate }, className), ...props }); }
|
|
107
113
|
// `max` com `+` é o idioma universal do contador (três das referências o usam). Exportada porque quem
|
|
108
114
|
// escreve o nome acessível precisa do MESMO texto — "99+ unread" tem de bater com o que se vê.
|
package/dist/media-client.d.ts
CHANGED
|
@@ -25,8 +25,16 @@ export interface ImageProps extends Omit<React.ImgHTMLAttributes<HTMLImageElemen
|
|
|
25
25
|
ratio?: string;
|
|
26
26
|
fit?: "cover" | "contain";
|
|
27
27
|
render?: React.ReactElement;
|
|
28
|
+
/** GAR-15 (0.28.0): a captura dentro de uma moldura de celular — GENÉRICA, sem ilha, entalhe nem
|
|
29
|
+
* botões (as regras de marketing de um fabricante proíbem simular o aparelho dele, e a Aurea não
|
|
30
|
+
* leva marca de terceiro). Com moldura, `className` e `style` vão para a MOLDURA (tamanho e lugar);
|
|
31
|
+
* a proporção (`ratio`, padrão 9/19,5) vai para a captura. */
|
|
32
|
+
frame?: "phone";
|
|
33
|
+
/** GAR-15 (0.28.0): a captura do tema escuro. A página em `data-theme="dark"` mostra esta; no claro,
|
|
34
|
+
* a de `src`. A que não aparece fica `display:none`, fora da árvore de acessibilidade. */
|
|
35
|
+
srcDark?: string;
|
|
28
36
|
}
|
|
29
|
-
export declare function Image({ ratio, fit, alt, className, style, render, onError, ...props }: ImageProps): React.JSX.Element;
|
|
37
|
+
export declare function Image({ ratio, fit, alt, className, style, render, onError, frame, srcDark, ...props }: ImageProps): React.JSX.Element;
|
|
30
38
|
export type GalleryItemKind = "image" | "video";
|
|
31
39
|
export interface GalleryItem {
|
|
32
40
|
id: string;
|
package/dist/media-client.js
CHANGED
|
@@ -123,13 +123,17 @@ export function MediaEmbed({ src, title, poster, ratio = "16/9", href, autoplay
|
|
|
123
123
|
? _jsx("iframe", { ref: frameRef, src: endereco, title: title, loading: "lazy", referrerPolicy: "strict-origin-when-cross-origin", allow: "autoplay; encrypted-media; fullscreen; picture-in-picture", allowFullScreen: true, ...rest })
|
|
124
124
|
: _jsxs("button", { type: "button", className: "media-embed-facade", "aria-label": `${s.mediaPlay}: ${title}`, onClick: () => { setAtivo(true); setClicou(true); }, children: [_jsx("img", { src: poster, alt: "", loading: "lazy", decoding: "async" }), _jsx("span", { className: "media-embed-play", "aria-hidden": "true", children: _jsx(Icon, { name: "play-circle", weight: "fill" }) })] }) }), href && _jsxs("a", { className: "media-embed-link", href: href, target: "_blank", rel: "noopener", children: [_jsx(Icon, { name: "arrow-square-out" }), s.mediaEmbedOpen] })] });
|
|
125
125
|
}
|
|
126
|
-
export function Image({ ratio, fit, alt, className, style, render, onError, ...props }) {
|
|
126
|
+
export function Image({ ratio, fit, alt, className, style, render, onError, frame, srcDark, ...props }) {
|
|
127
127
|
const [quebrou, setQuebrou] = React.useState(false);
|
|
128
128
|
// A proporção vai INLINE e só quando existe. Declará-la no core com fallback `auto` custou uma
|
|
129
129
|
// medição em 15/08/2026: `auto` vence o `aspect-ratio: auto <width>/<height>` que o navegador
|
|
130
130
|
// deriva dos atributos, e uma imagem com `width`/`height` e sem `ratio` saía com altura ZERO —
|
|
131
131
|
// a regra escrita contra o salto de layout produzindo o salto. Sem prop, o navegador decide.
|
|
132
132
|
const estilo = { ...(ratio ? { aspectRatio: ratio } : null), ...style };
|
|
133
|
+
// Com moldura, o `style` e a classe do consumidor vão para ela; a captura fica só com a proporção.
|
|
134
|
+
const daImagem = frame ? (ratio ? { aspectRatio: ratio } : undefined) : estilo;
|
|
135
|
+
const classeDaImagem = (tema) => cx("image", fit === "contain" && "image-contain", srcDark && tema && `image-theme-${tema}`, !frame && className);
|
|
136
|
+
const aoFalhar = (e) => { setQuebrou(true); onError?.(e); };
|
|
133
137
|
// O hook roda SEMPRE, antes de qualquer saída antecipada — trocar a ordem dos hooks entre
|
|
134
138
|
// renders é o que o React proíbe, e o ramo do erro é uma saída antecipada.
|
|
135
139
|
const elemento = useRender({ defaultTagName: "img", render,
|
|
@@ -137,13 +141,20 @@ export function Image({ ratio, fit, alt, className, style, render, onError, ...p
|
|
|
137
141
|
// reprovou: escritos depois, `loading="eager"` numa imagem de topo de página era engolido pelo
|
|
138
142
|
// nosso `lazy` — o componente prometia default e entregava imposição.
|
|
139
143
|
props: { loading: "lazy", decoding: "async", ...props, alt,
|
|
140
|
-
className:
|
|
141
|
-
|
|
144
|
+
className: classeDaImagem("light"), style: daImagem, onError: aoFalhar } });
|
|
145
|
+
// A captura do escuro é o MESMO elemento com outra fonte — o hook roda sempre (a ordem dos hooks
|
|
146
|
+
// não pode mudar entre renders) e só sai na página quando há `srcDark`.
|
|
147
|
+
const escuro = useRender({ defaultTagName: "img", render,
|
|
148
|
+
props: { loading: "lazy", decoding: "async", ...props, src: srcDark, alt,
|
|
149
|
+
className: classeDaImagem("dark"), style: daImagem, onError: aoFalhar } });
|
|
142
150
|
// `role="img"` com `aria-label={alt}`: a caixa de erro continua sendo a imagem para quem usa
|
|
143
151
|
// leitor de tela, com o mesmo texto alternativo. Sem isso o `alt` some junto com o `<img>`.
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
152
|
+
const conteudo = quebrou
|
|
153
|
+
? _jsx("span", { className: cx("image", "image-broken", fit === "contain" && "image-contain", !frame && className), style: daImagem, role: "img", "aria-label": alt, children: _jsx(Icon, { name: "image" }) })
|
|
154
|
+
: srcDark ? _jsxs(_Fragment, { children: [elemento, escuro] }) : elemento;
|
|
155
|
+
if (!frame)
|
|
156
|
+
return conteudo;
|
|
157
|
+
return _jsx("span", { className: cx("image-frame", `image-frame-${frame}`, className), style: style, children: conteudo });
|
|
147
158
|
}
|
|
148
159
|
export function Gallery({ items, label, selected, onSelect, zoom, ratio = "1/1", selectionMode = "single", selectedIds, onSelectionChange, hasMore, loading, onReachEnd, className, ...props }) {
|
|
149
160
|
const s = useAureaStrings();
|
package/dist/pure.d.ts
CHANGED
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.", dataEmpty: "Nothing here yet", confirmProceed: "Continue", paginationLabel: "Pagination", previous: "Previous", next: "Next", breadcrumbLabel: "Breadcrumb", tabsLabel: "Tabs", optionsLabel: "Options", tableLabel: "Table", commandLabel: "Command palette", commandPlaceholder: "Type a command…", 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", 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", tocLabel: "On this page", navigationToggle: "Navigation", sidebarLabel: "Sidebar", sidebarCollapse: "Collapse sidebar", sidebarExpand: "Expand sidebar", bottomNavLabel: "Main", themeToDark: "Switch to dark theme", themeToLight: "Switch to light theme", 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.", dataEmpty: "Nothing here yet", confirmProceed: "Continue", paginationLabel: "Pagination", previous: "Previous", next: "Next", breadcrumbLabel: "Breadcrumb", tabsLabel: "Tabs", optionsLabel: "Options", tableLabel: "Table", commandLabel: "Command palette", commandPlaceholder: "Type a command…", 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", 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", 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", themeToLight: "Switch to light theme", 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.", dataEmpty: "Ainda não há nada aqui", confirmProceed: "Continuar", paginationLabel: "Paginação", previous: "Anterior", next: "Próxima", breadcrumbLabel: "Breadcrumb", tabsLabel: "Abas", optionsLabel: "Opções", tableLabel: "Tabela", commandLabel: "Paleta de comandos", commandPlaceholder: "Digite um comando…", 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", 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", 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", themeToLight: "Mudar para o tema claro", 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.", dataEmpty: "Ainda não há nada aqui", confirmProceed: "Continuar", paginationLabel: "Paginação", previous: "Anterior", next: "Próxima", breadcrumbLabel: "Breadcrumb", tabsLabel: "Abas", optionsLabel: "Opções", tableLabel: "Tabela", commandLabel: "Paleta de comandos", commandPlaceholder: "Digite um comando…", 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", 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", 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", themeToLight: "Mudar para o tema claro", universalState: { waiting_user: "Esperando alguém agir.", waiting_approval: "Esperando aprovação.", waiting_dependency: "Esperando outra coisa terminar.", offline: "Sem conexão. Isto foi carregado antes.", stale: "Isto pode estar desatualizado.", partial: "Parte disto não pôde ser carregada.", degraded: "Funcionando com capacidade reduzida." } };
|
|
60
60
|
// Sprite de ícones: CONFIGURAÇÃO DE APLICAÇÃO, então entra pelo provider, uma vez.
|
|
61
61
|
// Antes o default absoluto "/aurea-icons.svg" vivia no Icon e 15 componentes declaravam
|
|
62
62
|
// e repassavam `spriteUrl` à mão — 52 sítios de código. Consequência: aplicação servida
|
package/dist/system.js
CHANGED
|
@@ -8,7 +8,7 @@ import { Toast as BaseToast } from "@base-ui/react/toast";
|
|
|
8
8
|
import { Tooltip as BaseTooltip } from "@base-ui/react/tooltip";
|
|
9
9
|
import { DirectionProvider } from "@base-ui/react/direction-provider";
|
|
10
10
|
import { peleDoEixo } from "./pure.js";
|
|
11
|
-
import { cx, StringsContext, SpriteContext, PortalContext, ThemeContext, DensityContext, DentroDoProviderContext, usePortalContainer, defaultStrings, defaultSpriteUrl, useSpriteUrl, useAureaStrings } from "./internal.js";
|
|
11
|
+
import { cx, StringsContext, SpriteContext, PortalContext, ThemeContext, DensityContext, DentroDoProviderContext, avisosAncorados, usePortalContainer, defaultStrings, defaultSpriteUrl, useSpriteUrl, useAureaStrings } from "./internal.js";
|
|
12
12
|
// `theme` e `density` seguem a convenção controlado/não-controlado do resto da biblioteca
|
|
13
13
|
// (`Toggle`, `ToggleGroup`): passe `theme` para mandar, `defaultTheme` para semear, e ouça por
|
|
14
14
|
// `onThemeChange`. Sem nenhum dos dois, o provider ADOTA o que o documento já trouxer no
|
|
@@ -40,7 +40,10 @@ export function AureaProvider({ children, strings, direction = "ltr", spriteUrl
|
|
|
40
40
|
// Agora a regra é uma: desconhecido resolve para claro e alterna para ESCURO.
|
|
41
41
|
toggleTheme: () => temaCtx.set(temaCtx.valor === "dark" ? "light" : "dark") }), [temaCtx]);
|
|
42
42
|
const dens = React.useMemo(() => ({ density: densCtx.valor, setDensity: densCtx.set }), [densCtx]);
|
|
43
|
-
|
|
43
|
+
// GAR-14: os avisos presos a um botão vivem num gerenciador do MÓDULO (ver `avisosAncorados`), então
|
|
44
|
+
// só o provedor de FORA monta o hospedeiro deles — com dois, cada aviso apareceria duas vezes.
|
|
45
|
+
const deFora = !React.useContext(DentroDoProviderContext);
|
|
46
|
+
return _jsx(DentroDoProviderContext.Provider, { value: true, children: _jsx(StringsContext.Provider, { value: value, children: _jsx(SpriteContext.Provider, { value: spriteUrl, children: _jsx(PortalContext.Provider, { value: portalContainer, children: _jsx(ThemeContext.Provider, { value: tema, children: _jsx(DensityContext.Provider, { value: dens, children: _jsx(DirectionProvider, { direction: direction, children: _jsx(BaseToast.Provider, { children: _jsxs(BaseTooltip.Provider, { children: [children, _jsx(AureaToastViewport, {}), deFora && _jsx(BaseToast.Provider, { toastManager: avisosAncorados, children: _jsx(AvisosAncorados, {}) })] }) }) }) }) }) }) }) }) });
|
|
44
47
|
}
|
|
45
48
|
/** Um eixo de apresentação que vive no `<html>`: tema ou densidade. A conta é a mesma para os
|
|
46
49
|
* dois, e escrevê-la duas vezes seria o defeito do §21 cometido dentro do próprio conserto
|
|
@@ -153,6 +156,40 @@ function AureaToastViewport() {
|
|
|
153
156
|
const portal = usePortalContainer();
|
|
154
157
|
return _jsx(BaseToast.Portal, { container: portal, children: _jsx(BaseToast.Viewport, { className: "toast-stack", children: _jsx(AureaToastList, {}) }) });
|
|
155
158
|
}
|
|
159
|
+
// GAR-14 (0.28.0) · OS AVISOS PRESOS A UM BOTÃO ("Link copiado", do `Button share`). A documentação do
|
|
160
|
+
// motor manda o aviso ancorado viver num gerenciador SEPARADO do da pilha — senão ele entra na conta
|
|
161
|
+
// da pilha do canto — e é o que este é: um do módulo, criado com `createToastManager` (mora no
|
|
162
|
+
// `internal.tsx`, para não virar API pública), que o botão chama direto sem precisar de hook. O hospedeiro dele é montado uma vez,
|
|
163
|
+
// pelo `AureaProvider` de fora. A posição é do motor (`Toast.Positioner`, ancorado no botão); a pele é
|
|
164
|
+
// a `.toast-anchored`, com a medida do botão. O anúncio ao leitor de tela é o da região do motor.
|
|
165
|
+
function AvisosAncorados() {
|
|
166
|
+
const { toasts } = BaseToast.useToastManager();
|
|
167
|
+
const portal = usePortalContainer();
|
|
168
|
+
// Região VIVA simples, sem papel e sem nome — o modelo clássico do "copiado" (WCAG 4.1.3). A padrão
|
|
169
|
+
// do motor é uma região com o nome "Notifications": a página ficava com DUAS (a pilha e esta), e o
|
|
170
|
+
// axe reprova (`landmark-unique`). Com `role="status"`, quem procura o status da página (o leitor de
|
|
171
|
+
// tela, e os testes de quem usa a Aurea) passava a achar dois. Sem papel, ela não é nenhum dos dois
|
|
172
|
+
// e continua anunciando: `aria-live` é atributo global. Os dois `undefined` tiram o padrão do motor.
|
|
173
|
+
return _jsx(BaseToast.Portal, { container: portal, children: _jsx(BaseToast.Viewport, { role: undefined, "aria-label": undefined, children: toasts.map(t => {
|
|
174
|
+
const falhou = t.type === "danger";
|
|
175
|
+
const url = t.data?.url;
|
|
176
|
+
const ancora = t.positionerProps?.anchor;
|
|
177
|
+
const fechar = (devolverFoco) => { avisosAncorados.close(t.id); if (devolverFoco && ancora instanceof HTMLElement)
|
|
178
|
+
ancora.focus(); };
|
|
179
|
+
const aviso = _jsxs("div", { className: cx("toast-anchored", falhou && "toast-anchored-danger"), children: [_jsx("span", { className: "toast-anchored-icon", "aria-hidden": "true" }), _jsx(BaseToast.Title, { render: _jsx("span", {}) })] });
|
|
180
|
+
return _jsx(BaseToast.Positioner, { toast: t, className: "toast-anchored-positioner", children: falhou
|
|
181
|
+
// O erro fica até a pessoa resolver: o link vem selecionado, para o Ctrl+C; Esc devolve o
|
|
182
|
+
// foco ao botão, e sair do campo fecha.
|
|
183
|
+
? _jsxs(BaseToast.Root, { toast: t, className: "toast-anchored-stack", children: [aviso, _jsx("input", { className: "input toast-anchored-link", readOnly: true, value: url ?? "", "aria-label": typeof t.title === "string" ? t.title : undefined, ref: el => { if (el) {
|
|
184
|
+
el.focus();
|
|
185
|
+
el.select();
|
|
186
|
+
} }, onKeyDown: e => { if (e.key === "Escape") {
|
|
187
|
+
e.preventDefault();
|
|
188
|
+
fechar(true);
|
|
189
|
+
} }, onBlur: () => fechar(false) })] })
|
|
190
|
+
: _jsxs(BaseToast.Root, { toast: t, className: "toast-anchored", children: [_jsx("span", { className: "toast-anchored-icon", "aria-hidden": "true" }), _jsx(BaseToast.Title, { render: _jsx("span", {}) })] }) }, t.id);
|
|
191
|
+
}) }) });
|
|
192
|
+
}
|
|
156
193
|
import { NOMES_PHOSPHOR } from "./icon-names.js";
|
|
157
194
|
// spriteUrl aqui é OVERRIDE local (dois sprites na mesma página, por exemplo). O normal é
|
|
158
195
|
// não passar nada e deixar o AureaProvider dizer de onde vêm os glifos.
|