@aurea-uds/react 0.1.0 → 0.3.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.
Files changed (64) hide show
  1. package/README.md +34 -2
  2. package/dist/actions.d.ts +20 -0
  3. package/dist/actions.js +59 -5
  4. package/dist/agents.d.ts +209 -0
  5. package/dist/agents.js +302 -0
  6. package/dist/calendar.d.ts +6 -0
  7. package/dist/calendar.js +27 -0
  8. package/dist/chart.d.ts +10 -0
  9. package/dist/chart.js +53 -0
  10. package/dist/code-client.d.ts +6 -0
  11. package/dist/code-client.js +24 -0
  12. package/dist/code-editor.js +1 -0
  13. package/dist/code.d.ts +2 -13
  14. package/dist/code.js +5 -18
  15. package/dist/communication.js +1 -0
  16. package/dist/data-display-client.d.ts +14 -0
  17. package/dist/data-display-client.js +22 -0
  18. package/dist/data-display.d.ts +2 -23
  19. package/dist/data-display.js +5 -13
  20. package/dist/data-grid.d.ts +52 -3
  21. package/dist/data-grid.js +205 -25
  22. package/dist/feedback-client.d.ts +64 -0
  23. package/dist/feedback-client.js +110 -0
  24. package/dist/feedback.d.ts +2 -53
  25. package/dist/feedback.js +5 -71
  26. package/dist/file-input.d.ts +21 -2
  27. package/dist/file-input.js +202 -21
  28. package/dist/graph.d.ts +33 -0
  29. package/dist/graph.js +178 -0
  30. package/dist/identity-client.d.ts +9 -0
  31. package/dist/identity-client.js +12 -0
  32. package/dist/identity.d.ts +2 -8
  33. package/dist/identity.js +5 -3
  34. package/dist/index.d.ts +4 -1
  35. package/dist/index.js +33 -3
  36. package/dist/inputs-client.d.ts +105 -0
  37. package/dist/inputs-client.js +264 -0
  38. package/dist/inputs.d.ts +2 -65
  39. package/dist/inputs.js +9 -61
  40. package/dist/internal.d.ts +23 -70
  41. package/dist/internal.js +115 -23
  42. package/dist/layout-client.d.ts +9 -0
  43. package/dist/layout-client.js +72 -0
  44. package/dist/layout.d.ts +2 -14
  45. package/dist/layout.js +5 -22
  46. package/dist/markup.d.ts +72 -0
  47. package/dist/markup.js +87 -0
  48. package/dist/media-client.d.ts +36 -0
  49. package/dist/media-client.js +239 -0
  50. package/dist/media.d.ts +2 -9
  51. package/dist/media.js +5 -98
  52. package/dist/navigation-client.d.ts +94 -0
  53. package/dist/navigation-client.js +154 -0
  54. package/dist/navigation.d.ts +2 -59
  55. package/dist/navigation.js +5 -113
  56. package/dist/overlays.d.ts +28 -0
  57. package/dist/overlays.js +66 -10
  58. package/dist/pure.d.ts +196 -0
  59. package/dist/pure.js +111 -0
  60. package/dist/qrcode.d.ts +2 -1
  61. package/dist/qrcode.js +3 -2
  62. package/dist/system.d.ts +11 -1
  63. package/dist/system.js +59 -4
  64. package/package.json +40 -4
@@ -1,59 +1,2 @@
1
- import React, { type HTMLAttributes, type RefAttributes, type ReactNode, type ReactElement } from "react";
2
- import { type IconName } from "./system.js";
3
- export declare function Breadcrumb({ items, label }: {
4
- items: Array<{
5
- label: ReactNode;
6
- href?: string;
7
- }>;
8
- label?: string;
9
- }): React.JSX.Element;
10
- export declare function Tabs({ tabs, value, onChange, label }: {
11
- tabs: Array<{
12
- id: string;
13
- label: ReactNode;
14
- content: ReactNode;
15
- }>;
16
- value: string;
17
- onChange: (id: string) => void;
18
- label?: string;
19
- }): React.JSX.Element;
20
- export declare function Pagination({ page, total, onPageChange }: {
21
- page: number;
22
- total: number;
23
- onPageChange: (p: number) => void;
24
- }): React.JSX.Element;
25
- export interface TocItem {
26
- id: string;
27
- label: string;
28
- sub?: boolean;
29
- }
30
- export declare function TableOfContents({ items, current, label, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement> & {
31
- items: TocItem[];
32
- current?: string;
33
- label?: string;
34
- }): React.JSX.Element;
35
- export interface TreeNode {
36
- id: string;
37
- label: ReactNode;
38
- icon?: IconName;
39
- children?: TreeNode[];
40
- }
41
- export declare function TreeView({ items, defaultExpandedIds, onSelect, label, className }: {
42
- items: TreeNode[];
43
- defaultExpandedIds?: string[];
44
- onSelect?: (node: TreeNode) => void;
45
- label?: string;
46
- className?: string;
47
- }): ReactElement<unknown, string | React.JSXElementConstructor<any>>;
48
- export declare function Sidebar({ children, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement>): React.JSX.Element;
49
- export type TopbarVariant = "floating" | "flush" | "pill";
50
- export declare function Topbar({ variant, brand, children, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement> & {
51
- variant?: TopbarVariant;
52
- brand?: ReactNode;
53
- }): React.JSX.Element;
54
- export declare function CommandPaletteShell({ open, query, onQueryChange, children }: {
55
- open: boolean;
56
- query: string;
57
- onQueryChange: (v: string) => void;
58
- children?: ReactNode;
59
- }): React.JSX.Element | null;
1
+ export * from "./navigation-client.js";
2
+ export { Topbar, type TopbarVariant } from "./markup.js";
@@ -1,113 +1,5 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- // Fase 9 (achado A5): este arquivo saiu do index.tsx de 970 linhas. Um módulo por categoria
3
- // do registry a taxonomia existia e é gateada. A ordem de import entre eles é um DAG:
4
- // internal system → actions → feedback → inputs → navigation → layout → data-display → resto.
5
- import React from "react";
6
- import { Tabs as BaseTabs } from "@base-ui/react/tabs";
7
- import { cx, useAureaStrings } from "./internal.js";
8
- import { Icon } from "./system.js";
9
- import { Button } from "./actions.js";
10
- import { Badge } from "./feedback.js";
11
- import { SearchField } from "./inputs.js";
12
- export function Breadcrumb({ items, label }) { const s = useAureaStrings(); return _jsx("nav", { className: "breadcrumb", "aria-label": label ?? s.breadcrumbLabel, children: items.map((i, n) => _jsxs(React.Fragment, { children: [n > 0 && _jsx(Icon, { name: "chevron--right", size: "sm" }), " ", i.href ? _jsx("a", { href: i.href, children: i.label }) : _jsx("strong", { "aria-current": "page", children: i.label })] }, n)) }); }
13
- export function Tabs({ tabs, value, onChange, label }) { const s = useAureaStrings(); return _jsxs(BaseTabs.Root, { value: value, onValueChange: v => onChange(String(v)), children: [_jsx(BaseTabs.List, { className: "tabs", "aria-label": label ?? s.tabsLabel, activateOnFocus: true, children: tabs.map(t => _jsx(BaseTabs.Tab, { value: t.id, className: "tab", children: t.label }, t.id)) }), tabs.map(t => _jsx(BaseTabs.Panel, { value: t.id, className: "card card-inset", tabIndex: 0, children: t.content }, t.id))] }); }
14
- export function Pagination({ page, total, onPageChange }) { const s = useAureaStrings(); return _jsxs("nav", { className: "pagination", "aria-label": s.paginationLabel, children: [_jsx(Button, { variant: "ghost", size: "sm", disabled: page <= 1, onClick: () => onPageChange(page - 1), children: s.previous }), _jsxs(Badge, { variant: "primary", children: [page, " / ", total] }), _jsx(Button, { variant: "ghost", size: "sm", disabled: page >= total, onClick: () => onPageChange(page + 1), children: s.next })] }); }
15
- export function TableOfContents({ items, current, label, className, ...props }) {
16
- const s = useAureaStrings();
17
- return _jsxs("nav", { className: cx("toc", className), "aria-label": label ?? s.tocLabel, ...props, children: [_jsx("p", { className: "toc-label", children: label ?? s.tocLabel }), items.map(i => _jsx("a", { href: `#${i.id}`, className: cx(i.sub && "toc-sub"), ...(i.id === current ? { "aria-current": "true" } : {}), children: i.label }, i.id))] });
18
- }
19
- function flattenVisible(nodes, expanded, level = 1, parentId, acc = []) {
20
- for (const node of nodes) {
21
- acc.push({ node, level, parentId });
22
- if (node.children?.length && expanded.has(node.id))
23
- flattenVisible(node.children, expanded, level + 1, node.id, acc);
24
- }
25
- return acc;
26
- }
27
- export function TreeView({ items, defaultExpandedIds, onSelect, label, className }) {
28
- const s = useAureaStrings();
29
- const baseId = React.useId();
30
- const [expanded, setExpanded] = React.useState(() => new Set(defaultExpandedIds));
31
- const [selected, setSelected] = React.useState();
32
- const [active, setActive] = React.useState(() => items[0]?.id);
33
- const rootRef = React.useRef(null);
34
- const visible = flattenVisible(items, expanded);
35
- // Roving tab stop derivado: se o nó ativo saiu do conjunto visível (dados
36
- // trocados, nó removido), o primeiro visível volta a ser tabulável — senão a
37
- // árvore inteira fica tabIndex=-1 e some da ordem do Tab (auditoria, MÉDIO 1).
38
- const effectiveActive = active !== undefined && visible.some(v => v.node.id === active) ? active : visible[0]?.node.id;
39
- const focusId = (id) => { setActive(id); rootRef.current?.querySelector(`[data-tree-id="${CSS.escape(id)}"]`)?.focus(); };
40
- const toggle = (id, open) => setExpanded(prev => { const n = new Set(prev); if (open)
41
- n.add(id);
42
- else
43
- n.delete(id); return n; });
44
- const select = (node) => { setSelected(node.id); onSelect?.(node); };
45
- const onKeyDown = (e) => {
46
- const idx = visible.findIndex(v => v.node.id === effectiveActive);
47
- if (idx < 0)
48
- return;
49
- const cur = visible[idx], hasChildren = !!cur.node.children?.length, isOpen = expanded.has(cur.node.id);
50
- const rtl = getComputedStyle(e.currentTarget).direction === "rtl";
51
- const expandKey = rtl ? "ArrowLeft" : "ArrowRight", collapseKey = rtl ? "ArrowRight" : "ArrowLeft";
52
- switch (e.key) {
53
- case "ArrowDown":
54
- e.preventDefault();
55
- if (idx < visible.length - 1)
56
- focusId(visible[idx + 1].node.id);
57
- break;
58
- case "ArrowUp":
59
- e.preventDefault();
60
- if (idx > 0)
61
- focusId(visible[idx - 1].node.id);
62
- break;
63
- case expandKey:
64
- e.preventDefault();
65
- if (hasChildren && !isOpen)
66
- toggle(cur.node.id, true);
67
- else if (hasChildren && isOpen)
68
- focusId(cur.node.children[0].id);
69
- break;
70
- case collapseKey:
71
- e.preventDefault();
72
- if (hasChildren && isOpen)
73
- toggle(cur.node.id, false);
74
- else if (cur.parentId)
75
- focusId(cur.parentId);
76
- break;
77
- case "Home":
78
- e.preventDefault();
79
- focusId(visible[0].node.id);
80
- break;
81
- case "End":
82
- e.preventDefault();
83
- focusId(visible[visible.length - 1].node.id);
84
- break;
85
- case "Enter":
86
- case " ":
87
- e.preventDefault();
88
- select(cur.node);
89
- if (hasChildren)
90
- toggle(cur.node.id, !isOpen);
91
- break;
92
- }
93
- };
94
- const renderNodes = (nodes, level) => (_jsx("ul", { ref: level === 1 ? rootRef : undefined, className: cx(level === 1 ? "tree" : "tree-group", level === 1 && className), role: level === 1 ? "tree" : "group", "aria-label": level === 1 ? (label ?? s.treeLabel) : undefined, onKeyDown: level === 1 ? onKeyDown : undefined, children: nodes.map(node => {
95
- const hasChildren = !!node.children?.length, isOpen = expanded.has(node.id), isSelected = selected === node.id, labelId = baseId + node.id;
96
- return _jsxs("li", { className: "tree-item", role: "treeitem", "data-tree-id": node.id, "aria-level": level, "aria-expanded": hasChildren ? isOpen : undefined, "aria-selected": isSelected, "aria-labelledby": labelId, tabIndex: node.id === effectiveActive ? 0 : -1, children: [_jsxs("span", { className: "tree-node", "data-selected": isSelected || undefined, style: { paddingInlineStart: `calc(var(--space-3) + ${level - 1} * var(--space-4))` }, onClick: () => { focusId(node.id); select(node); if (hasChildren)
97
- toggle(node.id, !isOpen); }, children: [hasChildren ? _jsx(Icon, { name: "chevron--right", size: "sm", className: "tree-twist" }) : _jsx("span", { className: "tree-indent", "aria-hidden": "true" }), node.icon && _jsx(Icon, { name: node.icon, size: "sm" }), _jsx("span", { id: labelId, className: "tree-label", children: node.label })] }), hasChildren && isOpen && renderNodes(node.children, level + 1)] }, node.id);
98
- }) }));
99
- return renderNodes(items, 1);
100
- }
101
- // Sidebar/Topbar: eram <aside>/<header> soltos DENTRO do AppShell; agora são componentes
102
- // nomeados que o AppShell COMPÕE (dogfooding, AUREA.md §2.4 — "se o catálogo mostra uma
103
- // Sidebar, a sidebar dele É a Sidebar da Aurea"). O landmark vem do elemento nativo
104
- // (<aside>=complementary, <header>=banner); o <nav> de navegação é do consumidor, passado
105
- // como children — por isso não embutimos <nav> aqui (aninharia landmark).
106
- export function Sidebar({ children, className, ...props }) { return _jsx("aside", { className: cx("sidebar", className), ...props, children: children }); }
107
- export function Topbar({ variant = "floating", brand, children, className, ...props }) { return _jsxs("header", { className: cx("topbar", `topbar-${variant}`, className), ...props, children: [brand != null && _jsx("div", { className: "brand", children: brand }), children] }); }
108
- // Shell NÃO-modal de propósito: é presentational (o consumidor controla open) e não
109
- // tem focus trap/inert/Escape — declarar aria-modal sem entregar a modalidade faria
110
- // leitores ocultarem o resto da página com o teclado ainda alcançando tudo
111
- // (auditoria 18/07/2026, ALTO 2; APG dialog-modal). Modal de verdade = BaseDialog.
112
- export function CommandPaletteShell({ open, query, onQueryChange, children }) { const s = useAureaStrings(); if (!open)
113
- return null; return _jsx("div", { className: "command-overlay", children: _jsxs("div", { className: "command-palette", role: "dialog", "aria-label": s.commandLabel, children: [_jsx(SearchField, { autoFocus: true, "aria-label": s.commandPlaceholder, value: query, onChange: e => onQueryChange(e.target.value), placeholder: s.commandPlaceholder }), children] }) }); }
1
+ // VITRINE da categoria é este arquivo que `@aurea-uds/react/navigation` resolve. Sem
2
+ // `"use client"` de propósito: a diretiva contamina o módulo inteiro e faria a marcação pura
3
+ // chegar como cliente por vizinhança (ADR-0026; o check 26b reprova quem a puser de volta aqui).
4
+ export * from "./navigation-client.js";
5
+ export { Topbar } from "./markup.js";
@@ -7,6 +7,16 @@ export declare function Dialog({ open, title, children, footer, onClose }: {
7
7
  footer?: ReactNode;
8
8
  onClose: () => void;
9
9
  }): React.JSX.Element;
10
+ export declare function ConfirmDialog({ open, title, description, confirmLabel, cancelLabel, destructive, onConfirm, onCancel }: {
11
+ open: boolean;
12
+ title: ReactNode;
13
+ description: ReactNode;
14
+ confirmLabel?: string;
15
+ cancelLabel?: string;
16
+ destructive?: boolean;
17
+ onConfirm: () => void;
18
+ onCancel: () => void;
19
+ }): React.JSX.Element;
10
20
  export declare function Drawer({ open, title, children, onClose, side }: {
11
21
  open: boolean;
12
22
  title: ReactNode;
@@ -14,6 +24,19 @@ export declare function Drawer({ open, title, children, onClose, side }: {
14
24
  onClose: () => void;
15
25
  side?: "left" | "right";
16
26
  }): React.JSX.Element;
27
+ export type AccessGateProps = {
28
+ allowed: boolean;
29
+ children: ReactElement;
30
+ } & ({
31
+ mode?: "hide";
32
+ fallback?: ReactNode;
33
+ reason?: never;
34
+ } | {
35
+ mode: "disable";
36
+ reason: ReactNode;
37
+ fallback?: never;
38
+ });
39
+ export declare function AccessGate({ allowed, children, ...resto }: AccessGateProps): React.JSX.Element;
17
40
  export type OverlaySide = "top" | "right" | "bottom" | "left";
18
41
  export declare function Tooltip({ children, content, side }: {
19
42
  children: ReactElement;
@@ -26,6 +49,11 @@ export declare function Popover({ trigger, title, children, side }: {
26
49
  children: ReactNode;
27
50
  side?: OverlaySide;
28
51
  }): React.JSX.Element;
52
+ export declare function HoverCard({ trigger, children, side }: {
53
+ trigger: ReactElement;
54
+ children: ReactNode;
55
+ side?: OverlaySide;
56
+ }): React.JSX.Element;
29
57
  export interface MenuItemDef {
30
58
  label: ReactNode;
31
59
  onClick?: () => void;
package/dist/overlays.js CHANGED
@@ -1,36 +1,92 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ "use client";
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 React from "react";
6
7
  import { Dialog as BaseDialog } from "@base-ui/react/dialog";
8
+ import { AlertDialog as BaseAlertDialog } from "@base-ui/react/alert-dialog";
7
9
  import { Popover as BasePopover } from "@base-ui/react/popover";
8
10
  import { Tooltip as BaseTooltip } from "@base-ui/react/tooltip";
9
11
  import { Menu as BaseMenu } from "@base-ui/react/menu";
10
12
  import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu";
11
- import { cx, useAureaStrings } from "./internal.js";
13
+ import { PreviewCard as BasePreviewCard } from "@base-ui/react/preview-card";
14
+ import { cx, useAureaStrings, usePortalContainer } from "./internal.js";
12
15
  import { Icon } from "./system.js";
13
- export function Dialog({ open, title, children, footer, onClose }) { const s = useAureaStrings(); return _jsx(BaseDialog.Root, { open: open, onOpenChange: o => { if (!o)
14
- onClose(); }, children: _jsxs(BaseDialog.Portal, { children: [_jsx(BaseDialog.Backdrop, { className: "dialog-backdrop" }), _jsxs(BaseDialog.Popup, { className: "dialog", children: [_jsxs("header", { children: [_jsx(BaseDialog.Title, { render: _jsx("h2", {}), children: title }), _jsx(BaseDialog.Close, { className: "btn btn-ghost btn-icon", "aria-label": s.close, children: _jsx(Icon, { name: "close" }) })] }), _jsx("div", { className: "dialog-body", children: children }), footer && _jsx("footer", { children: footer })] })] }) }); }
15
- export function Drawer({ open, title, children, onClose, side = "right" }) { const s = useAureaStrings(); return _jsx(BaseDialog.Root, { open: open, onOpenChange: o => { if (!o)
16
- onClose(); }, children: _jsxs(BaseDialog.Portal, { children: [_jsx(BaseDialog.Backdrop, { className: "drawer-backdrop" }), _jsxs(BaseDialog.Popup, { className: cx("drawer", `drawer-${side}`), children: [_jsxs("header", { children: [_jsx(BaseDialog.Title, { render: _jsx("h2", {}), children: title }), _jsx(BaseDialog.Close, { className: "btn btn-ghost btn-icon", "aria-label": s.close, children: _jsx(Icon, { name: "close" }) })] }), children] })] }) }); }
16
+ import { Button } from "./actions.js";
17
+ export function Dialog({ open, title, children, footer, onClose }) { const s = useAureaStrings(); const portal = usePortalContainer(); return _jsx(BaseDialog.Root, { open: open, onOpenChange: o => { if (!o)
18
+ onClose(); }, children: _jsxs(BaseDialog.Portal, { container: portal, children: [_jsx(BaseDialog.Backdrop, { className: "dialog-backdrop" }), _jsxs(BaseDialog.Popup, { className: "dialog", children: [_jsxs("header", { children: [_jsx(BaseDialog.Title, { render: _jsx("h2", {}), children: title }), _jsx(BaseDialog.Close, { className: "btn btn-ghost btn-icon", "aria-label": s.close, children: _jsx(Icon, { name: "close" }) })] }), _jsx("div", { className: "dialog-body", children: children }), footer && _jsx("footer", { children: footer })] })] }) }); }
19
+ // ConfirmDialog (M5): a decisão que não se fecha por engano. NÃO é um Dialog com dois botões
20
+ // é `role="alertdialog"`, e a diferença é de comportamento, não de aparência: o Base UI tira do
21
+ // AlertDialog.Root as props `modal` e `disablePointerDismissal` (medido no d.ts de 1.6.0), ou
22
+ // seja, clicar fora NÃO fecha. Num Dialog comum, clicar fora vira "cancelei" sem a pessoa ter
23
+ // decidido — que é exatamente o acidente que este componente existe para impedir.
24
+ //
25
+ // FOCO NO BOTÃO SEGURO: quem abre um "isto apaga" e aperta Enter por reflexo tem de cancelar,
26
+ // não apagar. As quatro referências convergem em cancelar-antes-de-agir na ORDEM visual, e
27
+ // nenhuma delas move o foco — este passo saiu de medir o teclado, não de ler.
28
+ //
29
+ // DUAS coisas garantem, e as duas foram medidas em 13/08/2026, uma de cada vez:
30
+ // • a ORDEM do DOM — o Cancelar vem primeiro, e o motor foca o primeiro focável. Sozinha, ela
31
+ // já faz o teste passar; tirar só o `initialFocus` NÃO reprova.
32
+ // • o `initialFocus`, que é o cinto: com a ordem dos dois botões INVERTIDA ele continua
33
+ // segurando o foco no Cancelar, e é aí que ele prova que não é enfeite. Sem ele e com a
34
+ // ordem invertida, o teste reprova — que é o defeito de verdade, porque inverter a ordem é
35
+ // uma mudança de aparência que alguém faz sem pensar no teclado.
36
+ // O teste cobra o EFEITO ("o foco nasce no seguro"), não o mecanismo. É por isso que ele
37
+ // sobrevive a trocar um dos dois — e reprova quando os dois somem.
38
+ //
39
+ // ESCOPO MENOR que a referência (BUILDING.md §5): lá são nove peças compostas
40
+ // (Root/Trigger/Content/Header/Title/Description/Footer/Cancel/Action). Aqui é uma prop `open`,
41
+ // como no `Dialog` e no `Drawer` — a composição não acrescenta escolha nenhuma num diálogo cujo
42
+ // corpo é uma frase e dois botões.
43
+ //
44
+ // `description` é prop e não `children` porque ela é o nó de `aria-describedby`: o AlertDialog
45
+ // só anuncia o que passa pelo `Description`. Como `children`, um consumidor poria um <div> no
46
+ // meio e o leitor de tela perderia a frase que diz o que se perde.
47
+ export function ConfirmDialog({ open, title, description, confirmLabel, cancelLabel, destructive, onConfirm, onCancel }) {
48
+ const s = useAureaStrings();
49
+ const portal = usePortalContainer();
50
+ const seguro = React.useRef(null);
51
+ return _jsx(BaseAlertDialog.Root, { open: open, onOpenChange: o => { if (!o)
52
+ onCancel(); }, children: _jsxs(BaseAlertDialog.Portal, { container: portal, children: [_jsx(BaseAlertDialog.Backdrop, { className: "dialog-backdrop" }), _jsxs(BaseAlertDialog.Popup, { className: "dialog dialog-confirm", initialFocus: seguro, children: [_jsx("header", { children: _jsx(BaseAlertDialog.Title, { render: _jsx("h2", {}), children: title }) }), _jsx(BaseAlertDialog.Description, { className: "dialog-body", children: description }), _jsxs("footer", { children: [_jsx(Button, { ref: seguro, variant: "secondary", onClick: onCancel, children: cancelLabel ?? s.confirmCancel }), _jsx(Button, { variant: destructive ? "danger" : "primary", onClick: onConfirm, children: confirmLabel ?? s.confirmProceed })] })] })] }) });
53
+ }
54
+ export function Drawer({ open, title, children, onClose, side = "right" }) { const s = useAureaStrings(); const portal = usePortalContainer(); return _jsx(BaseDialog.Root, { open: open, onOpenChange: o => { if (!o)
55
+ onClose(); }, children: _jsxs(BaseDialog.Portal, { container: portal, children: [_jsx(BaseDialog.Backdrop, { className: "drawer-backdrop" }), _jsxs(BaseDialog.Popup, { className: cx("drawer", `drawer-${side}`), children: [_jsxs("header", { children: [_jsx(BaseDialog.Title, { render: _jsx("h2", {}), children: title }), _jsx(BaseDialog.Close, { className: "btn btn-ghost btn-icon", "aria-label": s.close, children: _jsx(Icon, { name: "close" }) })] }), children] })] }) }); }
56
+ export function AccessGate({ allowed, children, ...resto }) {
57
+ if (allowed)
58
+ return children;
59
+ if (resto.mode === "disable")
60
+ return _jsx(Tooltip, { content: resto.reason, children: React.cloneElement(children, { "aria-disabled": true }) });
61
+ return _jsx(_Fragment, { children: resto.fallback ?? null });
62
+ }
17
63
  // `role="tooltip"` + `aria-describedby` no disparador é o que faz a dica EXISTIR para leitor
18
64
  // de tela. Medido em 30/07/2026: sem isso, o popup saía sem role e sem id, e o disparador sem
19
65
  // aria-describedby — quem navega por leitor de tela ouvia só o rótulo do botão e nunca o
20
66
  // conteúdo da dica. Era tooltip visual, não acessível (padrão APG Tooltip).
21
67
  // O id aponta para um elemento que só existe quando aberto; referência pendente é ignorada
22
68
  // pela tecnologia assistiva, então não precisa acompanhar o estado.
23
- export function Tooltip({ children, content, side = "top" }) { const id = React.useId(); return _jsxs(BaseTooltip.Root, { children: [_jsx(BaseTooltip.Trigger, { render: children, "aria-describedby": id }), _jsx(BaseTooltip.Portal, { children: _jsx(BaseTooltip.Positioner, { side: side, sideOffset: 8, children: _jsx(BaseTooltip.Popup, { id: id, role: "tooltip", className: "tooltip", children: content }) }) })] }); }
24
- export function Popover({ trigger, title, children, side = "bottom" }) { return _jsxs(BasePopover.Root, { children: [_jsx(BasePopover.Trigger, { render: trigger }), _jsx(BasePopover.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] }) }) })] }); }
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 }) }) })] }); }
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
+ // HoverCard (Lote 1 do BUILDING.md). Não é Tooltip nem Popover, e a diferença é de propósito,
72
+ // não de aparência: a Tooltip é um RÓTULO curto (`role="tooltip"`, some ao mover o mouse); o
73
+ // Popover abre por CLIQUE e pode conter foco; este é uma PRÉVIA rica que aparece ao repousar o
74
+ // ponteiro sobre um link e cujo conteúdo é alcançável — o cartão de perfil ao passar sobre um
75
+ // nome. As três referências que o têm chamam de hover-card ou preview-card e concordam nisso.
76
+ // Superfície reusa `.popover` de propósito: é a mesma camada flutuante do sistema, e dar a ela
77
+ // um segundo nome criaria duas peles para a mesma coisa.
78
+ // Por depender de repouso do ponteiro, NÃO serve para informação essencial — quem navega só por
79
+ // teclado ou toque não abre um hover card. Conteúdo obrigatório vai em Popover.
80
+ export function HoverCard({ trigger, children, side = "bottom" }) { const portal = usePortalContainer(); return _jsxs(BasePreviewCard.Root, { children: [_jsx(BasePreviewCard.Trigger, { render: trigger }), _jsx(BasePreviewCard.Portal, { container: portal, children: _jsx(BasePreviewCard.Positioner, { side: side, sideOffset: 8, children: _jsx(BasePreviewCard.Popup, { className: "popover hover-card", children: children }) }) })] }); }
25
81
  // ContextMenu.Item/.Separator/.Popup são os MESMOS componentes de Menu.* no Base UI,
26
82
  // então os itens renderizam igual nos dois menus.
27
83
  const renderMenuItems = (items) => items.map((it, i) => it === "separator"
28
84
  ? _jsx(BaseMenu.Separator, { className: "menu-sep" }, i)
29
85
  : _jsxs(BaseMenu.Item, { className: "menu-item", disabled: it.disabled, onClick: it.onClick, children: [it.leadingIcon && _jsx(Icon, { name: it.leadingIcon }), it.label] }, i));
30
- export function DropdownMenu({ trigger, items, side = "bottom", label }) { return _jsxs(BaseMenu.Root, { children: [_jsx(BaseMenu.Trigger, { render: trigger }), _jsx(BaseMenu.Portal, { children: _jsx(BaseMenu.Positioner, { side: side, sideOffset: 6, children: _jsx(BaseMenu.Popup, { className: "menu", "aria-label": label, children: renderMenuItems(items) }) }) })] }); }
86
+ export function DropdownMenu({ trigger, items, side = "bottom", label }) { const portal = usePortalContainer(); return _jsxs(BaseMenu.Root, { children: [_jsx(BaseMenu.Trigger, { render: trigger }), _jsx(BaseMenu.Portal, { container: portal, children: _jsx(BaseMenu.Positioner, { side: side, sideOffset: 6, children: _jsx(BaseMenu.Popup, { className: "menu", "aria-label": label, children: renderMenuItems(items) }) }) })] }); }
31
87
  // ContextMenu: abre no botão direito e — por teclado — em Shift+F10 / tecla Menu,
32
88
  // que o browser só dispara (como evento contextmenu) sobre um elemento FOCADO. Por
33
89
  // isso o gatilho é focável (tabIndex 0) e tem nome acessível (auditoria 18/07/2026,
34
90
  // MÉDIO 3); sem isso o teclado não alcança o menu. Consumidor pode sobrescrever
35
91
  // tabIndex via children se o próprio já for focável.
36
- export function ContextMenu({ children, items, label, className }) { return _jsxs(BaseContextMenu.Root, { children: [_jsx(BaseContextMenu.Trigger, { className: className, tabIndex: 0, "aria-label": label, "aria-haspopup": "menu", children: children }), _jsx(BaseContextMenu.Portal, { children: _jsx(BaseContextMenu.Positioner, { children: _jsx(BaseContextMenu.Popup, { className: "menu", "aria-label": label, children: renderMenuItems(items) }) }) })] }); }
92
+ export function ContextMenu({ children, items, label, className }) { const portal = usePortalContainer(); return _jsxs(BaseContextMenu.Root, { children: [_jsx(BaseContextMenu.Trigger, { className: className, tabIndex: 0, "aria-label": label, "aria-haspopup": "menu", children: children }), _jsx(BaseContextMenu.Portal, { container: portal, children: _jsx(BaseContextMenu.Positioner, { children: _jsx(BaseContextMenu.Popup, { className: "menu", "aria-label": label, children: renderMenuItems(items) }) }) })] }); }
package/dist/pure.d.ts ADDED
@@ -0,0 +1,196 @@
1
+ export declare const cx: (...v: Array<string | false | null | undefined>) => string;
2
+ export type UniversalState = "waiting_user" | "waiting_approval" | "waiting_dependency" | "offline" | "stale" | "partial" | "degraded";
3
+ export declare const universalStates: readonly UniversalState[];
4
+ export declare const stateSeverity: (state: UniversalState) => "info" | "warning";
5
+ export interface AureaStrings {
6
+ close: string;
7
+ confirmCancel: string;
8
+ dataError: string;
9
+ dataEmpty: string;
10
+ confirmProceed: string;
11
+ paginationLabel: string;
12
+ previous: string;
13
+ next: string;
14
+ breadcrumbLabel: string;
15
+ tabsLabel: string;
16
+ optionsLabel: string;
17
+ tableLabel: string;
18
+ commandLabel: string;
19
+ commandPlaceholder: string;
20
+ dismissNotification: string;
21
+ toolbarLabel: string;
22
+ loading: string;
23
+ otpDigit: string;
24
+ stepperLabel: string;
25
+ increment: string;
26
+ decrement: string;
27
+ comboboxEmpty: string;
28
+ comboboxClear: string;
29
+ comboboxOpen: string;
30
+ comboboxRemove: string;
31
+ comboboxLoading: string;
32
+ fileDropPrompt: string;
33
+ fileAdded: string;
34
+ fileRemoved: string;
35
+ fileRemove: string;
36
+ fileTooLarge: string;
37
+ fileWrongType: string;
38
+ treeLabel: string;
39
+ notificationsLabel: string;
40
+ notificationMarkAll: string;
41
+ notificationEmpty: string;
42
+ notificationUnread: string;
43
+ notificationNew: string;
44
+ dataGridFilter: string;
45
+ dataGridEmpty: string;
46
+ dataGridSelectAll: string;
47
+ dataGridSelectRow: string;
48
+ dataGridSelected: string;
49
+ dataGridClearSelection: string;
50
+ dataGridBulkLabel: string;
51
+ dataGridColumns: string;
52
+ dataGridResize: string;
53
+ dataGridStale: string;
54
+ dataGridPartial: string;
55
+ dataGridError: string;
56
+ dataGridDetails: string;
57
+ dataGridDetailPanel: string;
58
+ dataGridExport: string;
59
+ dataGridExportRows: string;
60
+ dataGridExportFiltered: string;
61
+ dataGridExportSelected: string;
62
+ mediaPlayer: string;
63
+ mediaPlay: string;
64
+ mediaPause: string;
65
+ mediaMute: string;
66
+ mediaUnmute: string;
67
+ mediaSeek: string;
68
+ mediaVolume: string;
69
+ mediaCaptionsShow: string;
70
+ mediaCaptionsHide: string;
71
+ mediaSkipBack: string;
72
+ mediaSkipForward: string;
73
+ mediaFullscreenEnter: string;
74
+ mediaFullscreenExit: string;
75
+ carouselLabel: string;
76
+ carouselSlide: string;
77
+ positionOf: string;
78
+ carouselPrev: string;
79
+ carouselNext: string;
80
+ galleryLabel: string;
81
+ sortableLabel: string;
82
+ sortableHandle: string;
83
+ sortableHelp: string;
84
+ sortableGrabbed: string;
85
+ sortableDropped: string;
86
+ sortableMoved: string;
87
+ sortableCanceled: string;
88
+ blockEditorLabel: string;
89
+ blockLabel: string;
90
+ blockRemove: string;
91
+ uploadSending: string;
92
+ uploadCancel: string;
93
+ uploadRetry: string;
94
+ uploadError: string;
95
+ uploadCanceled: string;
96
+ uploadComplete: string;
97
+ uploadPause: string;
98
+ uploadResume: string;
99
+ uploadPaused: string;
100
+ uploadPending: string;
101
+ uploadChecksum: string;
102
+ uploadChecksumBad: string;
103
+ fileConflict: string;
104
+ fileReplace: string;
105
+ fileKeepBoth: string;
106
+ fileSkip: string;
107
+ uploadReceipt: string;
108
+ uploadReceiptCopy: string;
109
+ agentInspector: string;
110
+ invocationLabel: string;
111
+ invocationInput: string;
112
+ invocationOutput: string;
113
+ taskQueueLabel: string;
114
+ taskState: Record<"queued" | "running" | "completed" | "failed" | "blocked" | "paused", string>;
115
+ taskPriority: Record<"low" | "medium" | "high", string>;
116
+ approvalLabel: string;
117
+ approvalApprove: string;
118
+ approvalDeny: string;
119
+ approvalApproved: string;
120
+ approvalDenied: string;
121
+ approvalDeadline: string;
122
+ approvalRisk: Record<"low" | "medium" | "high", string>;
123
+ permissionLabel: string;
124
+ permissionAsk: string;
125
+ permissionAlways: string;
126
+ permissionNever: string;
127
+ eventStreamLabel: string;
128
+ traceLabel: string;
129
+ healthLabel: string;
130
+ healthState: Record<"operational" | "degraded" | "down" | "maintenance" | "unknown", string>;
131
+ modelUsageLabel: string;
132
+ usageMetric: Record<"tokens" | "cost" | "requests", string>;
133
+ costMeterLabel: string;
134
+ costMeterSpent: string;
135
+ costMeterRemaining: string;
136
+ costMeterExceeded: string;
137
+ costMeterNear: string;
138
+ costMeterOver: string;
139
+ memoryLabel: string;
140
+ memoryProvenance: string;
141
+ memoryOperation: Record<"added" | "updated" | "recalled" | "forgotten", string>;
142
+ memoryScope: Record<"episodic" | "semantic" | "procedural", string>;
143
+ agentMessageLabel: string;
144
+ agentMessageTo: string;
145
+ agentMessageBroadcast: string;
146
+ agentMessageReason: string;
147
+ agentMessageKind: Record<"request" | "response" | "handoff" | "broadcast" | "error", string>;
148
+ automationWhen: string;
149
+ automationThen: string;
150
+ automationEnabled: string;
151
+ automationLastRun: string;
152
+ automationResult: Record<"success" | "failure", string>;
153
+ graphLabel: string;
154
+ agentState: Record<"idle" | "thinking" | "running" | "paused" | "error" | "completed", string>;
155
+ codeEditor: string;
156
+ chatLabel: string;
157
+ chatMessage: string;
158
+ chatSend: string;
159
+ qrCode: string;
160
+ chartLabel: string;
161
+ copyCode: string;
162
+ tocLabel: string;
163
+ navigationToggle: string;
164
+ sidebarLabel: string;
165
+ universalState: Record<UniversalState, string>;
166
+ }
167
+ export declare const defaultStrings: AureaStrings;
168
+ export declare const ptBR: AureaStrings;
169
+ export declare const defaultSpriteUrl = "/aurea-icons.svg";
170
+ export interface GridState {
171
+ sorting?: Array<{
172
+ id: string;
173
+ desc: boolean;
174
+ }>;
175
+ globalFilter?: string;
176
+ columnFilters?: Array<{
177
+ id: string;
178
+ value: unknown;
179
+ }>;
180
+ page?: number;
181
+ }
182
+ export declare function gridStateToParams(state: GridState, into?: URLSearchParams): URLSearchParams;
183
+ export declare function gridStateFromParams(params: URLSearchParams, filters?: Array<{
184
+ column: string;
185
+ facet?: boolean;
186
+ }>): GridState;
187
+ export interface ScreenState extends GridState {
188
+ tab?: string;
189
+ view?: string;
190
+ detail?: string;
191
+ }
192
+ export declare function screenStateToParams(state: ScreenState, into?: URLSearchParams): URLSearchParams;
193
+ export declare function screenStateFromParams(params: URLSearchParams, filters?: Array<{
194
+ column: string;
195
+ facet?: boolean;
196
+ }>): ScreenState;