@aurea-uds/react 0.1.0 → 0.2.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
@@ -14,6 +14,19 @@ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>, Re
14
14
  kbd?: string;
15
15
  }
16
16
  export declare const Button: React.ForwardRefExoticComponent<Omit<ButtonProps, "ref"> & RefAttributes<HTMLButtonElement>>;
17
+ export interface ToggleProps {
18
+ pressed?: boolean;
19
+ defaultPressed?: boolean;
20
+ onPressedChange?: (pressed: boolean) => void;
21
+ icon?: IconName;
22
+ label?: string;
23
+ size?: Extract<ComponentSize, "sm" | "md" | "lg">;
24
+ disabled?: boolean;
25
+ id?: string;
26
+ className?: string;
27
+ children?: React.ReactNode;
28
+ }
29
+ export declare function Toggle({ pressed, defaultPressed, onPressedChange, icon, label, size, disabled, id, className, children }: ToggleProps): React.JSX.Element;
17
30
  export interface IconButtonProps extends Omit<ButtonProps, "children"> {
18
31
  label: string;
19
32
  icon: IconName;
package/dist/actions.js CHANGED
@@ -1,9 +1,11 @@
1
+ "use client";
1
2
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
3
  // Fase 9 (achado A5): este arquivo saiu do index.tsx de 970 linhas. Um módulo por categoria
3
4
  // do registry — a taxonomia já existia e é gateada. A ordem de import entre eles é um DAG:
4
5
  // internal → system → actions → feedback → inputs → navigation → layout → data-display → resto.
5
6
  import { forwardRef } from "react";
6
7
  import { Toolbar as BaseToolbar } from "@base-ui/react/toolbar";
8
+ import { Toggle as BaseToggle } from "@base-ui/react/toggle";
7
9
  import { cx, useAureaStrings, Kbd } from "./internal.js";
8
10
  import { Icon } from "./system.js";
9
11
  // type="button" por default: o default do HTML é submit, e um "Cancelar"/"Remover"
@@ -19,6 +21,9 @@ export const Button = forwardRef(function Button({ variant = "secondary", size =
19
21
  return _jsx("a", { ref: ref, className: cls, ...(off ? { "aria-disabled": true } : { href }), ...shared, ...props, children: inner });
20
22
  return _jsx("button", { ref: ref, type: type, className: cls, disabled: off, "aria-pressed": pressed, ...shared, ...props, children: inner });
21
23
  });
24
+ export function Toggle({ pressed, defaultPressed, onPressedChange, icon, label, size = "md", disabled, id, className, children }) {
25
+ return _jsxs(BaseToggle, { id: id, disabled: disabled, pressed: pressed, defaultPressed: defaultPressed, onPressedChange: onPressedChange, "aria-label": children ? undefined : label, className: cx("btn", "btn-ghost", size !== "md" && `btn-${size}`, !children && "btn-icon", "toggle", className), children: [icon && _jsx(Icon, { name: icon }), children] });
26
+ }
22
27
  // default ghost (não secondary): um ícone-ação solto — hambúrguer, tema, fechar — é sem
23
28
  // caixa por convenção (pedido do Victor: hambúrguer sem borda). Quem quer a caixa passa
24
29
  // variant. Alinha o React ao HTML dos docs, onde .btn-icon já é transparente.
@@ -0,0 +1,209 @@
1
+ import React, { type HTMLAttributes, type OlHTMLAttributes, type ReactNode, type RefAttributes } from "react";
2
+ import { type IconName } from "./system.js";
3
+ export type AgentState = "idle" | "thinking" | "running" | "paused" | "error" | "completed";
4
+ export declare function AgentStatus({ state, label, className, ...props }: HTMLAttributes<HTMLSpanElement> & RefAttributes<HTMLSpanElement> & {
5
+ state?: AgentState;
6
+ label?: ReactNode;
7
+ }): React.JSX.Element;
8
+ export interface AgentCapability {
9
+ name: string;
10
+ description?: string;
11
+ icon?: IconName;
12
+ }
13
+ export declare function AgentCard({ name, description, avatarSrc, model, state, capabilities, actions, className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement> & {
14
+ name: string;
15
+ description?: ReactNode;
16
+ avatarSrc?: string;
17
+ model?: string;
18
+ state?: AgentState;
19
+ capabilities?: AgentCapability[];
20
+ actions?: ReactNode;
21
+ }): React.JSX.Element;
22
+ export declare function AgentInspector({ title, sections, children, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement> & {
23
+ title: ReactNode;
24
+ sections?: Array<{
25
+ label: string;
26
+ items: Array<{
27
+ term: string;
28
+ value: ReactNode;
29
+ }>;
30
+ }>;
31
+ }): React.JSX.Element;
32
+ export interface InvocationStep {
33
+ id: string;
34
+ label: string;
35
+ detail?: string;
36
+ state?: "running" | "done" | "error";
37
+ content?: ReactNode;
38
+ }
39
+ export declare function InvocationPanel({ title, input, steps, output, running, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement> & {
40
+ title?: ReactNode;
41
+ input?: ReactNode;
42
+ steps?: InvocationStep[];
43
+ output?: ReactNode;
44
+ running?: boolean;
45
+ }): React.JSX.Element;
46
+ export type TaskState = "queued" | "running" | "completed" | "failed" | "blocked" | "paused";
47
+ export type TaskPriority = "low" | "medium" | "high";
48
+ export interface QueueTask {
49
+ id: string;
50
+ title: string;
51
+ description?: string;
52
+ state: TaskState;
53
+ priority?: TaskPriority;
54
+ progress?: number;
55
+ }
56
+ export declare function TaskQueue({ tasks, label, onRetry, className, ...props }: OlHTMLAttributes<HTMLOListElement> & RefAttributes<HTMLOListElement> & {
57
+ tasks: QueueTask[];
58
+ label?: string;
59
+ onRetry?: (task: QueueTask) => void;
60
+ }): React.JSX.Element;
61
+ export type RiskLevel = "low" | "medium" | "high";
62
+ export declare function HumanApproval({ title, description, details, risk, reasoning, deadline, decision, onApprove, onDeny, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement> & {
63
+ title: ReactNode;
64
+ description?: ReactNode;
65
+ details?: Array<{
66
+ term: string;
67
+ value: ReactNode;
68
+ }>;
69
+ risk?: RiskLevel;
70
+ reasoning?: ReactNode;
71
+ deadline?: ReactNode;
72
+ decision?: "approved" | "denied";
73
+ onApprove?: () => void;
74
+ onDeny?: () => void;
75
+ }): React.JSX.Element;
76
+ export type PermissionLevel = "ask" | "always" | "never";
77
+ export interface ToolPermissionEntry {
78
+ id: string;
79
+ name: string;
80
+ description?: string;
81
+ scope?: string;
82
+ permission: PermissionLevel;
83
+ }
84
+ export declare function ToolPermission({ tools, onChange, label, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement> & {
85
+ tools: ToolPermissionEntry[];
86
+ onChange?: (id: string, permission: PermissionLevel) => void;
87
+ label?: string;
88
+ }): React.JSX.Element;
89
+ export type EventSeverity = "info" | "success" | "warning" | "danger";
90
+ export interface StreamEvent {
91
+ id: string;
92
+ title: ReactNode;
93
+ time?: ReactNode;
94
+ severity?: EventSeverity;
95
+ detail?: ReactNode;
96
+ group?: string;
97
+ }
98
+ export declare function EventStream({ events, label, follow, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement> & {
99
+ events: StreamEvent[];
100
+ label?: string;
101
+ follow?: boolean;
102
+ }): React.JSX.Element;
103
+ export interface TraceSpan {
104
+ id: string;
105
+ label: ReactNode;
106
+ start: number;
107
+ end: number;
108
+ kind?: string;
109
+ depth?: number;
110
+ error?: boolean;
111
+ }
112
+ export declare function TraceTimeline({ spans, label, className, ...props }: OlHTMLAttributes<HTMLOListElement> & RefAttributes<HTMLOListElement> & {
113
+ spans: TraceSpan[];
114
+ label?: string;
115
+ }): React.JSX.Element;
116
+ export type HealthState = "operational" | "degraded" | "down" | "maintenance" | "unknown";
117
+ export interface HealthEntry {
118
+ id: string;
119
+ name: ReactNode;
120
+ state: HealthState;
121
+ detail?: ReactNode;
122
+ }
123
+ export declare function HealthMatrix({ entries, label, className, ...props }: HTMLAttributes<HTMLUListElement> & RefAttributes<HTMLUListElement> & {
124
+ entries: HealthEntry[];
125
+ label?: string;
126
+ }): React.JSX.Element;
127
+ export type UsageMetric = "tokens" | "cost" | "requests";
128
+ export interface ModelUsageEntry {
129
+ id: string;
130
+ model: string;
131
+ provider?: string;
132
+ tokens?: number;
133
+ cost?: number;
134
+ requests?: number;
135
+ }
136
+ export declare function ModelUsage({ entries, metric, label, currency, locale, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement> & {
137
+ entries: ModelUsageEntry[];
138
+ metric?: UsageMetric;
139
+ label?: string;
140
+ currency?: string;
141
+ locale?: string;
142
+ }): React.JSX.Element;
143
+ export interface CostSegment {
144
+ id: string;
145
+ label: ReactNode;
146
+ amount: number;
147
+ }
148
+ export type CostState = "under" | "near" | "over";
149
+ export declare function CostMeter({ spent, limit, softLimit, currency, locale, period, segments, label, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement> & {
150
+ spent: number;
151
+ limit?: number;
152
+ softLimit?: number;
153
+ currency?: string;
154
+ locale?: string;
155
+ period?: ReactNode;
156
+ segments?: CostSegment[];
157
+ label?: string;
158
+ }): React.JSX.Element;
159
+ export type MemoryScope = "episodic" | "semantic" | "procedural";
160
+ export type MemoryOperation = "added" | "updated" | "recalled" | "forgotten";
161
+ export interface MemoryRecord {
162
+ id: string;
163
+ content: ReactNode;
164
+ scope: MemoryScope;
165
+ operation: MemoryOperation;
166
+ time?: ReactNode;
167
+ source?: ReactNode;
168
+ details?: Array<{
169
+ term: string;
170
+ value: ReactNode;
171
+ }>;
172
+ }
173
+ export declare function MemoryLedger({ records, label, className, ...props }: OlHTMLAttributes<HTMLOListElement> & RefAttributes<HTMLOListElement> & {
174
+ records: MemoryRecord[];
175
+ label?: string;
176
+ }): React.JSX.Element;
177
+ export type MessageKind = "request" | "response" | "handoff" | "broadcast" | "error";
178
+ export interface AgentMessage {
179
+ id: string;
180
+ from: string;
181
+ to?: string;
182
+ body: ReactNode;
183
+ time?: ReactNode;
184
+ kind?: MessageKind;
185
+ reason?: ReactNode;
186
+ details?: Array<{
187
+ term: string;
188
+ value: ReactNode;
189
+ }>;
190
+ }
191
+ export declare function InterAgentMessage({ messages, label, className, ...props }: OlHTMLAttributes<HTMLOListElement> & RefAttributes<HTMLOListElement> & {
192
+ messages: AgentMessage[];
193
+ label?: string;
194
+ }): React.JSX.Element;
195
+ export declare function AutomationCard({ name, description, trigger, action, enabled, onToggle, lastRun, lastResult, details, actions, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement> & {
196
+ name: ReactNode;
197
+ description?: ReactNode;
198
+ trigger: ReactNode;
199
+ action: ReactNode;
200
+ enabled?: boolean;
201
+ onToggle?: (enabled: boolean) => void;
202
+ lastRun?: ReactNode;
203
+ lastResult?: "success" | "failure";
204
+ details?: Array<{
205
+ term: string;
206
+ value: ReactNode;
207
+ }>;
208
+ actions?: ReactNode;
209
+ }): React.JSX.Element;
package/dist/agents.js ADDED
@@ -0,0 +1,302 @@
1
+ "use client";
2
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ // A camada operacional — PLANO-1.0, Parte H (09/08/2026).
4
+ //
5
+ // Um módulo por categoria do registry, como os outros (Fase 9, achado A5). A categoria
6
+ // é NOVA: "AI & Agents", da macroárea 18 do `DIRECTION.md`. Ela não estava na lista
7
+ // travada dos 13, e a decisão de acrescentá-la está na
8
+ // [ADR-0017](../../../decisions/0017-categoria-ai-agents.md) — porque o §2 do
9
+ // `DIRECTION.md` se declara "ilustrativo, não-vinculante", então tirar dali uma
10
+ // categoria é decisão, não dedução.
11
+ //
12
+ // PROCEDÊNCIA (BUILDING.md passo 2): estes três saem de `agents-kit-main`
13
+ // (`components/agents-ui/agent-card.tsx`, `agent-status-panel.tsx`) e do `DetailsView/`
14
+ // do `agent-prism-main`. As sete referências antigas NÃO têm esta família — foi por
15
+ // isso que a Parte H ficou bloqueada até 08/08/2026.
16
+ //
17
+ // Escopo menor que o da referência (passo 5): o `AgentCard` de lá despacha ações por
18
+ // STRING (`onAction: (action: string) => void`), o que troca o compilador por um acordo
19
+ // verbal. Aqui as ações entram como nó, e quem monta o botão sabe o que ele faz.
20
+ import React from "react";
21
+ import { cx, useAureaStrings } from "./internal.js";
22
+ import { Icon } from "./system.js";
23
+ import { Status, Badge, Progress, Alert } from "./feedback.js";
24
+ import { Avatar } from "./identity.js";
25
+ import { DataList } from "./data-display.js";
26
+ import { SegmentedControl, Switch } from "./inputs.js";
27
+ import { Button, IconButton } from "./actions.js";
28
+ // Só a variante: o `Status` já desenha o ponto, e um ícone ao lado dele seria a mesma
29
+ // informação duas vezes. A primeira versão deste mapa tinha um ícone por estado e
30
+ // nenhum era renderizado — código morto nascendo junto com o componente.
31
+ const ESTADO = {
32
+ idle: "neutral", thinking: "info", running: "info", paused: "warning", error: "danger", completed: "success",
33
+ };
34
+ // AgentStatus — o estado, e nada além dele.
35
+ // É `Status` com o vocabulário fixo desta família. Não vale um componente novo pela
36
+ // aparência; vale por CONTRATO: sem ele cada aplicação escreveria o seu par
37
+ // estado→variante, e a mesma condição apareceria de seis jeitos na mesma tela — que é
38
+ // exatamente o que a Parte J existe para impedir, um nível acima.
39
+ export function AgentStatus({ state = "idle", label, className, ...props }) {
40
+ const s = useAureaStrings();
41
+ return _jsx(Status, { variant: ESTADO[state], className: className, "data-state": state, ...props, children: label ?? s.agentState[state] });
42
+ }
43
+ // AgentCard — a identidade do agente: quem é, em que estado está, o que sabe fazer.
44
+ export function AgentCard({ name, description, avatarSrc, model, state, capabilities, actions, className, ...props }) {
45
+ return _jsxs("article", { className: cx("card", "agent-card", className), ...props, children: [_jsxs("header", { className: "agent-card-head", children: [_jsx(Avatar, { src: avatarSrc, alt: name, fallback: name.slice(0, 2), size: "md" }), _jsxs("div", { className: "agent-card-id", children: [_jsx("strong", { children: name }), model && _jsx("span", { className: "hint", children: model })] }), state && _jsx(AgentStatus, { state: state })] }), description && _jsx("p", { className: "agent-card-desc", children: description }), !!capabilities?.length && _jsx("ul", { className: "agent-caps", children: capabilities.map(c => _jsxs("li", { className: "agent-cap", title: c.description, children: [c.icon && _jsx(Icon, { name: c.icon, size: "sm" }), _jsx("span", { children: c.name })] }, c.name)) }), actions && _jsx("footer", { className: "agent-card-actions", children: actions })] });
46
+ }
47
+ // AgentInspector — o detalhe: configuração, ferramentas, instruções.
48
+ // A anatomia é a do `DetailsView/` do `agent-prism`: cabeçalho + seções rotuladas, com
49
+ // o valor cru disponível. Aqui as seções são `DataList`, que já existe e já tem pele —
50
+ // e o corpo livre entra como filho, para inspecionar o que a ficha não previu.
51
+ //
52
+ // O rótulo de seção NÃO é `<h3>`, e isso foi corrigido em 09/08/2026 por defeito medido: um
53
+ // componente não sabe a que profundidade está na página, e fixar um nível produz salto de
54
+ // hierarquia assim que ele entra sob um `<h1>` — foi o que a varredura do catálogo acusou
55
+ // (`salto h1 → h3`) no minuto em que a prévia dele passou a renderizar. Cada seção vira um
56
+ // `group` NOMEADO pelo próprio rótulo: o leitor de tela continua sabendo onde começa cada
57
+ // bloco, e ninguém precisa adivinhar o nível certo.
58
+ export function AgentInspector({ title, sections, children, className, ...props }) {
59
+ const s = useAureaStrings();
60
+ const uid = React.useId();
61
+ return _jsxs("section", { className: cx("card", "agent-inspector", className), "aria-label": typeof title === "string" ? title : s.agentInspector, ...props, children: [_jsx("header", { className: "agent-inspector-head", children: _jsx("strong", { children: title }) }), sections?.map((sec, i) => _jsxs("div", { className: "agent-inspector-section", role: "group", "aria-labelledby": `${uid}-${i}`, children: [_jsx("p", { id: `${uid}-${i}`, className: "agent-inspector-label", children: sec.label }), _jsx(DataList, { items: sec.items })] }, sec.label)), children] });
62
+ }
63
+ // InvocationPanel — UMA execução: o que foi pedido, os passos, o que saiu.
64
+ //
65
+ // O passo que tem corpo é um `<details>` nativo, o mesmo idioma do `Accordion`: dobrar
66
+ // e desdobrar já é comportamento de plataforma, com teclado e ARIA, e a referência
67
+ // gasta um `Collapsible` de biblioteca para chegar no mesmo lugar.
68
+ //
69
+ // `running` marca `aria-busy` na região INTEIRA em vez de animar o texto. A referência
70
+ // usa um `TextShimmer` — animação em cima do rótulo — e isso é decoração que um leitor
71
+ // de tela não alcança e que `prefers-reduced-motion` teria de desfazer.
72
+ //
73
+ // Entrada e saída são `group` NOMEADO, e não `<h3>` — mesmo defeito e mesma correção do
74
+ // `AgentInspector` (09/08/2026): nível de título fixo dentro de um componente vira salto de
75
+ // hierarquia na página que o hospeda.
76
+ export function InvocationPanel({ title, input, steps, output, running, className, ...props }) {
77
+ const s = useAureaStrings();
78
+ const uid = React.useId();
79
+ return _jsxs("section", { className: cx("card", "invocation", className), "aria-label": typeof title === "string" ? title : s.invocationLabel, "aria-busy": running || undefined, ...props, children: [title && _jsxs("header", { className: "invocation-head", children: [_jsx("strong", { children: title }), running && _jsx(AgentStatus, { state: "running" })] }), input && _jsxs("div", { className: "invocation-io", role: "group", "aria-labelledby": `${uid}-in`, children: [_jsx("p", { id: `${uid}-in`, className: "invocation-label", children: s.invocationInput }), _jsx("div", { children: input })] }), !!steps?.length && _jsx("ol", { className: "invocation-steps", children: steps.map(st => _jsx("li", { className: "invocation-step", "data-state": st.state ?? "done", children: st.content
80
+ ? _jsxs("details", { children: [_jsxs("summary", { children: [st.label, st.detail && _jsxs("span", { className: "hint", children: [" \u00B7 ", st.detail] })] }), _jsx("div", { className: "invocation-step-body", children: st.content })] })
81
+ : _jsxs("span", { children: [st.label, st.detail && _jsxs("span", { className: "hint", children: [" \u00B7 ", st.detail] })] }) }, st.id)) }), output && _jsxs("div", { className: "invocation-io", role: "group", "aria-labelledby": `${uid}-out`, children: [_jsx("p", { id: `${uid}-out`, className: "invocation-label", children: s.invocationOutput }), _jsx("div", { children: output })] })] });
82
+ }
83
+ // Os seis estados e os três degraus de prioridade são os da referência, medidos.
84
+ const TAREFA = {
85
+ queued: "neutral", running: "info", completed: "success", failed: "danger", blocked: "warning", paused: "warning",
86
+ };
87
+ // TaskQueue — a fila de trabalho.
88
+ //
89
+ // ESCOPO MENOR QUE O DA REFERÊNCIA, e por fronteira, não por preguiça: o `AgentTask` de
90
+ // lá tem 15 campos, e cinco deles pertencem a OUTROS componentes desta mesma parte —
91
+ // `metrics.tokens` e `metrics.cost` são o `ModelUsage` (H11) e o `CostMeter` (H12),
92
+ // `checkpoints` é o `TraceTimeline` (H9), `assignee` é o `AgentCard` (H1). Absorvê-los
93
+ // aqui faria a fila responder por quatro contratos e nenhum deles direito.
94
+ export function TaskQueue({ tasks, label, onRetry, className, ...props }) {
95
+ const s = useAureaStrings();
96
+ return _jsx("ol", { className: cx("task-queue", className), "aria-label": label ?? s.taskQueueLabel, ...props, children: tasks.map(t => _jsxs("li", { className: "task-item", "data-state": t.state, children: [_jsxs("div", { className: "task-line", children: [_jsx("span", { className: "task-title", children: t.title }), t.priority && _jsx(Badge, { variant: t.priority === "high" ? "warning" : "neutral", children: s.taskPriority[t.priority] }), _jsx(Status, { variant: TAREFA[t.state], children: s.taskState[t.state] }), t.state === "failed" && onRetry && _jsx(IconButton, { variant: "ghost", size: "sm", icon: "restart", label: `${s.uploadRetry} ${t.title}`, onClick: () => onRetry(t) })] }), t.description && _jsx("p", { className: "task-desc", children: t.description }), t.state === "running" && t.progress != null && _jsx(Progress, { value: Math.round(t.progress * 100), label: t.title })] }, t.id)) });
97
+ }
98
+ // HumanApproval — o portão: o que vai acontecer, e a decisão de uma pessoa.
99
+ export function HumanApproval({ title, description, details, risk, reasoning, deadline, decision, onApprove, onDeny, className, ...props }) {
100
+ const s = useAureaStrings();
101
+ return _jsxs("section", { className: cx("card", "approval", className), "aria-label": typeof title === "string" ? title : s.approvalLabel, ...props, children: [_jsxs("header", { className: "approval-head", children: [_jsx("strong", { children: title }), risk && _jsx(Badge, { variant: risk === "high" ? "danger" : risk === "medium" ? "warning" : "neutral", children: s.approvalRisk[risk] })] }), description && _jsx("p", { className: "approval-desc", children: description }), !!details?.length && _jsx(DataList, { items: details }), reasoning && _jsx("p", { className: "approval-reason", children: reasoning }), deadline && _jsxs("p", { className: "hint", children: [s.approvalDeadline, ": ", deadline] }), decision
102
+ ? _jsx(Alert, { variant: decision === "approved" ? "success" : "warning", children: decision === "approved" ? s.approvalApproved : s.approvalDenied })
103
+ : _jsxs("footer", { className: "approval-actions", children: [_jsx(Button, { variant: "secondary", onClick: onDeny, children: s.approvalDeny }), _jsx(Button, { variant: "primary", onClick: onApprove, children: s.approvalApprove })] })] });
104
+ }
105
+ // ToolPermission — o que cada ferramenta pode, sem perguntar de novo.
106
+ //
107
+ // A escolha de três vias é um `SegmentedControl`, que já é `radiogroup` do Base UI
108
+ // (ADR-0016): setas que movem E selecionam, `Home`/`End`, roving tabindex. Escrever
109
+ // três botões alternáveis aqui repetiria à mão o padrão que aquela ADR rejeitou.
110
+ export function ToolPermission({ tools, onChange, label, className, ...props }) {
111
+ const s = useAureaStrings();
112
+ const opcoes = [{ value: "ask", label: s.permissionAsk }, { value: "always", label: s.permissionAlways }, { value: "never", label: s.permissionNever }];
113
+ return _jsx("section", { className: cx("card", "tool-permission", className), "aria-label": label ?? s.permissionLabel, ...props, children: _jsx("ul", { className: "tool-permission-list", children: tools.map(t => _jsxs("li", { className: "tool-permission-item", children: [_jsxs("div", { className: "tool-permission-id", children: [_jsx("strong", { children: t.name }), t.scope && _jsx("code", { className: "tool-permission-scope", children: t.scope }), t.description && _jsx("span", { className: "hint", children: t.description })] }), _jsx(SegmentedControl, { items: opcoes, value: t.permission, label: `${t.name}${t.scope ? " " + t.scope : ""}`, onChange: v => onChange?.(t.id, v) })] }, t.id)) }) });
114
+ }
115
+ // EventStream — o que aconteceu, em ordem, ao vivo.
116
+ //
117
+ // NÃO é o `LogStream`, e a diferença é de PAPEL, não de aparência: `role="log"` é para
118
+ // saída de texto que se acumula; isto é `role="feed"` do APG — uma lista de artigos que
119
+ // a pessoa percorre, cada um com título, hora e gravidade próprios. Um evento tem
120
+ // estrutura; uma linha de log é texto.
121
+ export function EventStream({ events, label, follow, className, ...props }) {
122
+ const s = useAureaStrings();
123
+ const fim = React.useRef(null);
124
+ // "Seguir o fim" é o comportamento que distingue um fluxo ao vivo de uma lista: sem
125
+ // ele, quem está lendo o topo perde o que chega. Com ele E sem controle, quem está
126
+ // lendo o MEIO é arrastado para baixo — por isso é uma prop, e não o default.
127
+ React.useEffect(() => { if (follow)
128
+ fim.current?.scrollIntoView({ block: "end" }); }, [events.length, follow]);
129
+ const grupos = events.reduce((acc, e) => {
130
+ const ultimo = acc[acc.length - 1];
131
+ if (ultimo && ultimo.nome === e.group)
132
+ ultimo.itens.push(e);
133
+ else
134
+ acc.push({ nome: e.group, itens: [e] });
135
+ return acc;
136
+ }, []);
137
+ // O `feed` fica NO GRUPO, e não por fora, e isso é correção medida de 09/08/2026: `feed` só
138
+ // aceita `article` como filho, e o cabeçalho de grupo — que era um `<h3>` — reprovava em
139
+ // `aria-required-children` E em ordem de título, os dois achados pela varredura assim que a
140
+ // prévia do catálogo parou de sair vazia. Agora cada grupo é um feed com NOME próprio (a data),
141
+ // o rótulo deixou de ser título de nível fixo, e sem agrupamento nenhum o feed único continua
142
+ // se chamando como o componente todo.
143
+ return _jsxs("section", { className: cx("event-stream", className), "aria-label": label ?? s.eventStreamLabel, "aria-busy": follow || undefined, ...props, children: [grupos.map((g, gi) => _jsxs(React.Fragment, { children: [g.nome && _jsx("p", { className: "event-group", children: g.nome }), _jsx("div", { className: "event-group-feed", role: "feed", "aria-label": g.nome ?? label ?? s.eventStreamLabel, children: g.itens.map(e => _jsxs("article", { className: "event-item", "data-severity": e.severity ?? "info", "aria-labelledby": `ev-${e.id}`, children: [_jsx("span", { className: "event-dot", "aria-hidden": "true" }), _jsxs("div", { className: "event-body", children: [_jsx("span", { id: `ev-${e.id}`, children: e.title }), e.detail && _jsx("span", { className: "hint", children: e.detail })] }), e.time && _jsx("time", { className: "event-time", children: e.time })] }, e.id)) })] }, g.nome ?? gi)), _jsx("div", { ref: fim })] });
144
+ }
145
+ // TraceTimeline — quanto cada passo demorou, em cascata.
146
+ //
147
+ // NÃO é o `Timeline` que já existe: aquele é uma coluna de momentos (ponto, título,
148
+ // hora); este é uma cascata de DURAÇÕES, onde a posição e a largura da barra são o dado.
149
+ // A matemática é a da referência: cada barra é (start-min)/(max-min) de deslocamento e
150
+ // (end-start)/(max-min) de largura.
151
+ //
152
+ // O que NÃO entrou: as ONZE cores por categoria de span da referência
153
+ // (`llm_call`, `tool_execution`, `retrieval`…). Cor por categoria numa paleta travada é
154
+ // o mesmo defeito que o H.a recusou; `kind` entra como TEXTO, que é legível também por
155
+ // quem não distingue as cores.
156
+ export function TraceTimeline({ spans, label, className, ...props }) {
157
+ const s = useAureaStrings();
158
+ const min = Math.min(...spans.map(x => x.start), 0);
159
+ const max = Math.max(...spans.map(x => x.end), min + 1);
160
+ const janela = max - min || 1;
161
+ return _jsx("ol", { className: cx("trace", className), "aria-label": label ?? s.traceLabel, ...props, children: spans.map(sp => {
162
+ const off = ((sp.start - min) / janela) * 100, larg = Math.max(((sp.end - sp.start) / janela) * 100, 1);
163
+ return _jsxs("li", { className: "trace-span", "data-error": sp.error || undefined, style: { ["--trace-depth"]: String(sp.depth ?? 0) }, children: [_jsxs("span", { className: "trace-label", children: [sp.label, sp.kind && _jsxs("span", { className: "hint", children: [" \u00B7 ", sp.kind] })] }), _jsx("span", { className: "trace-track", role: "meter", "aria-label": typeof sp.label === "string" ? sp.label : s.traceLabel, "aria-valuemin": min, "aria-valuemax": max, "aria-valuenow": sp.end - sp.start, "aria-valuetext": `${sp.end - sp.start}`, children: _jsx("span", { className: "trace-bar", style: { insetInlineStart: `${off}%`, inlineSize: `${larg}%` } }) })] }, sp.id);
164
+ }) });
165
+ }
166
+ const SAUDE = {
167
+ operational: "success", degraded: "warning", down: "danger", maintenance: "info", unknown: "neutral",
168
+ };
169
+ // HealthMatrix — o que está de pé, numa grade.
170
+ export function HealthMatrix({ entries, label, className, ...props }) {
171
+ const s = useAureaStrings();
172
+ return _jsx("ul", { className: cx("health-matrix", className), "aria-label": label ?? s.healthLabel, ...props, children: entries.map(e => _jsxs("li", { className: "health-cell", "data-state": e.state, children: [_jsx("span", { className: "health-name", children: e.name }), _jsx(Status, { variant: SAUDE[e.state], children: s.healthState[e.state] }), e.detail && _jsx("span", { className: "hint", children: e.detail })] }, e.id)) });
173
+ }
174
+ // ─────────────────────────────────────────────────────────────────────────────
175
+ // H.e — custo e memória: quanto se consumiu, contra que teto, e o que ficou guardado.
176
+ //
177
+ // PROCEDÊNCIA: `langfuse-main/web/src/features/dashboard/components/` — o
178
+ // `ModelUsageChart.tsx` (a métrica total no topo e a quebra por modelo), o
179
+ // `ModelCostTable.tsx` (as colunas modelo × tokens × custo, com o número à direita), o
180
+ // `TotalMetric.tsx` (número grande + descrição, e é UMA linha de arranjo) e o
181
+ // `cards/BarListChartArea.tsx` (a lista de barras horizontais com rótulo de valor).
182
+ // Mais `agent-prism-main/packages/ui/src/components/{TokensBadge,PriceBadge}.tsx` — o par
183
+ // de unidades desta família, contagem e preço — e `agents-kit-main/components/agents-ui/
184
+ // agent-status-panel.tsx`, que traz a tarifa por 1k tokens com entrada e saída separadas.
185
+ //
186
+ // O `MemoryLedger` NÃO TEM REFERÊNCIA, e é o caso declarado no `BUILDING.md` §1: nasce de
187
+ // pesquisa registrada no `REFERENCES.md` e de composição. A pesquisa está lá com data.
188
+ // Formatação de número: `Intl` é a plataforma, e o locale entra como prop com default
189
+ // FIXO. O default fixo é o que mantém a saída determinística no SSR do catálogo e no gate
190
+ // de pixel — locale do ambiente mudaria o texto entre a máquina e a CI. A referência faz
191
+ // igual: o `costFormatter` do langfuse é `Intl.NumberFormat("en-US")` pregado, medido em
192
+ // `web/src/utils/numbers.ts`.
193
+ const compacto = (n, locale) => new Intl.NumberFormat(locale, { notation: "compact", maximumFractionDigits: 2 }).format(n);
194
+ // Duas casas fixas é o que o `costFormatter` da referência usa, e aqui isso MENTE: custo de
195
+ // modelo cai em fração de centavo o tempo todo, e "$0.00" para um gasto real de US$ 0,004
196
+ // apaga o número justamente no componente que existe para vigiá-lo.
197
+ const dinheiro = (n, currency, locale) => new Intl.NumberFormat(locale, { style: "currency", currency, minimumFractionDigits: 2, maximumFractionDigits: n !== 0 && Math.abs(n) < 0.01 ? 6 : 2 }).format(n);
198
+ // ModelUsage — o consumo repartido POR MODELO.
199
+ //
200
+ // NÃO é o `CostMeter`, e a diferença é de PAPEL, como a do `EventStream` para o `LogStream`:
201
+ // aqui a barra é FATIA DE UMA SOMA — o teto é o próprio total, e a pergunta é "qual modelo
202
+ // levou quanto". No `CostMeter` o teto vem de fora, e a pergunta é "quanto ainda cabe".
203
+ // Trocar um pelo outro é mostrar orçamento onde não existe orçamento nenhum.
204
+ //
205
+ // ESCOPO MENOR QUE O DA REFERÊNCIA (passo 5): as quatro abas de lá (`Cost by model`,
206
+ // `Cost by type`, `Usage by model`, `Usage by type`) existem porque são quatro CONSULTAS
207
+ // diferentes no produto dela. Aqui a dimensão é uma prop e os dados chegam prontos. Também
208
+ // ficaram fora o seletor de modelos em popover e a série temporal — a série é o `Chart`,
209
+ // que já existe, e embutir um segundo gráfico aqui duplicaria aquele contrato.
210
+ export function ModelUsage({ entries, metric = "tokens", label, currency = "USD", locale = "en-US", className, ...props }) {
211
+ const s = useAureaStrings();
212
+ const valor = (e) => (metric === "cost" ? e.cost : metric === "requests" ? e.requests : e.tokens) ?? 0;
213
+ const fmt = (n) => metric === "cost" ? dinheiro(n, currency, locale) : compacto(n, locale);
214
+ const total = entries.reduce((a, e) => a + valor(e), 0);
215
+ // Ordem decrescente pela métrica, como a referência (`orderBy` em `ModelCostTable`): uma
216
+ // lista de barras fora de ordem obriga a varrer tudo para achar o maior, que é a única
217
+ // coisa que ela existe para responder de relance. Cópia, não `sort` no array de quem chamou.
218
+ const linhas = [...entries].sort((a, b) => valor(b) - valor(a));
219
+ return _jsxs("section", { className: cx("card", "model-usage", className), "aria-label": label ?? s.modelUsageLabel, ...props, children: [_jsxs("header", { className: "metric-total", children: [_jsx("strong", { children: fmt(total) }), _jsx("span", { className: "hint", children: s.usageMetric[metric] })] }), _jsx("ul", { className: "model-usage-list", children: linhas.map(e => {
220
+ const v = valor(e), pct = total > 0 ? (v / total) * 100 : 0;
221
+ return _jsxs("li", { className: "model-usage-row", children: [_jsxs("span", { className: "model-usage-name", children: [e.model, e.provider && _jsxs("span", { className: "hint", children: [" \u00B7 ", e.provider] })] }), _jsx("span", { className: "model-usage-track", role: "meter", "aria-label": e.model, "aria-valuemin": 0, "aria-valuemax": total || 1, "aria-valuenow": v, "aria-valuetext": fmt(v), children: _jsx("span", { className: "model-usage-bar", style: { inlineSize: `${pct}%` } }) }), _jsx("span", { className: "model-usage-value", children: fmt(v) })] }, e.id);
222
+ }) })] });
223
+ }
224
+ // CostMeter — o gasto contra um TETO.
225
+ //
226
+ // Os dois limites são os do LiteLLM, que é o padrão de mercado de controle de custo de LLM
227
+ // medido em 09/08/2026 (pesquisa registrada no `REFERENCES.md`): o limite RÍGIDO bloqueia,
228
+ // o limite BRANDO só avisa. Nenhuma das nove referências locais tem orçamento — o langfuse
229
+ // OSS mostra custo e não teto —, então isto veio pelo passo 4 do `BUILDING.md`, pesquisado
230
+ // antes de escrever, e não de memória.
231
+ //
232
+ // Sem `softLimit` NÃO EXISTE estado de aviso. A tentação era derivar um em 80% do teto;
233
+ // 80% é um número inventado, e um alerta que aparece sozinho num limiar que ninguém
234
+ // configurou é ruído com aparência de política.
235
+ export function CostMeter({ spent, limit, softLimit, currency = "USD", locale = "en-US", period, segments, label, className, ...props }) {
236
+ const s = useAureaStrings();
237
+ const fmt = (n) => dinheiro(n, currency, locale);
238
+ const estado = limit != null && spent >= limit ? "over" : softLimit != null && spent >= softLimit ? "near" : "under";
239
+ const temTeto = limit != null && limit > 0;
240
+ return _jsxs("section", { className: cx("card", "cost-meter", className), "data-state": estado, "aria-label": label ?? s.costMeterLabel, ...props, children: [_jsxs("header", { className: "metric-total", children: [_jsx("strong", { children: fmt(spent) }), _jsx("span", { className: "hint", children: period ?? s.costMeterSpent })] }), temTeto && _jsxs(_Fragment, { children: [_jsx("span", { className: "cost-meter-track", role: "meter", "aria-label": typeof label === "string" ? label : s.costMeterLabel, "aria-valuemin": 0, "aria-valuemax": limit, "aria-valuenow": Math.min(spent, limit), "aria-valuetext": `${fmt(spent)} / ${fmt(limit)}`, children: _jsx("span", { className: "cost-meter-bar", style: { inlineSize: `${Math.min((spent / limit) * 100, 100)}%` } }) }), _jsxs("p", { className: "hint", children: [spent < limit ? `${fmt(limit - spent)} ${s.costMeterRemaining}` : s.costMeterExceeded, " \u00B7 ", fmt(limit)] })] }), !!segments?.length && _jsx(DataList, { items: segments.map(g => ({ term: g.label, value: fmt(g.amount) })) }), estado !== "under" && _jsx(Alert, { variant: estado === "over" ? "danger" : "warning", children: estado === "over" ? s.costMeterOver : s.costMeterNear })] });
241
+ }
242
+ const LANCAMENTO = {
243
+ added: "success", updated: "info", recalled: "neutral", forgotten: "warning",
244
+ };
245
+ // MemoryLedger — o que o agente guardou, esqueceu ou lembrou, e DE ONDE veio.
246
+ //
247
+ // É o único da Parte H sem referência no mundo aberto: o ADE do Letta só abre o servidor, o
248
+ // OpenMemory do mem0 está sendo descontinuado e o painel do mem0 é só na nuvem. Medido em
249
+ // 08/08/2026 e reconfirmado em 09/08.
250
+ //
251
+ // Livro-razão é APENDE-SÓ, e é isso que o separa de uma lista de memórias: `forgotten` não
252
+ // tira a linha, registra o esquecimento. Uma tela que apaga a linha ao esquecer perde
253
+ // exatamente a informação que se procura quando o agente para de saber uma coisa.
254
+ //
255
+ // NÃO usa o `DataGrid`, e a razão é medida: `data-grid.tsx` mora em subpath próprio porque
256
+ // carrega o `@tanstack/react-table` como peer OPCIONAL (check 19), e este módulo sai pelo
257
+ // barril leve. Importá-lo aqui faria quem instala a biblioteca pelo Button passar a precisar
258
+ // da tabela. O plano previa o contrário; a fronteira do pacote vence o plano. Quem quiser
259
+ // ordenar e filtrar o razão compõe as duas coisas na aplicação — o exemplo do catálogo mostra.
260
+ export function MemoryLedger({ records, label, className, ...props }) {
261
+ const s = useAureaStrings();
262
+ return _jsx("ol", { className: cx("memory-ledger", className), "aria-label": label ?? s.memoryLabel, ...props, children: records.map(r => _jsxs("li", { className: "memory-entry", "data-operation": r.operation, "data-scope": r.scope, children: [_jsxs("div", { className: "memory-line", children: [_jsx(Badge, { variant: LANCAMENTO[r.operation], children: s.memoryOperation[r.operation] }), _jsx(Badge, { children: s.memoryScope[r.scope] }), _jsx("span", { className: "memory-content", children: r.content }), r.time && _jsx("time", { className: "memory-time", children: r.time })] }), (r.source || r.details?.length) && _jsxs("details", { className: "memory-provenance", children: [_jsx("summary", { children: s.memoryProvenance }), r.source && _jsx("p", { className: "memory-source", children: r.source }), !!r.details?.length && _jsx(DataList, { items: r.details })] })] }, r.id)) });
263
+ }
264
+ const RECADO = {
265
+ request: "info", response: "success", handoff: "primary", broadcast: "neutral", error: "danger",
266
+ };
267
+ // InterAgentMessage — o recado de um agente para outro.
268
+ //
269
+ // NÃO é o `MessageList`, e a diferença é de PAPEL, como todas as desta parte: aquele é uma
270
+ // conversa com uma PESSOA — autor, corpo, hora, recibo de leitura. Aqui a DIREÇÃO é o dado:
271
+ // tem um remetente e um destinatário, e é a passagem entre os dois que se está lendo. Um
272
+ // `MessageList` com dois autores não diz quem entregou o quê a quem.
273
+ //
274
+ // O que NÃO entrou: as seis cores por intenção do `agent-routing-hub` (`technical` ciano,
275
+ // `billing` âmbar, `sales` ardósia…). É a TERCEIRA vez que esta parte recusa a mesma coisa —
276
+ // depois das onze de span no H.d e das seis de estado no H.a. Cor por categoria numa paleta
277
+ // travada não é legível para quem não separa as cores. A `kind` entra como palavra, num selo.
278
+ export function InterAgentMessage({ messages, label, className, ...props }) {
279
+ const s = useAureaStrings();
280
+ return _jsx("ol", { className: cx("agent-messages", className), "aria-label": label ?? s.agentMessageLabel, ...props, children: messages.map(m => {
281
+ const destino = m.to ?? s.agentMessageBroadcast;
282
+ return _jsxs("li", { className: "agent-message", "data-kind": m.kind ?? "handoff", children: [_jsxs("div", { className: "agent-message-line", children: [_jsxs("span", { className: "agent-message-route", role: "group", "aria-label": `${m.from} ${s.agentMessageTo} ${destino}`, children: [_jsx("strong", { children: m.from }), _jsx(Icon, { name: "arrow--right", size: "sm", className: "agent-message-arrow" }), m.to ? _jsx("strong", { children: m.to }) : _jsx("span", { className: "hint", children: destino })] }), _jsx(Badge, { variant: RECADO[m.kind ?? "handoff"], children: s.agentMessageKind[m.kind ?? "handoff"] }), m.time && _jsx("time", { className: "agent-message-time", children: m.time })] }), _jsx("p", { className: "agent-message-body", children: m.body }), (m.reason || m.details?.length) && _jsxs("details", { className: "agent-message-why", children: [_jsx("summary", { children: s.agentMessageReason }), m.reason && _jsx("p", { className: "agent-message-reason", children: m.reason }), !!m.details?.length && _jsx(DataList, { items: m.details })] })] }, m.id);
283
+ }) });
284
+ }
285
+ // AutomationCard — a regra que roda sozinha: QUANDO isto, ENTÃO aquilo.
286
+ //
287
+ // A anatomia é a do `AutomationSidebar` do langfuse, medida: nome, gatilho (fonte de evento) e
288
+ // ação (tipo), mais o estado ativo/inativo. É isso que separa este cartão do `AgentCard`, que é
289
+ // identidade, e da `TaskQueue`, que é trabalho enfileirado: uma automação é uma REGRA, e regra
290
+ // é uma condição e uma consequência.
291
+ //
292
+ // O par QUANDO/ENTÃO entra em `DataList`, que já existe e já é o par termo/valor da casa — a
293
+ // mesma escolha do `HumanApproval` para os parâmetros, e pelo mesmo motivo: quem lê precisa
294
+ // achar a condição sem varrer um parágrafo.
295
+ //
296
+ // O que NÃO entrou: o histórico de execuções. Na referência ele é uma aba com tabela dentro do
297
+ // mesmo componente; aqui já existem `DataGrid` e `EventStream` para isso, e absorvê-lo faria o
298
+ // cartão responder por dois contratos — o erro que o `TaskQueue` recusou no H.b.
299
+ export function AutomationCard({ name, description, trigger, action, enabled, onToggle, lastRun, lastResult, details, actions, className, ...props }) {
300
+ const s = useAureaStrings();
301
+ return _jsxs("article", { className: cx("card", "automation", className), "data-enabled": enabled ?? undefined, ...props, children: [_jsxs("header", { className: "automation-head", children: [_jsxs("div", { className: "automation-id", children: [_jsx("strong", { children: name }), description && _jsx("span", { className: "hint", children: description })] }), onToggle && _jsx(Switch, { checked: !!enabled, onChange: e => onToggle(e.target.checked), label: s.automationEnabled })] }), _jsx(DataList, { items: [{ term: s.automationWhen, value: trigger }, { term: s.automationThen, value: action }, ...(details ?? [])] }), (lastRun || lastResult) && _jsxs("footer", { className: "automation-foot", children: [lastResult && _jsx(Status, { variant: lastResult === "success" ? "success" : "danger", children: s.automationResult[lastResult] }), lastRun && _jsxs("span", { className: "hint", children: [s.automationLastRun, ": ", lastRun] }), actions] }), !lastRun && !lastResult && actions && _jsx("footer", { className: "automation-foot", children: actions })] });
302
+ }
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ import { DayPicker } from "react-day-picker";
3
+ export type CalendarProps = React.ComponentProps<typeof DayPicker> & {
4
+ label?: string;
5
+ };
6
+ export declare function Calendar({ label, className, classNames, ...props }: CalendarProps): React.JSX.Element;
@@ -0,0 +1,27 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { DayPicker } from "react-day-picker";
4
+ import { cx } from "./internal.js";
5
+ // Só TRÊS nomes são renomeados, e é de propósito. Todo o resto da pele é escrito contra ELEMENTO
6
+ // (`.calendar table`, `.calendar th`, `.calendar td button`) e contra os `data-*` que o motor já
7
+ // emite (`data-selected`, `data-today`, `data-outside`, `data-disabled`, `data-hidden`) — e
8
+ // atributo não é classe, então o check 15 nem os vê. Renomear os 21 nomes do motor encheria o
9
+ // core de superfície que ninguém usa.
10
+ // Os três que sobram são os que não dão para alcançar por elemento: a raiz (é o escopo de tudo),
11
+ // o embrulho dos meses (é o `position:relative` que a navegação usa de âncora) e o rótulo do mês
12
+ // (um <span> solto no meio de <div>s).
13
+ const NOMES = { months: "calendar-months", month_caption: "calendar-caption" };
14
+ export function Calendar({ label, className, classNames, ...props }) {
15
+ const grade = _jsx(DayPicker
16
+ // Grade cheia por padrão, como o shadcn: mês com buraco nas pontas treme ao trocar de mês.
17
+ , {
18
+ // Grade cheia por padrão, como o shadcn: mês com buraco nas pontas treme ao trocar de mês.
19
+ showOutsideDays: true, ...props, classNames: { ...NOMES, root: cx("calendar", className), ...classNames } });
20
+ // O motor já nomeia a GRADE com o mês ("August 2026"). O que ele não sabe é para que serve
21
+ // ESTE calendário — "de" e "até" lado a lado soariam os dois "August 2026". É o que `label`
22
+ // resolve, e só quando é preciso: dentro de um Popover quem diz o assunto é o gatilho, e um
23
+ // grupo a mais só acrescentaria ruído.
24
+ // O invólucro existe porque o `role` do DayPicker é tipado como "application" | "dialog" — o
25
+ // motor não deixa a raiz dele ser um `group`, e nenhum dos dois papéis dele serve aqui.
26
+ return label ? _jsx("div", { role: "group", "aria-label": label, children: grade }) : grade;
27
+ }
@@ -0,0 +1,10 @@
1
+ import React, { type ReactElement } from "react";
2
+ import { Tooltip, type LegendProps } from "recharts";
3
+ export interface ChartProps {
4
+ children: ReactElement;
5
+ label?: string;
6
+ className?: string;
7
+ }
8
+ export declare function Chart({ children, label, className }: ChartProps): React.JSX.Element;
9
+ export declare function ChartTooltip(props: React.ComponentProps<typeof Tooltip>): React.JSX.Element;
10
+ export declare function ChartLegend(props: LegendProps): React.JSX.Element;