@aurea-uds/react 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/actions.d.ts CHANGED
@@ -10,6 +10,18 @@ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>, Re
10
10
  trailingIcon?: IconName;
11
11
  href?: string;
12
12
  fullWidth?: boolean;
13
+ /**
14
+ * @deprecated Use `<Toggle>` instead. Pesquisado em 18/08/2026 nas doze referências (MUI,
15
+ * Fluent 2, React Aria, Spectrum, Carbon, Radix/Base UI, shadcn, ReUI, PrimeReact, HeroUI,
16
+ * Cedar, APG): **nenhuma** põe o estado de pressionado no botão comum — todas têm um
17
+ * componente separado, e o nosso é o `Toggle`. Manter os dois é dois caminhos para a mesma
18
+ * coisa, que é o "qual eu uso?" que denuncia recurso duplicado.
19
+ * A diferença de verdade: aqui VOCÊ guarda o estado e isto só pinta e anuncia; o `Toggle`
20
+ * guarda o estado (motor Base UI), devolve `onPressedChange` e cobra nome acessível quando
21
+ * é só ícone.
22
+ * @deprecatedSince 0.4.0 — sai na `1.0`. A Aurea está em `0.x`, onde o semver permite
23
+ * quebrar, e por isso este é o momento mais barato que vai existir.
24
+ */
13
25
  pressed?: boolean;
14
26
  kbd?: string;
15
27
  }
package/dist/actions.js CHANGED
@@ -60,6 +60,13 @@ function temConteudoVisivel(children) {
60
60
  return temConteudoVisivel(p.children);
61
61
  });
62
62
  }
63
+ // ESTE é o toggle da Aurea. O `pressed` do `Button` está DEPRECIADO em favor dele (0.4.0,
64
+ // sai na 1.0): as doze referências pesquisadas em 18/08/2026 têm componente separado, e
65
+ // nenhuma põe o estado no botão comum.
66
+ // E a REGRA QUE FALTAVA ESTAR ESCRITA AQUI, do Adobe Spectrum e do APG: **o rótulo não muda
67
+ // entre os estados**. Se o texto vira "Mute"/"Unmute" ou "Play"/"Pause", não é toggle — é
68
+ // botão de ação, porque quem lê tela ouve o rótulo NOVO e o estado ao mesmo tempo e não sabe
69
+ // se o botão descreve o que é ou o que fará.
63
70
  export function Toggle({ pressed, defaultPressed, onPressedChange, icon, label, size = "md", disabled, id, className, children }) {
64
71
  // O tipo barra o consumidor TypeScript; este aviso barra o de JavaScript, que não tem tipo nenhum.
65
72
  // Sem gate por NODE_ENV de propósito: o `dist` é saída de `tsc`, então `process` não existe no
@@ -1,2 +1,2 @@
1
1
  export * from "./feedback-client.js";
2
- export { Badge, Progress, Skeleton, type BadgeVariant } from "./markup.js";
2
+ export { Badge, formatBadgeCount, Progress, Skeleton, type BadgeVariant, type BadgeEmphasis, type BadgeSize, type BadgePlacement, type BadgeProps } 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, Progress, Skeleton } from "./markup.js";
5
+ export { Badge, formatBadgeCount, Progress, Skeleton } from "./markup.js";
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { cx, defaultStrings, ptBR, defaultSpriteUrl, gridStateToParams, gridStateFromParams, screenStateToParams, screenStateFromParams, universalStates, stateSeverity, type AureaStrings, type GridState, type ScreenState, type UniversalState } from "./pure.js";
2
2
  export { useAureaStrings, useSpriteUrl } from "./internal.js";
3
- export { Card, Stack, Cluster, Grid, KPI, DataList, Timeline, Prose, Badge, Progress, Skeleton, AvatarGroup, LogStream, MediaPlayerShell, Topbar, Kbd, Select, Textarea, Checkbox, Radio, Switch, Range, type BadgeVariant, type AvatarSize, type TopbarVariant } from "./markup.js";
3
+ export { Card, Stack, Cluster, Grid, Separator, KPI, DataList, Timeline, Prose, Badge, Progress, Skeleton, AvatarGroup, LogStream, MediaPlayerShell, Topbar, Kbd, Select, Textarea, Checkbox, Radio, Switch, Range, formatBadgeCount, type BadgeVariant, type BadgeEmphasis, type BadgeSize, type BadgePlacement, type BadgeProps, type AvatarSize, type TopbarVariant } from "./markup.js";
4
4
  export * from "./system.js";
5
5
  export * from "./actions.js";
6
6
  export * from "./feedback.js";
package/dist/index.js CHANGED
@@ -42,7 +42,7 @@ export { useAureaStrings, useSpriteUrl } from "./internal.js";
42
42
  // inteiro). O que muda é de ONDE ele vem — do módulo com a diretiva —, e aí ele volta a chegar
43
43
  // como referência de CLIENTE e os 118,5 KB voltam com ele. Não é um erro: é o ganho do item O1
44
44
  // se desfazendo em silêncio. É isso, exatamente isso, que o check 35 pega.
45
- export { Card, Stack, Cluster, Grid, KPI, DataList, Timeline, Prose, Badge, Progress, Skeleton, AvatarGroup, LogStream, MediaPlayerShell, Topbar, Kbd, Select, Textarea, Checkbox, Radio, Switch, Range } from "./markup.js";
45
+ export { Card, Stack, Cluster, Grid, Separator, KPI, DataList, Timeline, Prose, Badge, Progress, Skeleton, AvatarGroup, LogStream, MediaPlayerShell, Topbar, Kbd, Select, Textarea, Checkbox, Radio, Switch, Range, formatBadgeCount } from "./markup.js";
46
46
  export * from "./system.js";
47
47
  export * from "./actions.js";
48
48
  export * from "./feedback.js";
@@ -1,9 +1,10 @@
1
1
  import { type HTMLAttributes, type RefAttributes, type ReactNode } from "react";
2
- import { type TopbarVariant } from "./navigation.js";
3
- export declare function AppShell({ brand, navigation, topbar, topbarVariant, sidebarCollapsed, children, className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement> & {
2
+ import { type TopbarVariant, type SidebarVariant } from "./navigation.js";
3
+ export declare function AppShell({ brand, navigation, topbar, topbarVariant, sidebarVariant, sidebarCollapsed, children, className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement> & {
4
4
  brand: ReactNode;
5
5
  navigation: ReactNode;
6
6
  topbar?: ReactNode;
7
7
  topbarVariant?: Exclude<TopbarVariant, "pill">;
8
+ sidebarVariant?: SidebarVariant;
8
9
  sidebarCollapsed?: boolean;
9
10
  }): import("react").JSX.Element;
@@ -66,7 +66,12 @@ function focoDaGaveta(e) {
66
66
  // colisão possível — e o CSS e o gate precisam de um alvo estável.
67
67
  // `sidebarCollapsed` é CONTROLADO pelo consumidor, como o `open` do CommandPaletteShell: o
68
68
  // shell não decide quando recolher nem desenha o botão que recolhe — quem sabe se há espaço,
69
- // e se a preferência se guarda, é a aplicação. O que o shell faz é o que ele pode: a coluna
70
- // do grid encolhe para --sidebar-rail (a regra `:has(.sidebar-collapsed)` no core).
69
+ // e se a preferência se guarda, é a aplicação. O shell encolhe o painel para --sidebar-rail e,
70
+ // quando ele flutua, preserva as duas margens na coluna (as regras `:has()` no core).
71
+ // `sidebarVariant` existe porque SEM ELE a variante da lateral é enfeite. Medido em 20/08/2026: o
72
+ // shell chamava `<Sidebar>` sem variante nenhuma, então quem monta por aqui — que é o caminho
73
+ // normal, e é como as 106 páginas do catálogo são montadas — recebia o padrão e ponto. A variante
74
+ // estava documentada no CHANGELOG como saída para quem instalou a `0.3.0`, e a porta estava
75
+ // trancada. É o par do `topbarVariant`, que já existia logo acima. Ver ADR-0034.
71
76
  const SHELL_NAV_ID = "aurea-shell-nav";
72
- export function AppShell({ brand, navigation, topbar, topbarVariant = "floating", sidebarCollapsed, children, className, ...props }) { const s = useAureaStrings(); return _jsxs("div", { className: cx("app-shell", topbarVariant === "flush" && "app-shell-flush", className), ...props, children: [_jsx(Topbar, { variant: topbarVariant, brand: _jsxs(_Fragment, { children: [_jsx(IconButton, { className: "nav-toggle", icon: "menu", label: s.navigationToggle, popoverTarget: SHELL_NAV_ID }), brand] }), children: topbar }), _jsx(Sidebar, { id: SHELL_NAV_ID, popover: "auto", collapsed: sidebarCollapsed, onToggle: focoDaGaveta, children: navigation }), _jsx("main", { className: "content", children: children })] }); }
77
+ export function AppShell({ brand, navigation, topbar, topbarVariant = "floating", sidebarVariant, sidebarCollapsed, children, className, ...props }) { const s = useAureaStrings(); return _jsxs("div", { className: cx("app-shell", topbarVariant === "flush" && "app-shell-flush", className), ...props, children: [_jsx(Topbar, { variant: topbarVariant, brand: _jsxs(_Fragment, { children: [_jsx(IconButton, { className: "nav-toggle", icon: "menu", label: s.navigationToggle, popoverTarget: SHELL_NAV_ID }), brand] }), children: topbar }), _jsx(Sidebar, { id: SHELL_NAV_ID, popover: "auto", variant: sidebarVariant, collapsed: sidebarCollapsed, onToggle: focoDaGaveta, children: navigation }), _jsx("main", { className: "content", children: children })] }); }
package/dist/layout.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export * from "./layout-client.js";
2
- export { Card, Stack, Cluster, Grid } from "./markup.js";
2
+ export { Card, Stack, Cluster, Grid, Separator } from "./markup.js";
package/dist/layout.js CHANGED
@@ -2,4 +2,4 @@
2
2
  // de propósito: a diretiva contamina o módulo inteiro e faria a marcação pura chegar como cliente
3
3
  // por vizinhança (ADR-0026; o check 26b reprova quem a puser de volta aqui).
4
4
  export * from "./layout-client.js";
5
- export { Card, Stack, Cluster, Grid } from "./markup.js";
5
+ export { Card, Stack, Cluster, Grid, Separator } from "./markup.js";
package/dist/markup.d.ts CHANGED
@@ -6,6 +6,9 @@ export declare function Card({ variant, className, ...props }: HTMLAttributes<HT
6
6
  variant?: "base" | "raised" | "interactive" | "inset" | "selected" | "danger";
7
7
  }): React.JSX.Element;
8
8
  export declare function Stack({ className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>): React.JSX.Element;
9
+ export declare function Separator({ orientation, className, ...props }: HTMLAttributes<HTMLHRElement> & RefAttributes<HTMLHRElement> & {
10
+ orientation?: "horizontal" | "vertical";
11
+ }): React.JSX.Element;
9
12
  export declare function Cluster({ className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>): React.JSX.Element;
10
13
  export declare function Grid({ className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>): React.JSX.Element;
11
14
  export declare function KPI({ label, value, trend, className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement> & {
@@ -27,9 +30,37 @@ export declare function Timeline({ items }: {
27
30
  }>;
28
31
  }): React.JSX.Element;
29
32
  export declare function Prose({ className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement>): React.JSX.Element;
30
- export declare function Badge({ variant, className, ...props }: HTMLAttributes<HTMLSpanElement> & RefAttributes<HTMLSpanElement> & {
33
+ export type BadgeEmphasis = "soft" | "solid" | "outline";
34
+ export type BadgeSize = "xs" | "sm" | "md" | "lg";
35
+ export type BadgePlacement = "top-end" | "top-start" | "bottom-end" | "bottom-start";
36
+ export declare function formatBadgeCount(count: number, max?: number): string;
37
+ export interface BadgeProps extends HTMLAttributes<HTMLSpanElement>, RefAttributes<HTMLSpanElement> {
31
38
  variant?: BadgeVariant;
32
- }): React.JSX.Element;
39
+ /** `soft` é o tom de sempre; `solid` preenche com o acento; `outline` é só contorno. */
40
+ emphasis?: BadgeEmphasis;
41
+ size?: BadgeSize;
42
+ /** Ponto de estado antes do texto. Sozinho num `anchor`, ele É o badge. */
43
+ dot?: boolean;
44
+ leading?: ReactNode;
45
+ trailing?: ReactNode;
46
+ /** Foto redonda no início — o `BadgeWithImage` da referência. */
47
+ image?: string;
48
+ imageAlt?: string;
49
+ /** Conteúdo numérico. Passa por `max` e some em zero, salvo `showZero`. */
50
+ count?: number;
51
+ max?: number;
52
+ showZero?: boolean;
53
+ /** Liga o modo SOBREPOSTO e escolhe o canto. `children` passa a ser o que se decora. */
54
+ anchor?: BadgePlacement;
55
+ /** `circle` recolhe o canto em 14% — é o `overlap` da MUI, para avatar redondo. */
56
+ anchorShape?: "square" | "circle";
57
+ /** Esconde sem tirar o filho do lugar. */
58
+ invisible?: boolean;
59
+ /** Conteúdo do badge no modo sobreposto (no modo chip, quem manda é `children`).
60
+ * Nome da MUI, e não `content`: este colide com o atributo HTML de mesmo nome. */
61
+ badgeContent?: ReactNode;
62
+ }
63
+ export declare function Badge({ variant, emphasis, size, dot, leading, trailing, image, imageAlt, count, max, showZero, anchor, anchorShape, invisible, badgeContent, children, className, ...props }: BadgeProps): React.JSX.Element;
33
64
  export declare function Progress({ value, label }: {
34
65
  value: number;
35
66
  label?: string;
package/dist/markup.js CHANGED
@@ -40,6 +40,27 @@ import { cx } from "./pure.js";
40
40
  // ── Layout ───────────────────────────────────────────────────────────────────────────────────
41
41
  export function Card({ variant = "base", className, ...props }) { return _jsx("div", { className: cx("card", variant !== "base" && `card-${variant}`, className), ...props }); }
42
42
  export function Stack({ className, ...props }) { return _jsx("div", { className: cx("stack", className), ...props }); }
43
+ // SEPARATOR — a régua entre coisas. Faltava: a Aurea só tinha `.prose hr` (preso à prosa) e o
44
+ // `ToolbarSeparator` (preso ao Toolbar). Untitled UI precisa dela para a variante de seções da
45
+ // lateral, e ela serve em todo lugar.
46
+ //
47
+ // É `<hr>`, e isso é decisão medida em 18/08/2026. O motor que já usamos ENTREGA um `Separator` —
48
+ // mas ele é `'use client'`, usa hook (`useRenderElement`) e o que produz são DOIS atributos:
49
+ // `role="separator"` e `aria-orientation`. Importá-lo arrastaria este módulo para o lado cliente,
50
+ // que é o defeito da ADR-0026 (o `Card` custou 118,5 KB atravessando essa fronteira). Aqui a regra
51
+ // "se o motor entrega, não escrevemos" (BUILDING.md passo 2) PERDE para a fronteira — e o registro
52
+ // existe para a próxima sessão não "corrigir" isto de volta.
53
+ //
54
+ // `<hr>` nativo JÁ TEM `role="separator"` implícito, então escrever o papel seria ARIA redundante —
55
+ // e o APG avisa que ARIA a mais é pior que ARIA nenhuma. O papel `separator` também tem orientação
56
+ // HORIZONTAL por padrão: por isso `aria-orientation` só aparece quando é vertical.
57
+ //
58
+ // O que NÃO entrou, pelo passo 5: as três tonalidades do HeroUI (`secondary`/`tertiary`) — a Aurea
59
+ // tem um `--border` e inventar escala de tom aqui seria copiar o sistema de token deles. E o
60
+ // separador COM RÓTULO no meio ("or", uma data numa conversa), que eles têm em
61
+ // `separator__container` + `__line` + `__content`: é outra estrutura (o `<hr>` não carrega texto),
62
+ // ninguém pediu ainda, e fica registrado aqui como o próximo degrau se alguém precisar.
63
+ export function Separator({ orientation = "horizontal", className, ...props }) { return _jsx("hr", { "aria-orientation": orientation === "vertical" ? "vertical" : undefined, className: cx("separator", orientation === "vertical" && "separator-vertical", className), ...props }); }
43
64
  export function Cluster({ className, ...props }) { return _jsx("div", { className: cx("cluster", className), ...props }); }
44
65
  export function Grid({ className, ...props }) { return _jsx("div", { className: cx("grid", className), ...props }); }
45
66
  // ── Data Display ─────────────────────────────────────────────────────────────────────────────
@@ -52,8 +73,24 @@ export function Timeline({ items }) { return _jsx("ol", { className: "timeline",
52
73
  // `dangerouslySetInnerHTML` tem de SANITIZAR antes. A Aurea desenha o texto; ela não pode decidir
53
74
  // o que é seguro renderizar. Está dito na ficha, em voz alta.
54
75
  export function Prose({ className, ...props }) { return _jsx("div", { className: cx("prose", className), ...props }); }
55
- // ── Feedback ─────────────────────────────────────────────────────────────────────────────────
56
- export function Badge({ variant = "neutral", className, ...props }) { return _jsx("span", { className: cx("badge", variant !== "neutral" && `badge-${variant}`, className), ...props }); }
76
+ // `max` com `+` é o idioma universal do contador (MUI, Ant, Material 3). Exportada porque quem
77
+ // escreve o nome acessível precisa do MESMO texto "99+ unread" tem de bater com o que se vê.
78
+ export function formatBadgeCount(count, max = 99) { return count > max ? `${max}+` : String(count); }
79
+ export function Badge({ variant = "neutral", emphasis = "soft", size = "md", dot, leading, trailing, image, imageAlt, count, max = 99, showZero, anchor, anchorShape = "square", invisible, badgeContent, children, className, ...props }) {
80
+ const numero = count != null ? formatBadgeCount(count, max) : undefined;
81
+ const miolo = anchor ? (numero ?? badgeContent) : (numero ?? children);
82
+ // Ponto puro: `dot` sem nada para mostrar. Aí o badge não tem conteúdo, e ganha medida própria.
83
+ const soPonto = !!dot && miolo == null;
84
+ const chip = _jsxs("span", { className: cx("badge", variant !== "neutral" && `badge-${variant}`, emphasis !== "soft" && `badge-${emphasis}`, size !== "md" && `badge-${size}`, anchor && `badge-overlay badge-at-${anchor}`, anchor && anchorShape === "circle" && "badge-on-circle", anchor && soPonto && "badge-is-dot", className), ...props, children: [dot && !soPonto && _jsx("span", { className: "badge-dot" }), image && _jsx("img", { className: "badge-image", src: image, alt: imageAlt ?? "" }), leading, miolo, trailing] });
85
+ if (!anchor)
86
+ return chip;
87
+ // Some em zero por padrão, como a MUI: caixa de entrada zerada não merece um "0" no canto.
88
+ const escondido = invisible || (count === 0 && !showZero) || (miolo == null && !dot);
89
+ // `aria-hidden` no contador, e o número vai para o nome de QUEM É DECORADO — regra da própria
90
+ // documentação da MUI e das três fontes de acessibilidade lidas em 17/08/2026. Sem isso, o
91
+ // botão do sino é anunciado "sino 8" e ninguém sabe o que é o 8.
92
+ return _jsxs("span", { className: "badge-anchor", children: [children, !escondido && React.cloneElement(chip, { "aria-hidden": true })] });
93
+ }
57
94
  export function Progress({ value, label }) { const pct = Math.max(0, Math.min(100, value)); return _jsx("div", { children: _jsx("div", { className: "progress", role: "progressbar", "aria-label": label, "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": pct, children: _jsx("span", { style: { width: `${pct}%` } }) }) }); }
58
95
  export function Skeleton({ className, ...props }) { return _jsx("div", { className: cx("skeleton", className), "aria-hidden": "true", ...props }); }
59
96
  // ── Identity ─────────────────────────────────────────────────────────────────────────────────
@@ -66,12 +66,38 @@ export interface SidebarItem {
66
66
  onClick?: () => void;
67
67
  items?: SidebarItem[];
68
68
  }
69
- export declare function Sidebar({ items, current, collapsed, label, children, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement> & {
69
+ export type SidebarVariant = "floating" | "flush";
70
+ export declare function Sidebar({ items, current, collapsed, variant, label, children, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement> & {
70
71
  items?: SidebarItem[];
71
72
  current?: string;
72
73
  collapsed?: boolean;
74
+ variant?: SidebarVariant;
73
75
  label?: string;
74
76
  }): React.JSX.Element;
77
+ export type BottomNavVariant = "floating" | "edge";
78
+ export type BottomNavIndicator = "none" | "subtle" | "pill" | "circle" | "circle-raised" | "circle-bold" | "circle-outline";
79
+ /** @deprecated Os quatro nomes de 17/08/2026. Use `variant` + `indicator`. */
80
+ export type BottomNavVariantLegacy = "flat" | "surface" | "pill" | "dock";
81
+ export declare function BottomNav({ items, current, variant, indicator, label, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement> & {
82
+ items: SidebarItem[];
83
+ current?: string;
84
+ variant?: BottomNavVariant | BottomNavVariantLegacy;
85
+ indicator?: BottomNavIndicator;
86
+ label?: string;
87
+ }): React.JSX.Element;
88
+ export interface NavListItem {
89
+ id: string;
90
+ label: ReactNode;
91
+ description?: ReactNode;
92
+ value?: ReactNode;
93
+ icon?: IconName;
94
+ href?: string;
95
+ onClick?: () => void;
96
+ disabled?: boolean;
97
+ }
98
+ export declare function NavList({ items, className, ...props }: HTMLAttributes<HTMLUListElement> & RefAttributes<HTMLUListElement> & {
99
+ items: NavListItem[];
100
+ }): React.JSX.Element;
75
101
  export interface CommandItem {
76
102
  id: string;
77
103
  label: string;
@@ -12,6 +12,10 @@ import { Icon } from "./system.js";
12
12
  import { Button } from "./actions.js";
13
13
  import { Badge } from "./feedback.js";
14
14
  import { SearchField } from "./inputs.js";
15
+ // `overlays` PASSOU A VIR ANTES de `navigation` no DAG (18/08/2026, MAP.md §DAG). Ele só
16
+ // importa `internal`, `system` e `actions` — todos anteriores —, então não há ciclo: o que
17
+ // mudou foi a ORDEM documentada, que colocava overlays no "resto" sem motivo medido.
18
+ import { Tooltip } from "./overlays.js";
15
19
  export function Stepper({ items, label, className }) {
16
20
  const s = useAureaStrings();
17
21
  return _jsx("div", { role: "list", "aria-label": label ?? s.stepperLabel, className: cx("stepper", className), children: items.map((it, n) => {
@@ -120,16 +124,54 @@ function sidebarList(items, ctx, sub, labelledBy) {
120
124
  if (filhos && !it.href && !it.onClick)
121
125
  return _jsxs("li", { children: [_jsx("p", { id: lid, className: cx("sidebar-group-label", ctx.collapsed && "sr-only"), children: it.label }), sidebarList(filhos, ctx, false, lid)] }, it.id);
122
126
  const ativo = it.id === ctx.current;
123
- const miolo = _jsxs(_Fragment, { children: [it.icon && _jsx(Icon, { name: it.icon, size: "sm" }), _jsx("span", { className: cx("sidebar-label", ctx.collapsed && "sr-only"), children: it.label }), it.badge != null && oculto(it.badge)] });
124
- return _jsxs("li", { children: [it.href
125
- ? _jsx("a", { id: lid, href: it.href, className: "sidebar-item", "aria-current": ativo ? "page" : undefined, onClick: it.onClick, children: miolo })
126
- : _jsx("button", { id: lid, type: "button", className: "sidebar-item", "aria-current": ativo ? "page" : undefined, onClick: it.onClick, children: miolo }), filhos && sidebarList(filhos, ctx, true, lid)] }, it.id);
127
+ const miolo = _jsxs(_Fragment, { children: [it.icon && _jsx(Icon, { name: it.icon }), _jsx("span", { className: cx("sidebar-label", ctx.collapsed && "sr-only"), children: it.label }), it.badge != null && oculto(it.badge)] });
128
+ const alvo = it.href
129
+ ? _jsx("a", { id: lid, href: it.href, className: "sidebar-item", "aria-current": ativo ? "page" : undefined, onClick: it.onClick, children: miolo })
130
+ : _jsx("button", { id: lid, type: "button", className: "sidebar-item", "aria-current": ativo ? "page" : undefined, onClick: it.onClick, children: miolo });
131
+ // NO TRILHO O NOME SÓ EXISTE NO TOOLTIP. Recolhida, a lateral manda o rótulo para `.sr-only`: quem
132
+ // usa leitor de tela continua ouvindo, e quem ENXERGA fica com um ícone mudo. A referência resolve
133
+ // isso com tooltip no `NavButton`, e é o que falta para um trilho de ícone não virar adivinhação.
134
+ // Só quando recolhida: com o rótulo visível ao lado, o tooltip repetiria o que já está na tela.
135
+ // `side="right"` porque a lateral encosta na borda esquerda — para cima o balão sairia do trilho.
136
+ return _jsxs("li", { children: [ctx.collapsed ? _jsx(Tooltip, { content: it.label, side: "right", children: alvo }) : alvo, filhos && sidebarList(filhos, ctx, true, lid)] }, it.id);
127
137
  }) });
128
138
  }
129
- export function Sidebar({ items, current, collapsed, label, children, className, ...props }) {
139
+ export function Sidebar({ items, current, collapsed, variant = "floating", label, children, className, ...props }) {
130
140
  const s = useAureaStrings();
131
141
  const baseId = React.useId();
132
- return _jsxs("aside", { className: cx("sidebar", collapsed && "sidebar-collapsed", className), ...props, children: [items && items.length > 0 && _jsx("nav", { className: "sidebar-nav", "aria-label": label ?? s.sidebarLabel, children: sidebarList(items, { baseId, current, collapsed }) }), children] });
142
+ return _jsxs("aside", { className: cx("sidebar", variant !== "floating" && `sidebar-${variant}`, collapsed && "sidebar-collapsed", className), ...props, children: [items && items.length > 0 && _jsx("nav", { className: "sidebar-nav", "aria-label": label ?? s.sidebarLabel, children: sidebarList(items, { baseId, current, collapsed }) }), children] });
143
+ }
144
+ const LEGADO = {
145
+ flat: ["edge", "none"], surface: ["floating", "circle"], pill: ["floating", "pill"], dock: ["floating", "circle"]
146
+ };
147
+ export function BottomNav({ items, current, variant = "floating", indicator = "none", label, className, ...props }) {
148
+ const s = useAureaStrings();
149
+ const [layout, marca0] = variant in LEGADO ? LEGADO[variant] : [variant, indicator];
150
+ // O indicador explícito ganha do que o nome legado implica: quem escreveu os dois quis os dois.
151
+ const ind = indicator !== "none" ? indicator : marca0;
152
+ return _jsx("nav", { className: cx("bottom-nav", layout === "edge" && "bottom-nav-edge", `bottom-nav-ind-${ind}`, className), "aria-label": label ?? s.bottomNavLabel, ...props, children: items.map(it => {
153
+ const ativo = it.id === current;
154
+ // O CONTADOR PENDURA NO ÍCONE, e é por isso que existe esta caixa. Pendurado no ITEM (a
155
+ // primeira versão), `50%` cai no meio do RÓTULO quando o item é linha — o Victor viu o número
156
+ // cobrir o nome inteiro em 17/08/2026. A pesquisa (Material 3 e os guias de barra de abas do
157
+ // iOS) diz a mesma coisa: canto superior do ÍCONE, encostando na borda dele, nunca sobre o
158
+ // texto. A caixa é o que dá ao contador um canto para se ancorar — e nos quatro indicadores
159
+ // redondos é ela que VIRA o círculo, com o rótulo embaixo, fora dele.
160
+ // `size="lg"` porque a proporção contra o contador foi medida: 24 para 16, razão 0,67.
161
+ const marca = _jsxs("span", { className: "bottom-nav-mark", children: [it.icon && _jsx(Icon, { name: it.icon, size: "lg" }), it.badge != null && _jsx("span", { className: "bottom-nav-badge", children: it.badge })] });
162
+ const miolo = _jsxs(_Fragment, { children: [marca, _jsx("span", { className: "bottom-nav-label", children: it.label })] });
163
+ return it.href
164
+ ? _jsx("a", { href: it.href, className: "bottom-nav-item", "aria-current": ativo ? "page" : undefined, onClick: it.onClick, children: miolo }, it.id)
165
+ : _jsx("button", { type: "button", className: "bottom-nav-item", "aria-current": ativo ? "page" : undefined, onClick: it.onClick, children: miolo }, it.id);
166
+ }) });
167
+ }
168
+ export function NavList({ items, className, ...props }) {
169
+ return _jsx("ul", { className: cx("nav-list", className), ...props, children: items.map(it => {
170
+ const miolo = _jsxs(_Fragment, { children: [it.icon && _jsx(Icon, { name: it.icon }), _jsxs("span", { className: "nav-list-text", children: [_jsx("span", { className: "nav-list-label", children: it.label }), it.description != null && _jsx("span", { className: "nav-list-description", children: it.description })] }), it.value != null && _jsx("span", { className: "nav-list-value", children: it.value }), it.href && _jsx(Icon, { name: "chevron--right", size: "sm", className: "nav-list-chevron" })] });
171
+ return _jsx("li", { children: it.href && !it.disabled
172
+ ? _jsx("a", { href: it.href, className: "nav-list-row", onClick: it.onClick, children: miolo })
173
+ : _jsx("button", { type: "button", className: "nav-list-row", "aria-disabled": it.disabled || undefined, onClick: it.disabled ? undefined : it.onClick, children: miolo }) }, it.id);
174
+ }) });
133
175
  }
134
176
  export function CommandPalette({ open, onClose, items, placeholder, label }) {
135
177
  const s = useAureaStrings();
package/dist/overlays.js CHANGED
@@ -66,7 +66,7 @@ export function AccessGate({ allowed, children, ...resto }) {
66
66
  // conteúdo da dica. Era tooltip visual, não acessível (padrão APG Tooltip).
67
67
  // O id aponta para um elemento que só existe quando aberto; referência pendente é ignorada
68
68
  // pela tecnologia assistiva, então não precisa acompanhar o estado.
69
- export function Tooltip({ children, content, side = "top" }) { const id = React.useId(); const portal = usePortalContainer(); return _jsxs(BaseTooltip.Root, { children: [_jsx(BaseTooltip.Trigger, { render: children, "aria-describedby": id }), _jsx(BaseTooltip.Portal, { container: portal, children: _jsx(BaseTooltip.Positioner, { side: side, sideOffset: 8, children: _jsx(BaseTooltip.Popup, { id: id, role: "tooltip", className: "tooltip", children: content }) }) })] }); }
69
+ export function Tooltip({ children, content, side = "top" }) { const id = React.useId(); const triggerId = children.props.id; const portal = usePortalContainer(); return _jsxs(BaseTooltip.Root, { children: [_jsx(BaseTooltip.Trigger, { id: triggerId, render: children, "aria-describedby": id }), _jsx(BaseTooltip.Portal, { container: portal, children: _jsx(BaseTooltip.Positioner, { side: side, sideOffset: 8, children: _jsx(BaseTooltip.Popup, { id: id, role: "tooltip", className: "tooltip", children: content }) }) })] }); }
70
70
  export function Popover({ trigger, title, children, side = "bottom" }) { const portal = usePortalContainer(); return _jsxs(BasePopover.Root, { children: [_jsx(BasePopover.Trigger, { render: trigger }), _jsx(BasePopover.Portal, { container: portal, children: _jsx(BasePopover.Positioner, { side: side, sideOffset: 8, children: _jsxs(BasePopover.Popup, { className: "popover", children: [title && _jsx(BasePopover.Title, { render: _jsx("strong", {}), children: title }), children] }) }) })] }); }
71
71
  // HoverCard (Lote 1 do BUILDING.md). Não é Tooltip nem Popover, e a diferença é de propósito,
72
72
  // não de aparência: a Tooltip é um RÓTULO curto (`role="tooltip"`, some ao mover o mouse); o
package/dist/pure.d.ts CHANGED
@@ -162,6 +162,7 @@ export interface AureaStrings {
162
162
  tocLabel: string;
163
163
  navigationToggle: string;
164
164
  sidebarLabel: string;
165
+ bottomNavLabel: string;
165
166
  universalState: Record<UniversalState, string>;
166
167
  }
167
168
  export declare const defaultStrings: AureaStrings;
package/dist/pure.js CHANGED
@@ -21,10 +21,10 @@ export const universalStates = ["waiting_user", "waiting_approval", "waiting_dep
21
21
  // perdeu qualidade é avisado. Um `role="alert"` aqui interromperia o leitor de tela por uma
22
22
  // condição que não pede ação imediata, que é o oposto do que o papel serve.
23
23
  export const stateSeverity = (state) => state.startsWith("waiting_") ? "info" : "warning";
24
- export const defaultStrings = { 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", carouselLabel: "Carousel", carouselSlide: "Slide", positionOf: "of", carouselPrev: "Previous slide", carouselNext: "Next slide", galleryLabel: "Gallery", 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", qrCode: "QR code", chartLabel: "Chart", copyCode: "Copy code", tocLabel: "On this page", navigationToggle: "Navigation", sidebarLabel: "Sidebar", 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." } };
24
+ export const defaultStrings = { 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", carouselLabel: "Carousel", carouselSlide: "Slide", positionOf: "of", carouselPrev: "Previous slide", carouselNext: "Next slide", galleryLabel: "Gallery", 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", qrCode: "QR code", chartLabel: "Chart", copyCode: "Copy code", tocLabel: "On this page", navigationToggle: "Navigation", sidebarLabel: "Sidebar", bottomNavLabel: "Main", 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." } };
25
25
  // pt-BR preservado como locale (mesmos valores que já eram o default): passe
26
26
  // <AureaProvider strings={ptBR}> para restaurar português.
27
- export const ptBR = { 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", carouselLabel: "Carrossel", carouselSlide: "Slide", positionOf: "de", carouselPrev: "Slide anterior", carouselNext: "Próximo slide", galleryLabel: "Galeria", 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", qrCode: "Código QR", chartLabel: "Gráfico", copyCode: "Copiar código", tocLabel: "Nesta página", navigationToggle: "Navegação", sidebarLabel: "Lateral", 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." } };
27
+ export const ptBR = { 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", carouselLabel: "Carrossel", carouselSlide: "Slide", positionOf: "de", carouselPrev: "Slide anterior", carouselNext: "Próximo slide", galleryLabel: "Galeria", 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", qrCode: "Código QR", chartLabel: "Gráfico", copyCode: "Copiar código", tocLabel: "Nesta página", navigationToggle: "Navegação", sidebarLabel: "Lateral", bottomNavLabel: "Principal", 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." } };
28
28
  // Sprite de ícones: CONFIGURAÇÃO DE APLICAÇÃO, então entra pelo provider, uma vez.
29
29
  // Antes o default absoluto "/aurea-icons.svg" vivia no Icon e 15 componentes declaravam
30
30
  // e repassavam `spriteUrl` à mão — 52 sítios de código. Consequência: aplicação servida
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aurea-uds/react",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "React components for Aurea UDS. Import @aurea-uds/fonts/css and @aurea-uds/core/css alongside.",
5
5
  "keywords": [
6
6
  "aurea",