@aurea-uds/react 0.51.0 → 0.54.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 +11 -4
- package/dist/actions.js +6 -4
- package/dist/agents.js +7 -6
- package/dist/code-client.d.ts +6 -1
- package/dist/code-client.js +21 -3
- package/dist/code-highlight.js +4 -1
- package/dist/data-display-client.d.ts +8 -1
- package/dist/data-display-client.js +1 -1
- package/dist/data-grid.js +23 -2
- package/dist/disclosure.d.ts +7 -1
- package/dist/disclosure.js +12 -2
- package/dist/feedback-client.d.ts +5 -2
- package/dist/feedback-client.js +9 -5
- package/dist/graph.js +2 -1
- package/dist/inputs-client.d.ts +12 -4
- package/dist/inputs-client.js +9 -6
- package/dist/layout-client.d.ts +5 -2
- package/dist/layout-client.js +4 -3
- package/dist/markup.d.ts +26 -8
- package/dist/markup.js +31 -9
- package/dist/navigation-client.d.ts +32 -4
- package/dist/navigation-client.js +68 -22
- package/dist/pure.d.ts +4 -0
- package/dist/pure.js +6 -2
- package/dist/system.js +2 -2
- package/package.json +1 -1
package/dist/inputs-client.js
CHANGED
|
@@ -433,7 +433,7 @@ export function CheckboxGroup({ label, description, error, value, defaultValue,
|
|
|
433
433
|
});
|
|
434
434
|
return _jsxs("div", { role: "group", "aria-labelledby": idRotulo, "aria-describedby": [idDescricao, idErro].filter(Boolean).join(" ") || undefined, className: cx("checkbox-group", className), ...props, children: [_jsx("span", { className: "label", id: idRotulo, children: _jsxs("span", { children: [label, required ? _jsx("span", { className: "label-required", "aria-hidden": "true", children: "*" }) : null] }) }), description && _jsx("span", { className: "field-description", id: idDescricao, children: description }), caixas, error && _jsx("span", { className: "field-error", id: idErro, children: error })] });
|
|
435
435
|
}
|
|
436
|
-
export function RadioGroup({ label, labelHidden, description, error, value, defaultValue, onValueChange, name, disabled, invalid, orientation = "vertical", required, children, className, ...props }) {
|
|
436
|
+
export function RadioGroup({ label, labelHidden, description, error, value, defaultValue, onValueChange, name, disabled, invalid, orientation = "vertical", required, variant = "list", indicatorPlacement = "start", children, className, ...props }) {
|
|
437
437
|
const auto = React.useId();
|
|
438
438
|
const [proprio, setProprio] = React.useState(defaultValue);
|
|
439
439
|
const escolhido = value ?? proprio;
|
|
@@ -456,7 +456,7 @@ export function RadioGroup({ label, labelHidden, description, error, value, defa
|
|
|
456
456
|
onValueChange?.(v);
|
|
457
457
|
} });
|
|
458
458
|
});
|
|
459
|
-
return _jsxs("div", { role: "radiogroup", "aria-labelledby": idRotulo, "aria-describedby": [idDescricao, idErro].filter(Boolean).join(" ") || undefined, "aria-orientation": orientation, "aria-required": required || undefined, "aria-invalid": error || invalid ? true : undefined, className: cx("radio-group", orientation === "horizontal" && "radio-group-horizontal", labelHidden && "radio-group-bare", className), ...props, children: [_jsx("span", { className: cx("label", labelHidden && "sr-only"), id: idRotulo, children: _jsxs("span", { children: [label, required ? _jsx("span", { className: "label-required", "aria-hidden": "true", children: "*" }) : null] }) }), description && _jsx("span", { className: "field-description", id: idDescricao, children: description }), orientation === "horizontal" ? _jsx("div", { className: "radio-group-items", children: opcoes }) : opcoes, error && _jsx("span", { className: "field-error", id: idErro, children: error })] });
|
|
459
|
+
return _jsxs("div", { role: "radiogroup", "aria-labelledby": idRotulo, "aria-describedby": [idDescricao, idErro].filter(Boolean).join(" ") || undefined, "aria-orientation": orientation, "aria-required": required || undefined, "aria-invalid": error || invalid ? true : undefined, className: cx("radio-group", orientation === "horizontal" && "radio-group-horizontal", labelHidden && "radio-group-bare", variant === "card" && indicatorPlacement === "none" && "radio-group-indicator-none", className), ...props, children: [_jsx("span", { className: cx("label", labelHidden && "sr-only"), id: idRotulo, children: _jsxs("span", { children: [label, required ? _jsx("span", { className: "label-required", "aria-hidden": "true", children: "*" }) : null] }) }), description && _jsx("span", { className: "field-description", id: idDescricao, children: description }), variant === "card" ? _jsx("div", { className: "radio-group-cards", children: opcoes }) : orientation === "horizontal" ? _jsx("div", { className: "radio-group-items", children: opcoes }) : opcoes, error && _jsx("span", { className: "field-error", id: idErro, children: error })] });
|
|
460
460
|
}
|
|
461
461
|
/** A opção do grupo: o `Radio`, como o `RadioGroup.Item` do nativo. */
|
|
462
462
|
RadioGroup.Item = Radio;
|
|
@@ -730,12 +730,15 @@ export function OTPField({ length, value, defaultValue, onValueChange, mask, dis
|
|
|
730
730
|
const s = useAureaStrings();
|
|
731
731
|
return _jsx(BaseOTPField.Root, { id: id, length: length, value: value, defaultValue: defaultValue, onValueChange: soOValor(onValueChange), mask: mask, disabled: disabled, required: required, role: "group", "aria-label": label, className: cx("otp-field", className), children: Array.from({ length }, (_, i) => _jsxs(React.Fragment, { children: [_jsx(BaseOTPField.Input, { render: _jsx("input", { "aria-label": `${s.otpDigit} ${i + 1}` }), className: cx("input otp-slot", variant === "secondary" && "input-secondary") }), groupSize && groupSize > 0 && (i + 1) % groupSize === 0 && i < length - 1 ? _jsx(BaseOTPField.Separator, { className: "otp-separator" }) : null] }, i)) });
|
|
732
732
|
}
|
|
733
|
-
|
|
733
|
+
// O SITE B (aprovado pela bancada em 01/11/2026, os itens 3 e 8): `items[].icon` (o escolhido troca sozinho para a forma
|
|
734
|
+
// cheia), `size="2xl"` (segmento de 48), `wrap` (quebra linha, o trilho com canto 22) e `orientation="vertical"` (em pé).
|
|
735
|
+
export function SegmentedControl({ items, value, onChange, label, fullWidth, size = "md", selectedStyle, wrap, orientation = "horizontal" }) {
|
|
734
736
|
const s = useAureaStrings();
|
|
735
|
-
const classe = cx("segmented", fullWidth && "segmented-full", size === "sm" && "segmented-sm");
|
|
737
|
+
const classe = cx("segmented", fullWidth && "segmented-full", size === "sm" && "segmented-sm", size === "lg" && "segmented-lg", size === "xl" && "segmented-xl", size === "2xl" && "segmented-2xl", wrap && orientation !== "vertical" && "segmented-wrap", orientation === "vertical" && "segmented-vertical");
|
|
738
|
+
const miolo = (i) => i.icon ? _jsxs(_Fragment, { children: [_jsx(Icon, { name: i.icon, weight: i.value === value ? "fill" : "regular" }), i.label] }) : i.label;
|
|
736
739
|
if (items.length > 0 && items.every(i => i.href != null))
|
|
737
|
-
return _jsx("nav", { className: classe, "data-segment-style": selectedStyle, "aria-label": label ?? s.optionsLabel, children: items.map(i => _jsx("a", { href: i.href, className: i.value === value ? "active" : undefined, "aria-current": i.value === value ? "page" : undefined, children: i
|
|
738
|
-
return _jsx(BaseRadioGroup, { className: classe, "data-segment-style": selectedStyle, "aria-label": label ?? s.optionsLabel, value: value, onValueChange: v => onChange?.(String(v)), children: items.map(i => _jsx(BaseRadio.Root, { value: i.value, className: i.value === value ? "active" : undefined, nativeButton: true, render: _jsx("button", { type: "button" }), children: i
|
|
740
|
+
return _jsx("nav", { className: classe, "data-segment-style": selectedStyle, "aria-label": label ?? s.optionsLabel, children: items.map(i => _jsx("a", { href: i.href, className: i.value === value ? "active" : undefined, "aria-current": i.value === value ? "page" : undefined, children: miolo(i) }, i.value)) });
|
|
741
|
+
return _jsx(BaseRadioGroup, { className: classe, "data-segment-style": selectedStyle, "aria-label": label ?? s.optionsLabel, "aria-orientation": orientation === "vertical" ? "vertical" : undefined, value: value, onValueChange: v => onChange?.(String(v)), children: items.map(i => _jsx(BaseRadio.Root, { value: i.value, className: i.value === value ? "active" : undefined, nativeButton: true, render: _jsx("button", { type: "button" }), children: miolo(i) }, i.value)) });
|
|
739
742
|
}
|
|
740
743
|
const ehAgrupado = (items) => items != null && items.length > 0 && typeof items[0] === "object" && items[0] != null && "items" in items[0];
|
|
741
744
|
// UM renderizador e UMA lista para os dois combobox: duas cópias da mesma árvore é como a
|
package/dist/layout-client.d.ts
CHANGED
|
@@ -3,14 +3,14 @@ import { type Orientation, type Responsive } from "./pure.js";
|
|
|
3
3
|
import { type IconButtonProps } from "./actions.js";
|
|
4
4
|
import { type HeaderVariant, type HeaderTab, type SidebarVariant, type SidebarScrollbar, type SidebarEntry, type SidebarCollapsible, type SidebarIndicator } from "./navigation.js";
|
|
5
5
|
declare function AppShellSidebarToggle(props: Omit<IconButtonProps, "icon" | "label" | "onClick" | "variant">): React.JSX.Element;
|
|
6
|
-
export declare function AppShell({ brand, navigation, navItems, currentNavId, navLabel, topbar, topbarVariant, topbarDivider, topbarTabs, topbarCurrentTab, topbarTabsLabel, topbarTabsEnd, topbarActions, layout, sidebarVariant, sidebarScrollbar, sidebarFooter, sidebarCollapsed, sidebarCollapsible, sidebarToggle, sidebarShortcut, sidebarIndicator, sidebarPanel, sidebarContrast, defaultSidebarCollapsed, onSidebarCollapsedChange, contentVariant, aside, asideLabel, asideVariant, children, className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement> & {
|
|
6
|
+
export declare function AppShell({ brand, navigation, navItems, currentNavId, navLabel, topbar, topbarVariant, topbarDivider, topbarTabs, topbarCurrentTab, topbarTabsLabel, topbarTabsEnd, topbarActions, topbarBlurred, layout, sidebarVariant, sidebarScrollbar, sidebarFooter, sidebarCollapsed, sidebarCollapsible, sidebarToggle, sidebarShortcut, sidebarIndicator, sidebarPanel, sidebarContrast, defaultSidebarCollapsed, onSidebarCollapsedChange, contentVariant, aside, asideLabel, asideVariant, children, className, ...props }: HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement> & {
|
|
7
7
|
brand: ReactNode;
|
|
8
8
|
navigation?: ReactNode;
|
|
9
9
|
navItems?: SidebarEntry[];
|
|
10
10
|
currentNavId?: string;
|
|
11
11
|
navLabel?: string;
|
|
12
12
|
topbar?: ReactNode;
|
|
13
|
-
topbarVariant?:
|
|
13
|
+
topbarVariant?: HeaderVariant;
|
|
14
14
|
topbarDivider?: boolean;
|
|
15
15
|
sidebarVariant?: SidebarVariant;
|
|
16
16
|
/** O arranjo (lote T, 17/10/2026): `"app"` (o padrão, o de sempre) ou `"docs"`, o da documentação da referência — um
|
|
@@ -34,6 +34,9 @@ export declare function AppShell({ brand, navigation, navItems, currentNavId, na
|
|
|
34
34
|
* conta, o sino. É o `actions` do `Header`. No `layout="sidebar"` a barra do conteúdo passa a existir também quando o app
|
|
35
35
|
* passa só isto; no `"docs"`, o botão da gaveta continua o último, depois delas. */
|
|
36
36
|
topbarActions?: ReactNode;
|
|
37
|
+
/** O site B (30/10/2026): o fundo da barra de cima que EMBAÇA o que passa por baixo — o `blurred` do `Header`, na
|
|
38
|
+
* `flush` e na `pill`. */
|
|
39
|
+
topbarBlurred?: boolean;
|
|
37
40
|
/** 0.32.0: a barra de rolagem da lateral da esquerda — o `scrollbar` da `Sidebar`. Padrão `hover` (clara, só com o
|
|
38
41
|
* ponteiro em cima); `visible` é a barra sempre à vista. */
|
|
39
42
|
sidebarScrollbar?: SidebarScrollbar;
|
package/dist/layout-client.js
CHANGED
|
@@ -59,7 +59,8 @@ function focoDaGaveta(e) {
|
|
|
59
59
|
// API pública intacta: as props seguem brand/navigation/topbar. O que mudou é ONDE a
|
|
60
60
|
// marca sai — no topo, não na lateral. `topbarVariant` escolhe a pele do topo; o shell
|
|
61
61
|
// precisa saber porque a lateral se encaixa abaixo dele (o `flush` não tem folga em
|
|
62
|
-
// cima, então ela sobe um --space-4).
|
|
62
|
+
// cima, então ela sobe um --space-4). ~~`pill` é cabeçalho de site — não é pra shell.~~ Desde o site B (30/10/2026), a
|
|
63
|
+
// `pill` entra no shell: a cápsula da largura do bloco, que flutua a --space-4 do alto (o `maxWidth` do `Header`).
|
|
63
64
|
// A lateral RECOLHE em tela estreita: o <aside> é um popover nativo e o botão é o invoker. O
|
|
64
65
|
// navegador entrega Escape, clique fora e o `aria-expanded` no disparador. Era o achado A8: em
|
|
65
66
|
// 375px o `h1` da página começava 4,6 telas abaixo, depois dos 65 itens da navegação.
|
|
@@ -166,7 +167,7 @@ function ProvedorDaLateral({ ligado, children, ...p }) {
|
|
|
166
167
|
return ligado ? _jsx(Sidebar.Provider, { id: SHELL_NAV_ID, ...p, children: children }) : _jsx(_Fragment, { children: children });
|
|
167
168
|
}
|
|
168
169
|
function AppShellSidebarToggle(props) { return _jsx(Sidebar.Toggle, { ...props }); }
|
|
169
|
-
export function AppShell({ brand, navigation, navItems, currentNavId, navLabel, topbar, topbarVariant = "floating", topbarDivider, topbarTabs, topbarCurrentTab, topbarTabsLabel, topbarTabsEnd, topbarActions, layout = "app", sidebarVariant, sidebarScrollbar, sidebarFooter, sidebarCollapsed, sidebarCollapsible, sidebarToggle = "edge", sidebarShortcut = true, sidebarIndicator, sidebarPanel, sidebarContrast, defaultSidebarCollapsed, onSidebarCollapsedChange, contentVariant = "surface", aside, asideLabel, asideVariant, children, className, ...props }) {
|
|
170
|
+
export function AppShell({ brand, navigation, navItems, currentNavId, navLabel, topbar, topbarVariant = "floating", topbarDivider, topbarTabs, topbarCurrentTab, topbarTabsLabel, topbarTabsEnd, topbarActions, topbarBlurred, layout = "app", sidebarVariant, sidebarScrollbar, sidebarFooter, sidebarCollapsed, sidebarCollapsible, sidebarToggle = "edge", sidebarShortcut = true, sidebarIndicator, sidebarPanel, sidebarContrast, defaultSidebarCollapsed, onSidebarCollapsedChange, contentVariant = "surface", aside, asideLabel, asideVariant, children, className, ...props }) {
|
|
170
171
|
const s = useAureaStrings();
|
|
171
172
|
const docs = layout === "docs", lateral = layout === "sidebar";
|
|
172
173
|
useGavetaFechaNoDesktop(docs);
|
|
@@ -223,7 +224,7 @@ export function AppShell({ brand, navigation, navItems, currentNavId, navLabel,
|
|
|
223
224
|
// No arranjo, o topo é o pequeno (`size="sm"`), e o botão também: com o tamanho de sempre ele ficava 4 maior que os
|
|
224
225
|
// vizinhos e fora da linha deles (medido a 375, sem toque; com toque, todos sobem para 44).
|
|
225
226
|
const botaoDaGaveta = _jsx(IconButton, { className: "nav-toggle", icon: "list", label: s.navigationToggle, popoverTarget: SHELL_NAV_ID, ...(docs ? { size: "sm" } : {}) });
|
|
226
|
-
return _jsx("div", { className: cx("app-shell", layout === "docs" && "app-shell-docs", lateral && "app-shell-lateral", !lateral && topbarVariant === "flush" && "app-shell-flush", recolhe && "app-shell-collapsible", aside != null && "app-shell-with-aside", className), ...props, children: _jsxs(ProvedorDaLateral, { ligado: recolhe, collapsed: efetiva, onCollapsedChange: definir, collapsible: forma, shortcut: sidebarShortcut, children: [_jsx("a", { className: "skip-link", href: `#${SHELL_MAIN_ID}`, children: s.skipToContent }), !lateral && _jsxs(Header, { variant: topbarVariant, divider: topbarDivider, tabs: topbarTabs, currentTab: topbarCurrentTab, tabsLabel: topbarTabsLabel, tabsEnd: topbarTabsEnd, ...(docs ? { maxWidth: "docs", size: "sm" } : {}), brand: docs ? brand : _jsxs(_Fragment, { children: [botaoDaGaveta, brand] }), actions: topbarActions != null ? _jsxs(_Fragment, { children: [topbarActions, docs && botaoDaGaveta] }) : undefined, children: [topbar, docs && topbarActions == null && botaoDaGaveta] }), recolhe && !lateral && sidebarToggle !== "none" && _jsx("div", { className: "sidebar-toggle-slot", children: _jsx(Tooltip, { content: rotulo, side: "right", children: _jsx(IconButton, { className: "sidebar-toggle", size: "xs", icon: paraOComeco === direita ? "caret-right" : "caret-left", label: rotulo, "aria-expanded": !efetiva, "aria-controls": SHELL_NAV_ID, onClick: alternar }) }) }), _jsx(Sidebar, { id: SHELL_NAV_ID, popover: "auto", variant: sidebarVariant, scrollbar: sidebarScrollbar, collapsed: efetiva, collapsible: forma, indicator: sidebarIndicator, panel: sidebarPanel, contrast: sidebarContrast, items: navItems, current: currentNavId, label: navLabel, onToggle: focoDaGaveta, header: lateral ? brand : undefined, footer: sidebarFooter, children: navigation }), docs && aside != null && _jsx("div", { className: "docs-toc-bar", children: _jsxs("button", { type: "button", className: "docs-toc-toggle", popoverTarget: SHELL_TOC_ID, children: [_jsx(Icon, { name: "list-bullets" }), _jsx("span", { className: "docs-toc-current", "data-toc-current": "", children: asideLabel ?? s.tocLabel }), _jsx(Icon, { name: "caret-down" })] }) }), lateral
|
|
227
|
+
return _jsx("div", { className: cx("app-shell", layout === "docs" && "app-shell-docs", lateral && "app-shell-lateral", !lateral && topbarVariant === "flush" && "app-shell-flush", !lateral && topbarVariant === "pill" && "app-shell-pill", recolhe && "app-shell-collapsible", aside != null && "app-shell-with-aside", className), ...props, children: _jsxs(ProvedorDaLateral, { ligado: recolhe, collapsed: efetiva, onCollapsedChange: definir, collapsible: forma, shortcut: sidebarShortcut, children: [_jsx("a", { className: "skip-link", href: `#${SHELL_MAIN_ID}`, children: s.skipToContent }), !lateral && _jsxs(Header, { variant: topbarVariant, divider: topbarDivider, tabs: topbarTabs, currentTab: topbarCurrentTab, tabsLabel: topbarTabsLabel, tabsEnd: topbarTabsEnd, ...(docs ? { maxWidth: "docs", ...(topbarVariant === "pill" ? {} : { size: "sm" }) } : topbarVariant === "pill" ? { maxWidth: "full" } : {}), blurred: topbarBlurred, brand: docs ? brand : _jsxs(_Fragment, { children: [botaoDaGaveta, brand] }), actions: topbarActions != null ? _jsxs(_Fragment, { children: [topbarActions, docs && botaoDaGaveta] }) : undefined, children: [topbar, docs && topbarActions == null && botaoDaGaveta] }), recolhe && !lateral && sidebarToggle !== "none" && _jsx("div", { className: "sidebar-toggle-slot", children: _jsx(Tooltip, { content: rotulo, side: "right", children: _jsx(IconButton, { className: "sidebar-toggle", size: "xs", icon: paraOComeco === direita ? "caret-right" : "caret-left", label: rotulo, "aria-expanded": !efetiva, "aria-controls": SHELL_NAV_ID, onClick: alternar }) }) }), _jsx(Sidebar, { id: SHELL_NAV_ID, popover: "auto", variant: sidebarVariant, scrollbar: sidebarScrollbar, collapsed: efetiva, collapsible: forma, indicator: sidebarIndicator, panel: sidebarPanel, contrast: sidebarContrast, items: navItems, current: currentNavId, label: navLabel, onToggle: focoDaGaveta, header: lateral ? brand : undefined, footer: sidebarFooter, children: navigation }), docs && aside != null && _jsx("div", { className: "docs-toc-bar", children: _jsxs("button", { type: "button", className: "docs-toc-toggle", popoverTarget: SHELL_TOC_ID, children: [_jsx(Icon, { name: "list-bullets" }), _jsx("span", { className: "docs-toc-current", "data-toc-current": "", children: asideLabel ?? s.tocLabel }), _jsx(Icon, { name: "caret-down" })] }) }), lateral
|
|
227
228
|
? _jsxs("div", { className: "app-shell-column", children: [topbar != null || topbarActions != null
|
|
228
229
|
? _jsx(Header, { variant: "flush", size: "sm", divider: topbarDivider, brand: _jsxs(_Fragment, { children: [botaoDaGaveta, sidebarToggle !== "none" && _jsx(AppShellSidebarToggle, {})] }), actions: topbarActions, children: topbar })
|
|
229
230
|
: _jsxs("div", { className: "app-shell-narrow-bar", children: [botaoDaGaveta, brand] }), _jsx("main", { id: SHELL_MAIN_ID, tabIndex: -1, className: cx("content", contentVariant === "plain" && "content-plain"), children: children })] })
|
package/dist/markup.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ type CardBase = HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement> &
|
|
|
13
13
|
padding?: "normal" | "none";
|
|
14
14
|
orientation?: "vertical" | "horizontal";
|
|
15
15
|
accent?: CardAccent;
|
|
16
|
+
lift?: boolean;
|
|
17
|
+
fill?: "brand";
|
|
16
18
|
};
|
|
17
19
|
export type CardProps = CardBase & ({
|
|
18
20
|
variant?: "base" | "raised" | "inset" | "outline" | "selected" | "danger" | "contrast";
|
|
@@ -21,7 +23,7 @@ export type CardProps = CardBase & ({
|
|
|
21
23
|
variant: "interactive";
|
|
22
24
|
render: ReactElement;
|
|
23
25
|
});
|
|
24
|
-
export declare function Card({ variant, padding, orientation, accent, className, render, ...props }: CardProps): ReactElement<unknown, string | React.JSXElementConstructor<any>>;
|
|
26
|
+
export declare function Card({ variant, padding, orientation, accent, lift, fill, className, render, ...props }: CardProps): ReactElement<unknown, string | React.JSXElementConstructor<any>>;
|
|
25
27
|
export declare namespace Card {
|
|
26
28
|
export { CardMedia as Media };
|
|
27
29
|
export { CardHeader as Header };
|
|
@@ -174,7 +176,13 @@ export interface SectionProps extends Omit<HTMLAttributes<HTMLElement>, "title">
|
|
|
174
176
|
export declare function Section({ surface, spacing, theme, variant, brand, links, legal, layout, maxWidth, navLabel, title, titleAs: Titulo, eyebrow, description, actions, media, align, children, className, ...props }: SectionProps): React.JSX.Element;
|
|
175
177
|
export type KPIDirection = "up" | "down" | "flat";
|
|
176
178
|
export type KPITone = "success" | "danger" | "neutral";
|
|
177
|
-
export type KPIVariant = "card" | "plain";
|
|
179
|
+
export type KPIVariant = "card" | "plain" | "brand";
|
|
180
|
+
/** Uma barra do `KPI` (o site B): o nome curto ("Jun"), o valor dito na leitura ("$48.2k") e o número que dá a altura. */
|
|
181
|
+
export interface KPIBar {
|
|
182
|
+
label: string;
|
|
183
|
+
value: ReactNode;
|
|
184
|
+
amount: number;
|
|
185
|
+
}
|
|
178
186
|
export interface KPIProps extends HTMLAttributes<HTMLDivElement>, RefAttributes<HTMLDivElement> {
|
|
179
187
|
label: ReactNode;
|
|
180
188
|
value: ReactNode;
|
|
@@ -186,10 +194,16 @@ export interface KPIProps extends HTMLAttributes<HTMLDivElement>, RefAttributes<
|
|
|
186
194
|
tone?: KPITone;
|
|
187
195
|
/** A palavra que o leitor de tela ouve antes da tendência. Padrão em inglês: "Up", "Down", "No change". */
|
|
188
196
|
directionLabel?: string;
|
|
189
|
-
/** `plain` tira a caixa: o número dentro de um cartão que já existe.
|
|
197
|
+
/** `plain` tira a caixa: o número dentro de um cartão que já existe. `brand` (o site B, 0.54.0) é o cartão AMARELO, com
|
|
198
|
+
* a tinta e a sombra média. */
|
|
190
199
|
variant?: KPIVariant;
|
|
200
|
+
/** As barras embaixo do número (o site B, 0.54.0): cada uma é um botão de opção nativo; a escolhida fica branca no
|
|
201
|
+
* `brand` (na cor do texto, fora dele) e a leitura diz o nome e o valor dela. */
|
|
202
|
+
bars?: KPIBar[];
|
|
203
|
+
/** A barra que começa escolhida (o índice). Padrão: a última. */
|
|
204
|
+
defaultBar?: number;
|
|
191
205
|
}
|
|
192
|
-
export declare function KPI({ label, value, trend, direction, tone, directionLabel, variant, className, ...props }: KPIProps): React.JSX.Element;
|
|
206
|
+
export declare function KPI({ label, value, trend, direction, tone, directionLabel, variant, bars, defaultBar, className, ...props }: KPIProps): React.JSX.Element;
|
|
193
207
|
export declare function DataList({ items }: {
|
|
194
208
|
items: Array<{
|
|
195
209
|
term: ReactNode;
|
|
@@ -346,7 +360,8 @@ export interface HeaderProps extends HTMLAttributes<HTMLElement>, RefAttributes<
|
|
|
346
360
|
current?: string;
|
|
347
361
|
/** O que fica do lado direito: busca, botão de ação, conta. Fica na barra também no celular. */
|
|
348
362
|
actions?: ReactNode;
|
|
349
|
-
/** Até onde o miolo da barra cresce, pela escala do `Container` (`sm` 640 … `2xl` 1536, `full`).
|
|
363
|
+
/** Até onde o miolo da barra cresce, pela escala do `Container` (`sm` 640 … `2xl` 1536, `full`). Na `pill` (o site B,
|
|
364
|
+
* 30/10/2026), a cápsula passa a ser o miolo, da largura do `Container`, e não do conteúdo. */
|
|
350
365
|
maxWidth?: ContainerSize;
|
|
351
366
|
/**
|
|
352
367
|
* Onde ficam os links (14/10/2026): `"end"` (o padrão) logo antes das ações, na outra ponta da marca; `"start"`
|
|
@@ -360,8 +375,9 @@ export interface HeaderProps extends HTMLAttributes<HTMLElement>, RefAttributes<
|
|
|
360
375
|
*/
|
|
361
376
|
size?: "md" | "sm";
|
|
362
377
|
/**
|
|
363
|
-
*
|
|
364
|
-
* da referência. Quem pede menos transparência no sistema, ou o navegador sem desfoque,
|
|
378
|
+
* Na `flush` (15/10/2026) e na `pill` (o site B, 30/10/2026): o fundo transparente que EMBAÇA o que passa por baixo,
|
|
379
|
+
* como o topo da página inicial da referência. Quem pede menos transparência no sistema, ou o navegador sem desfoque,
|
|
380
|
+
* recebe o fundo cheio.
|
|
365
381
|
*/
|
|
366
382
|
blurred?: boolean;
|
|
367
383
|
/** O que entra no MENU DO CELULAR, embaixo dos links (15/10/2026): o GitHub, a conta. Na barra larga não aparece. */
|
|
@@ -403,11 +419,13 @@ export interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElemen
|
|
|
403
419
|
variant?: FieldVariant;
|
|
404
420
|
}
|
|
405
421
|
export declare const Textarea: React.ForwardRefExoticComponent<Omit<TextareaProps, "ref"> & RefAttributes<HTMLTextAreaElement>>;
|
|
406
|
-
export declare function Checkbox({ label, labelHidden, description, size, className, ...props }: Omit<InputHTMLAttributes<HTMLInputElement>, "size"> & RefAttributes<HTMLInputElement> & {
|
|
422
|
+
export declare function Checkbox({ label, labelHidden, description, size, variant, tone, className, ...props }: Omit<InputHTMLAttributes<HTMLInputElement>, "size"> & RefAttributes<HTMLInputElement> & {
|
|
407
423
|
label: ReactNode;
|
|
408
424
|
labelHidden?: boolean;
|
|
409
425
|
description?: ReactNode;
|
|
410
426
|
size?: Responsive<FieldSize>;
|
|
427
|
+
variant?: "default" | "pill";
|
|
428
|
+
tone?: "success";
|
|
411
429
|
}): React.JSX.Element;
|
|
412
430
|
export declare function Radio({ label, labelHidden, description, size, className, ...props }: Omit<InputHTMLAttributes<HTMLInputElement>, "size"> & RefAttributes<HTMLInputElement> & {
|
|
413
431
|
label: ReactNode;
|
package/dist/markup.js
CHANGED
|
@@ -39,8 +39,8 @@ import React, { forwardRef } from "react";
|
|
|
39
39
|
import { cx, fundirRender, peleDoEixo } from "./pure.js";
|
|
40
40
|
// As contas de cor são funções puras, sem estado e sem navegador (ADR-0069): o `ColorSwatch` usa a do contraste.
|
|
41
41
|
import { contrastingInk, hsbToRgb, parseColor } from "./color.js";
|
|
42
|
-
export function Card({ variant = "base", padding = "normal", orientation = "vertical", accent, className, render, ...props }) {
|
|
43
|
-
return fundirRender(render, { className: cx("card", variant !== "base" && `card-${variant}`, accent && `card-accent card-accent-${accent}`, padding === "none" && "card-flush", orientation === "horizontal" && "card-horizontal", className), ...(variant === "contrast" ? { "data-theme": "dark" } : null), ...props });
|
|
42
|
+
export function Card({ variant = "base", padding = "normal", orientation = "vertical", accent, lift, fill, className, render, ...props }) {
|
|
43
|
+
return fundirRender(render, { className: cx("card", variant !== "base" && `card-${variant}`, lift && variant === "interactive" && "card-lift", accent && `card-accent card-accent-${accent}`, fill === "brand" && "card-fill-brand", padding === "none" && "card-flush", orientation === "horizontal" && "card-horizontal", className), ...(variant === "contrast" ? { "data-theme": "dark" } : null), ...props });
|
|
44
44
|
}
|
|
45
45
|
/** A mídia do cartão — a primeira das partes da especificação do `Card` (A-14). No vertical,
|
|
46
46
|
* primeira filha, ela SANGRA até a borda de cima e dos lados; no horizontal, fica à esquerda com a
|
|
@@ -119,11 +119,19 @@ export function Section({ surface = "background", spacing = "md", theme, variant
|
|
|
119
119
|
}
|
|
120
120
|
const TOM_DA_DIRECAO = { up: "success", down: "danger", flat: "neutral" };
|
|
121
121
|
const PALAVRA_DA_DIRECAO = { up: "Up", down: "Down", flat: "No change" };
|
|
122
|
-
export function KPI({ label, value, trend, direction, tone, directionLabel, variant = "card", className, ...props }) {
|
|
122
|
+
export function KPI({ label, value, trend, direction, tone, directionLabel, variant = "card", bars, defaultBar, className, ...props }) {
|
|
123
123
|
const tom = direction ? (tone ?? TOM_DA_DIRECAO[direction]) : undefined;
|
|
124
124
|
const miolo = _jsxs(_Fragment, { children: [_jsx("span", { className: "muted", children: label }), _jsx("strong", { children: value }), (trend || trend === 0 || direction) && _jsxs("small", { className: direction ? cx("kpi-trend", `kpi-trend-${direction}`, `kpi-tone-${tom}`) : undefined, children: [direction && _jsx("span", { className: "kpi-trend-icon", "aria-hidden": "true" }), direction && _jsx("span", { className: "sr-only", children: directionLabel ?? PALAVRA_DA_DIRECAO[direction] }), trend] })] });
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
const maior = bars && bars.length > 0 ? Math.max(...bars.map(b => b.amount), 1) : 1;
|
|
126
|
+
const escolhida = bars && bars.length > 0 ? Math.min(Math.max(defaultBar ?? bars.length - 1, 0), bars.length - 1) : -1;
|
|
127
|
+
const leituraDe = (b) => `${b.label} · ${typeof b.value === "string" || typeof b.value === "number" ? b.value : ""}`;
|
|
128
|
+
// As barras são botões de opção NATIVOS (o KPI é marcação pura, roda no servidor): o grupo é um `fieldset` com o rótulo
|
|
129
|
+
// do KPI, cada barra o `label` de um rádio com a leitura dela; o CSS mostra a leitura da escolhida e a da que está sob o
|
|
130
|
+
// mouse. O `name` vem do rótulo quando é texto.
|
|
131
|
+
const nomeDoGrupo = `kpi-bars-${typeof label === "string" ? label.toLowerCase().replace(/[^a-z0-9]+/g, "-") : "x"}`;
|
|
132
|
+
const barras = bars && bars.length > 0 && _jsxs("fieldset", { className: "kpi-bars-wrap", children: [typeof label === "string" && _jsx("legend", { className: "sr-only", children: label }), _jsx("div", { className: "kpi-bars", style: { "--kpi-bars": bars.length }, children: bars.map((b, i) => _jsxs("label", { className: "kpi-bar", children: [_jsx("input", { type: "radio", className: "kpi-bar-input", name: nomeDoGrupo, value: String(i), defaultChecked: i === escolhida, "aria-label": leituraDe(b) }), _jsx("span", { className: "kpi-bar-fill", style: { "--kpi-bar-h": `${Math.round(b.amount / maior * 100)}%` } }), _jsx("span", { className: "kpi-bar-reading", "aria-hidden": "true", children: leituraDe(b) })] }, i)) }), _jsx("div", { className: "kpi-bars-x", "aria-hidden": "true", style: { "--kpi-bars": bars.length }, children: bars.map((b, i) => _jsx("span", { children: b.label }, i)) })] });
|
|
133
|
+
return variant === "plain" ? _jsxs("div", { className: cx("kpi", className), ...props, children: [miolo, barras] })
|
|
134
|
+
: _jsxs(Card, { className: cx("kpi", variant === "brand" && "kpi-brand", className), ...props, children: [miolo, barras] });
|
|
127
135
|
}
|
|
128
136
|
export function DataList({ items }) { return _jsx("dl", { className: "data-list", children: items.map((i, n) => _jsxs(React.Fragment, { children: [_jsx("dt", { children: i.term }), _jsx("dd", { children: i.value })] }, n)) }); }
|
|
129
137
|
export function Timeline({ items, variant }) { return _jsx("ol", { className: "timeline", "data-timeline-style": variant, children: items.map((i, n) => _jsxs("li", { children: [_jsx("span", { className: "timeline-dot" }), _jsxs("div", { children: [_jsx("strong", { children: i.title }), i.description && _jsx("p", { children: i.description }), i.time && _jsx("small", { className: "muted", children: i.time })] })] }, n)) }); }
|
|
@@ -217,7 +225,7 @@ export function Header({ variant = "floating", divider, brand, items, current, a
|
|
|
217
225
|
// Sem o encaixe, a marcação de sempre; com ele, a linha das áreas e a ponta numa mesma faixa.
|
|
218
226
|
return tabsEnd == null ? abas : _jsxs("div", { className: "topbar-tabs-row", children: [abas, _jsx("div", { className: "topbar-tabs-end", children: tabsEnd })] });
|
|
219
227
|
})()] });
|
|
220
|
-
return _jsx("header", { className: cx("topbar", `topbar-${variant}`, divider && variant === "flush" && "topbar-divider", site && "topbar-site", site && itemsJustify === "start" && "topbar-items-start", size === "sm" && "topbar-sm", blurred && variant === "flush" && "topbar-blurred", maxWidth && "topbar-contained", comAbas && "topbar-with-tabs", className), ...props, children: maxWidth ? _jsx("div", { className: cx("container", maxWidth !== "xl" && `container-${maxWidth}`, "topbar-inner"), children: miolo }) : miolo });
|
|
228
|
+
return _jsx("header", { className: cx("topbar", `topbar-${variant}`, divider && variant === "flush" && "topbar-divider", site && "topbar-site", site && itemsJustify === "start" && "topbar-items-start", size === "sm" && "topbar-sm", blurred && (variant === "flush" || variant === "pill") && "topbar-blurred", maxWidth && "topbar-contained", comAbas && "topbar-with-tabs", className), ...props, children: maxWidth ? _jsx("div", { className: cx("container", maxWidth !== "xl" && `container-${maxWidth}`, "topbar-inner"), children: miolo }) : miolo });
|
|
221
229
|
}
|
|
222
230
|
/** @deprecated `Topbar` é o nome antigo do `Header` (07/10/2026). Continua funcionando, igual; use `Header`. */
|
|
223
231
|
export function Topbar(props) { return _jsx(Header, { ...props }); }
|
|
@@ -233,7 +241,14 @@ export function Kbd({ children, className, ...props }) { return _jsx("kbd", { cl
|
|
|
233
241
|
export const Textarea = forwardRef(function Textarea({ className, size, variant, ...props }, ref) { return _jsx("textarea", { ref: ref, className: cx("textarea", peleDoEixo("textarea", size), variant === "secondary" && "textarea-secondary", className), ...props }); });
|
|
234
242
|
// `size` nos três marcáveis pela mesma razão do campo: uma linha de formulário com um campo `sm`
|
|
235
243
|
// e um checkbox de tamanho fixo ao lado desalinha. O degrau vai na MARCA, não no rótulo.
|
|
236
|
-
|
|
244
|
+
// `variant="pill"` (o site B, o "Mark as done" — aprovado pela bancada em 01/11/2026, o item 4): a cápsula em volta, o alvo
|
|
245
|
+
// inteiro, de 44 (`--target-min`, a caixa 24) ou, com `size` sm/md, de 36 (`--control-h-md`, a caixa 20). `tone="success"`
|
|
246
|
+
// pinta a marcada de "feito" (a cápsula no verde a 18%, a letra e a caixa no verde). Sem `pill`, a caixa de sempre.
|
|
247
|
+
export function Checkbox({ label, labelHidden, description, size, variant = "default", tone, className, ...props }) {
|
|
248
|
+
if (variant === "pill")
|
|
249
|
+
return _jsxs("label", { className: cx("checkbox", "checkbox-pill", (size === "sm" || size === "md") && "checkbox-pill-md", className), "data-tone": tone, children: [_jsx("input", { type: "checkbox", ...props }), _jsx("span", { className: "control-mark" }), _jsx("span", { className: labelHidden ? "sr-only" : undefined, children: label })] });
|
|
250
|
+
return _jsxs("label", { className: cx("checkbox", labelHidden && "checkbox-bare", className), children: [_jsx("input", { type: "checkbox", ...props }), _jsx("span", { className: cx("control-mark", peleDoEixo("control-mark", size)) }), _jsxs("span", { className: labelHidden ? "sr-only" : undefined, children: [_jsx("strong", { children: label }), description && _jsxs(_Fragment, { children: [_jsx("br", {}), _jsx("span", { className: "muted", children: description })] })] })] });
|
|
251
|
+
}
|
|
237
252
|
// `description` no `Radio` e no `Switch` (15/10/2026, a referência tem nos dois): a linha apagada embaixo do nome, do
|
|
238
253
|
// mesmo jeito do `Checkbox`. Sem ela, a marcação é a de sempre.
|
|
239
254
|
const comDescricao = (label, description) => description ? _jsxs("span", { children: [_jsx("strong", { children: label }), _jsx("br", {}), _jsx("span", { className: "muted", children: description })] }) : label;
|
|
@@ -291,6 +306,13 @@ export function Link({ external, disabled, href, target, rel, className, childre
|
|
|
291
306
|
// Transparente quando o texto diz alfa abaixo de 1 (hex de 4 ou 8 dígitos, `rgba()`, `hsla()`…). Cor de token ou
|
|
292
307
|
// `oklch()` a marcação não lê: fica sem xadrez.
|
|
293
308
|
const transparente = (cor) => { const c = parseColor(cor); return c !== null && c.a < 1; };
|
|
309
|
+
// A cor só entra no estilo quando É uma cor (31/10/2026, a auditoria de segurança): o texto ia cru para a variável, e
|
|
310
|
+
// no HTML do servidor um ";" abria regras novas (cobrir a tela, buscar imagem de outro endereço). Aceita o que a ficha
|
|
311
|
+
// promete — hex, nome, as funções de cor do CSS e `var(--token)` — e nada com ";", chaves, barra invertida, aspas,
|
|
312
|
+
// comentário ou outra função (`url(`). Recusada, a variável não se escreve: a amostra fica sem cor, e o nome continua.
|
|
313
|
+
// (O `parseColor` não serve de filtro: ele não lê `oklch()` nem `var()`, que a ficha promete.)
|
|
314
|
+
const COR_DE_CSS = /^(?:#[0-9a-f]{3,8}|[a-z]+|(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch|color)\([^;{}\\"'()]*\)|var\(--[\w-]+\))$/i;
|
|
315
|
+
const corDeCss = (cor) => { const c = cor.trim(); return COR_DE_CSS.test(c) && !c.includes("/*") ? c : undefined; };
|
|
294
316
|
export function ColorSwatch(props) {
|
|
295
317
|
if ("options" in props) {
|
|
296
318
|
const { options, name, label, value, defaultValue, onChange, layout = "grid", indicator, showLabels, size = "md", disabled, id, className } = props;
|
|
@@ -302,14 +324,14 @@ export function ColorSwatch(props) {
|
|
|
302
324
|
return _jsx("div", { role: "radiogroup", "aria-label": label, id: id, "aria-disabled": disabled || undefined, className: cx("color-swatch-picker", size !== "md" && `color-swatch-picker-${size}`, layout === "stack" && "color-swatch-picker-stack", showLabels && "color-swatch-picker-labels", className), children: options.map((o) => {
|
|
303
325
|
const op = typeof o === "string" ? { color: o } : o;
|
|
304
326
|
const cor = parseColor(op.color), rgb = cor && hsbToRgb(cor);
|
|
305
|
-
const circulo = (Tag, key) => _jsxs(Tag, { className: cx("color-swatch-option", rgb && contrastingInk(rgb) === "dark" && "color-swatch-option-dark"), style: { ["--color-swatch-current"]: op.color }, children: [_jsx("input", { type: "radio", className: "color-swatch-input", name: name, value: op.color, "aria-label": op.label ?? op.color, checked: value === undefined ? undefined : value === op.color, defaultChecked: value === undefined ? defaultValue === op.color : undefined, disabled: disabled || op.disabled, ...(onChange ? { onChange } : {}) }), _jsx("span", { className: cx("color-swatch", cor && cor.a < 1 && "color-swatch-alpha"), "aria-hidden": "true" }), indicator != null && _jsx("span", { className: "color-swatch-indicator", "aria-hidden": "true", children: indicator })] }, key);
|
|
327
|
+
const circulo = (Tag, key) => _jsxs(Tag, { className: cx("color-swatch-option", rgb && contrastingInk(rgb) === "dark" && "color-swatch-option-dark"), style: { ["--color-swatch-current"]: corDeCss(op.color) }, children: [_jsx("input", { type: "radio", className: "color-swatch-input", name: name, value: op.color, "aria-label": op.label ?? op.color, checked: value === undefined ? undefined : value === op.color, defaultChecked: value === undefined ? defaultValue === op.color : undefined, disabled: disabled || op.disabled, ...(onChange ? { onChange } : {}) }), _jsx("span", { className: cx("color-swatch", cor && cor.a < 1 && "color-swatch-alpha"), "aria-hidden": "true" }), indicator != null && _jsx("span", { className: "color-swatch-indicator", "aria-hidden": "true", children: indicator })] }, key);
|
|
306
328
|
return showLabels
|
|
307
329
|
? _jsxs("label", { className: "color-swatch-item", children: [circulo("span"), _jsx("span", { className: "color-swatch-name", "aria-hidden": "true", children: op.label ?? op.color })] }, op.color)
|
|
308
330
|
: circulo("label", op.color);
|
|
309
331
|
}) });
|
|
310
332
|
}
|
|
311
333
|
const { color, size = "md", label, className, style, ...resto } = props;
|
|
312
|
-
return _jsx("span", { role: "img", "aria-label": label ?? color, className: cx("color-swatch", size !== "md" && `color-swatch-${size}`, transparente(color) && "color-swatch-alpha", className), style: { ...style, ["--color-swatch-current"]: color }, ...resto });
|
|
334
|
+
return _jsx("span", { role: "img", "aria-label": label ?? color, className: cx("color-swatch", size !== "md" && `color-swatch-${size}`, transparente(color) && "color-swatch-alpha", className), style: { ...style, ["--color-swatch-current"]: corDeCss(color) }, ...resto });
|
|
313
335
|
}
|
|
314
336
|
export function ProgressCircle({ value, min = 0, max = 100, size = "md", tone = "brand", label, className, ...props }) {
|
|
315
337
|
const semTotal = value == null || Number.isNaN(value);
|
|
@@ -8,10 +8,15 @@ export interface StepItem {
|
|
|
8
8
|
state?: StepState;
|
|
9
9
|
optional?: ReactNode;
|
|
10
10
|
onClick?: () => void;
|
|
11
|
+
href?: string;
|
|
11
12
|
}
|
|
12
|
-
export
|
|
13
|
+
export type StepperVariant = "default" | "path" | "bar";
|
|
14
|
+
export declare function Stepper({ items, label, variant, startContent, endContent, className }: {
|
|
13
15
|
items: StepItem[];
|
|
14
16
|
label?: string;
|
|
17
|
+
variant?: StepperVariant;
|
|
18
|
+
startContent?: ReactNode;
|
|
19
|
+
endContent?: ReactNode;
|
|
15
20
|
className?: string;
|
|
16
21
|
}): React.JSX.Element;
|
|
17
22
|
export interface BreadcrumbItem {
|
|
@@ -64,10 +69,14 @@ export interface TocItem {
|
|
|
64
69
|
label: string;
|
|
65
70
|
sub?: boolean;
|
|
66
71
|
}
|
|
67
|
-
export declare function TableOfContents({ items, current, label, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement> & {
|
|
72
|
+
export declare function TableOfContents({ items, current, label, progress, indicator, className, ...props }: HTMLAttributes<HTMLElement> & RefAttributes<HTMLElement> & {
|
|
68
73
|
items: TocItem[];
|
|
69
74
|
current?: string;
|
|
70
75
|
label?: string;
|
|
76
|
+
/** O anel de leitura no lugar do ícone do nome: quanto da página já rolou, em anel e em número. */
|
|
77
|
+
progress?: boolean;
|
|
78
|
+
/** O desenho do item atual: `"line"` (o padrão, o traço do lado) ou `"segment"` (a cápsula levantada, como a da `Sidebar`). */
|
|
79
|
+
indicator?: "line" | "segment";
|
|
71
80
|
}): React.JSX.Element;
|
|
72
81
|
export interface TreeNode {
|
|
73
82
|
id: string;
|
|
@@ -245,10 +254,18 @@ export interface NavListItem {
|
|
|
245
254
|
};
|
|
246
255
|
/** Os sinais ao lado do `value` (AN-04): fixada, silenciada. Pequenos e apagados, cada um com nome. */
|
|
247
256
|
indicators?: NavListIndicator[];
|
|
257
|
+
/** A cor de categoria do círculo do ícone, no `size="lg"` (as cores do `Badge`). */
|
|
258
|
+
tone?: BadgeCategory;
|
|
259
|
+
/** A linha da página em que se está: `aria-current="page"`, o fundo, e o selo `currentLabel` no lugar da seta. */
|
|
260
|
+
current?: boolean;
|
|
248
261
|
}
|
|
249
|
-
export declare function NavList({ items, className, ...props }: HTMLAttributes<HTMLUListElement> & RefAttributes<HTMLUListElement> & {
|
|
262
|
+
export declare function NavList({ items, size, currentLabel, className, ...props }: HTMLAttributes<HTMLUListElement> & RefAttributes<HTMLUListElement> & {
|
|
250
263
|
items: NavListItem[];
|
|
264
|
+
size?: "md" | "lg";
|
|
265
|
+
/** O texto do selo da linha atual (só aparece com `current` num item). */
|
|
266
|
+
currentLabel?: ReactNode;
|
|
251
267
|
}): React.JSX.Element;
|
|
268
|
+
import type { BadgeCategory } from "./markup.js";
|
|
252
269
|
export interface CommandItem {
|
|
253
270
|
id: string;
|
|
254
271
|
label: string;
|
|
@@ -258,8 +275,12 @@ export interface CommandItem {
|
|
|
258
275
|
/** 0.32.0 (DOC-06): o grupo do item ("Componentes", "Páginas"). Itens com o mesmo grupo saem juntos,
|
|
259
276
|
* sob o título dele, na ordem em que o grupo aparece primeiro. */
|
|
260
277
|
group?: string;
|
|
278
|
+
/** A linha de baixo do item, apagada e cortada (no `size="lg"`). */
|
|
279
|
+
description?: string;
|
|
280
|
+
/** A cor de categoria do círculo do ícone (no `size="lg"`), como as do `Badge`. Sem ela, o círculo neutro. */
|
|
281
|
+
tone?: BadgeCategory;
|
|
261
282
|
}
|
|
262
|
-
export declare function CommandPalette({ open, onClose, items, placeholder, label, shortcuts }: {
|
|
283
|
+
export declare function CommandPalette({ open, onClose, items, placeholder, label, shortcuts, size, filters, preview, footer }: {
|
|
263
284
|
open: boolean;
|
|
264
285
|
onClose: () => void;
|
|
265
286
|
items: CommandItem[];
|
|
@@ -267,6 +288,13 @@ export declare function CommandPalette({ open, onClose, items, placeholder, labe
|
|
|
267
288
|
label?: string;
|
|
268
289
|
/** 0.32.0 (DOC-07): a linha que ensina as teclas, embaixo — ↑ ↓ mover, Enter abrir, Esc fechar. */
|
|
269
290
|
shortcuts?: boolean;
|
|
291
|
+
size?: "md" | "lg";
|
|
292
|
+
/** No `lg`: o que vai embaixo do campo — os filtros que o app desenha (um `ToggleGroup`, por exemplo). */
|
|
293
|
+
filters?: ReactNode;
|
|
294
|
+
/** No `lg`: a prévia do item ativo, ao lado da lista. Some quando a janela é estreita. */
|
|
295
|
+
preview?: (item: CommandItem) => ReactNode;
|
|
296
|
+
/** No `lg`: o que vai no pé, ao lado da linha das teclas. */
|
|
297
|
+
footer?: ReactNode;
|
|
270
298
|
}): React.JSX.Element;
|
|
271
299
|
export declare function CommandPaletteShell({ open, query, onQueryChange, onClose, label, children }: {
|
|
272
300
|
open: boolean;
|
|
@@ -11,7 +11,7 @@ import { Dialog as BaseDialog } from "@base-ui/react/dialog";
|
|
|
11
11
|
import { Popover as BasePopover } from "@base-ui/react/popover";
|
|
12
12
|
import { useValorResponsivo } from "./responsivo-runtime.js";
|
|
13
13
|
import { cx, fundirRender, useAureaStrings, usePortalContainer } from "./internal.js";
|
|
14
|
-
import { Kbd } from "./markup.js";
|
|
14
|
+
import { Kbd, ProgressCircle } from "./markup.js";
|
|
15
15
|
import { Icon } from "./system.js";
|
|
16
16
|
import { Button, IconButton } from "./actions.js";
|
|
17
17
|
import { Badge, Spinner } from "./feedback.js";
|
|
@@ -21,14 +21,20 @@ import { SearchField } from "./inputs.js";
|
|
|
21
21
|
// mudou foi a ORDEM documentada, que colocava overlays no "resto" sem motivo medido.
|
|
22
22
|
import { Tooltip } from "./overlays.js";
|
|
23
23
|
import { Avatar } from "./identity-client.js";
|
|
24
|
-
export function Stepper({ items, label, className }) {
|
|
24
|
+
export function Stepper({ items, label, variant = "default", startContent, endContent, className }) {
|
|
25
25
|
const s = useAureaStrings();
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
const comPontas = variant === "path";
|
|
27
|
+
const lista = _jsxs("div", { role: "list", "aria-label": label ?? s.stepperLabel, className: cx("stepper", variant === "default" && className), style: comPontas ? { "--stepper-cols": items.length + (startContent != null ? 1 : 0) + (endContent != null ? 1 : 0) } : undefined, children: [comPontas && startContent != null && _jsx("div", { role: "listitem", className: "step-end step-end-start", children: startContent }), items.map((it, n) => {
|
|
28
|
+
const st = it.state ?? "default";
|
|
29
|
+
const marca = st === "done" && variant !== "path" ? _jsx(Icon, { name: "check" }) : st === "error" ? _jsx(Icon, { name: "x-circle" }) : n + 1;
|
|
30
|
+
const miolo = variant === "bar" ? _jsx("span", { className: "sr-only", children: it.label }) : _jsxs(_Fragment, { children: [_jsx("span", { className: "step-dot", children: marca }), _jsx("strong", { children: it.label }), it.optional && _jsx("small", { className: "step-optional", children: it.optional })] });
|
|
31
|
+
return _jsx("div", { role: "listitem", className: cx("step", st !== "default" && `step-${st}`), "aria-current": st === "active" ? "step" : undefined, children: it.href ? _jsx("a", { className: "step-trigger", href: it.href, onClick: it.onClick, children: miolo }) : it.onClick || variant === "bar" ? _jsx("button", { type: "button", className: "step-trigger", onClick: it.onClick, children: miolo }) : miolo }, n);
|
|
32
|
+
}), comPontas && endContent != null && _jsx("div", { role: "listitem", className: "step-end", children: endContent })] });
|
|
33
|
+
if (variant === "path")
|
|
34
|
+
return _jsx("div", { className: cx("stepper-path", className), children: lista });
|
|
35
|
+
if (variant === "bar")
|
|
36
|
+
return _jsxs("div", { className: cx("stepper-bar", className), children: [startContent != null && _jsx("span", { className: "stepper-bar-label", children: startContent }), lista, endContent != null && _jsx("span", { className: "stepper-bar-count", role: "status", children: endContent })] });
|
|
37
|
+
return lista;
|
|
32
38
|
}
|
|
33
39
|
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: "caret-right", size: "sm" }), " ", i.render ? fundirRender(i.render, { children: i.label }, "a") : i.href ? _jsx("a", { href: i.href, children: i.label }) : _jsx("strong", { "aria-current": "page", children: i.label })] }, n)) }); }
|
|
34
40
|
export function Tabs({ tabs, value, onChange, label, orientation, activateOnFocus = true, loopFocus, panel = "card", variant = "primary" }) { const s = useAureaStrings(); const ancora = useRef(null); const resolvida = useValorResponsivo(orientation, "horizontal", ancora); return _jsxs(BaseTabs.Root, { ref: ancora, value: value, onValueChange: v => onChange(String(v)), orientation: resolvida, className: "tabs-root", children: [_jsx(BaseTabs.List, { className: cx("tabs", variant === "secondary" && "tabs-secondary"), "aria-label": label ?? s.tabsLabel, activateOnFocus: activateOnFocus, loopFocus: loopFocus, 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: panel === "plain" ? "tabs-panel" : "card card-inset", tabIndex: 0, children: t.content }, t.id))] }); }
|
|
@@ -62,11 +68,29 @@ export function Pagination({ page, total, onPageChange, variant = "numbers", sum
|
|
|
62
68
|
? _jsx("li", { children: _jsx("span", { className: "pagination-ellipsis", "aria-hidden": "true", children: "\u2026" }) }, `e${i}`)
|
|
63
69
|
: _jsx("li", { children: item(p, p, { atual: p === page, rotulo: `${s.paginationPage} ${p}` }) }, p)), _jsx("li", { children: proxima })] })] });
|
|
64
70
|
}
|
|
65
|
-
|
|
71
|
+
//
|
|
72
|
+
// O SITE B (30/10/2026, protótipo): `progress` troca o ícone do nome pelo ANEL DE LEITURA — quanto da página já rolou, no
|
|
73
|
+
// anel (o `ProgressCircle`) e em número, na ponta da linha. É enfeite de leitura: o anel e o número ficam fora do leitor
|
|
74
|
+
// de tela (o que importa a ele é a seção atual, que o `aria-current` já diz).
|
|
75
|
+
export function TableOfContents({ items, current, label, progress, indicator = "line", className, ...props }) {
|
|
66
76
|
const s = useAureaStrings();
|
|
67
77
|
const meu = React.useRef(null);
|
|
68
78
|
const observado = useSecaoEmVista(items, current === undefined, meu);
|
|
69
79
|
const atual = current ?? observado;
|
|
80
|
+
const [lido, setLido] = React.useState(0);
|
|
81
|
+
const Rotulo = progress ? "div" : "p";
|
|
82
|
+
React.useEffect(() => {
|
|
83
|
+
if (!progress || typeof window === "undefined")
|
|
84
|
+
return;
|
|
85
|
+
const ler = () => {
|
|
86
|
+
const alto = document.documentElement.scrollHeight - window.innerHeight;
|
|
87
|
+
setLido(alto > 0 ? Math.round(Math.min(1, Math.max(0, window.scrollY / alto)) * 100) : 100);
|
|
88
|
+
};
|
|
89
|
+
ler();
|
|
90
|
+
window.addEventListener("scroll", ler, { passive: true });
|
|
91
|
+
window.addEventListener("resize", ler);
|
|
92
|
+
return () => { window.removeEventListener("scroll", ler); window.removeEventListener("resize", ler); };
|
|
93
|
+
}, [progress]);
|
|
70
94
|
// O `ref` do consumidor continua chegando: em React 19 ele é prop comum, então espalhá-lo por
|
|
71
95
|
// `...props` depois do nosso o sobrescreveria em silêncio. Os dois são atendidos aqui.
|
|
72
96
|
const refDele = props.ref;
|
|
@@ -74,7 +98,9 @@ export function TableOfContents({ items, current, label, className, ...props })
|
|
|
74
98
|
return _jsxs("nav", { ref: n => { meu.current = n; if (typeof refDele === "function")
|
|
75
99
|
refDele(n);
|
|
76
100
|
else if (refDele)
|
|
77
|
-
refDele.current = n; }, className: cx("toc",
|
|
101
|
+
refDele.current = n; }, className: cx("toc", indicator === "segment" && "toc-segment", className), "aria-label": label ?? s.tocLabel, ...resto, children: [_jsxs(Rotulo, { className: cx("toc-label", progress && "toc-label-progress"), children: [progress
|
|
102
|
+
? _jsx("span", { className: "toc-progress", "aria-hidden": "true", children: _jsx(ProgressCircle, { value: lido, size: "lg", label: label ?? s.tocLabel }) })
|
|
103
|
+
: _jsx("span", { className: "toc-label-icon", "aria-hidden": "true" }), label ?? s.tocLabel, progress && _jsxs("span", { className: "toc-progress-value", "aria-hidden": "true", children: [lido, "%"] })] }), items.map(i => _jsx("a", { href: `#${i.id}`, className: cx(i.sub && "toc-sub"), ...(i.id === atual ? { "aria-current": "true" } : {}), children: i.label }, i.id))] });
|
|
78
104
|
}
|
|
79
105
|
/** Qual dos `items` está na faixa de leitura, observando o documento. Devolve `undefined` até o
|
|
80
106
|
* primeiro cálculo — e em SSR, onde não há documento para observar.
|
|
@@ -270,7 +296,7 @@ function SidebarGroup({ item, filhos, lid, ctx }) {
|
|
|
270
296
|
? _jsxs("button", { id: lid, type: "button", className: "sidebar-group-label sidebar-group-toggle", "aria-expanded": aberto, "aria-controls": lid + "-lista", onClick: () => setAberto(v => !v), children: [_jsx("span", { children: item.label }), _jsx(Icon, { name: aberto ? "caret-down" : direita ? "caret-left" : "caret-right", size: "sm", className: "sidebar-group-caret" })] })
|
|
271
297
|
: _jsx("p", { id: lid, className: cx("sidebar-group-label", ctx.collapsed && "sr-only"), children: item.label });
|
|
272
298
|
const lista = sidebarList(filhos, ctx, false, lid);
|
|
273
|
-
return _jsxs("li", { children: [acao || dobra ? _jsxs("div", { className: "sidebar-group-head", children: [nome, acao && _jsx("span", { className: "sidebar-group-action", children: item.action })] }) : nome, dobra ? _jsx("div", { id: lid + "-lista", hidden: !aberto, children: lista }) : lista] });
|
|
299
|
+
return _jsxs("li", { children: [acao || dobra ? _jsxs("div", { className: "sidebar-group-head", children: [nome, acao && _jsx("span", { className: "sidebar-group-action", children: item.action })] }) : nome, dobra ? _jsx("div", { id: lid + "-lista", className: "sidebar-group-list", hidden: !aberto, children: lista }) : lista] });
|
|
274
300
|
}
|
|
275
301
|
// A GAVETA FECHA AO ESCOLHER (A-06, 23/09/2026). Abaixo de lg a lateral do `AppShell` é popover,
|
|
276
302
|
// e a biblioteca a abria e NUNCA a fechava por código: `hidePopover` tinha zero ocorrências. O
|
|
@@ -463,17 +489,32 @@ export function BottomNav({ items, current, variant = "floating", indicator = "n
|
|
|
463
489
|
: _jsx("button", { type: "button", className: "bottom-nav-item", "aria-current": ativo ? "page" : undefined, onClick: it.onClick, children: miolo }, it.id);
|
|
464
490
|
}) });
|
|
465
491
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
492
|
+
// `size="lg"` (o site B — o menu do celular, aprovado pela bancada em 01/11/2026, o item 10): a linha de 56 em cápsula (o
|
|
493
|
+
// ícone de 40 + 8 em cima e embaixo), o ícone num círculo de 40 tingido (`tone`), a letra 18 seminegrito. `current` marca a
|
|
494
|
+
// linha atual (o fundo `--fill-2`), e `currentLabel` é o selo que ela leva no lugar da seta ("You are here"). Sem `lg`, a
|
|
495
|
+
// lista de sempre; `current` vale nos dois tamanhos.
|
|
496
|
+
export function NavList({ items, size = "md", currentLabel, className, ...props }) {
|
|
497
|
+
const grande = size === "lg";
|
|
498
|
+
return _jsx("ul", { className: cx("nav-list", grande && "nav-list-lg", className), ...props, children: items.map(it => {
|
|
499
|
+
const icone = it.icon && (grande ? _jsx("span", { className: "nav-list-tile", "data-tone": it.tone, children: _jsx(Icon, { name: it.icon }) }) : _jsx(Icon, { name: it.icon }));
|
|
500
|
+
const miolo = _jsxs(_Fragment, { children: [it.avatar ? _jsx(Avatar, { src: it.avatar.src, fallback: it.avatar.fallback }) : icone, _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.indicators && it.indicators.length > 0 && _jsx("span", { className: "nav-list-indicators", children: it.indicators.map(x => _jsxs("span", { children: [_jsx(Icon, { name: x.icon, size: "sm" }), _jsx("span", { className: "sr-only", children: x.label })] }, x.label)) }), it.value != null && _jsx("span", { className: "nav-list-value", children: it.value }), it.current && currentLabel != null ? _jsx(Badge, { variant: "primary", emphasis: "solid", className: "nav-list-here", children: currentLabel })
|
|
501
|
+
: (it.href || it.render) && _jsx(Icon, { name: "caret-right", size: "sm", className: "nav-list-chevron" })] });
|
|
502
|
+
const atual = it.current ? "page" : undefined;
|
|
469
503
|
return _jsx("li", { children: it.render && !it.disabled
|
|
470
|
-
? fundirRender(it.render, { className: "nav-list-row", onClick: it.onClick, children: miolo }, "a")
|
|
504
|
+
? fundirRender(it.render, { className: "nav-list-row", onClick: it.onClick, "aria-current": atual, children: miolo }, "a")
|
|
471
505
|
: it.href && !it.disabled
|
|
472
|
-
? _jsx("a", { href: it.href, className: "nav-list-row", onClick: it.onClick, children: miolo })
|
|
473
|
-
: _jsx("button", { type: "button", className: "nav-list-row", "aria-disabled": it.disabled || undefined, onClick: it.disabled ? undefined : it.onClick, children: miolo }) }, it.id);
|
|
506
|
+
? _jsx("a", { href: it.href, className: "nav-list-row", "aria-current": atual, onClick: it.onClick, children: miolo })
|
|
507
|
+
: _jsx("button", { type: "button", className: "nav-list-row", "aria-current": atual, "aria-disabled": it.disabled || undefined, onClick: it.disabled ? undefined : it.onClick, children: miolo }) }, it.id);
|
|
474
508
|
}) });
|
|
475
509
|
}
|
|
476
|
-
|
|
510
|
+
// `size="lg"` (o site B — a busca nova, aprovada pela bancada em 01/11/2026, o item 2 e o D-2): a janela da largura `lg`
|
|
511
|
+
// (1024), o campo de 64 com a lupa e o "Esc" dentro, o encaixe `filters` embaixo dele, o título do grupo em mono maiúsculo
|
|
512
|
+
// com a contagem, o item de 50 com o ícone num círculo de 40 tingido (`tone`), o título e a descrição cortada, o "↵" na
|
|
513
|
+
// linha ativa, a prévia (`preview`) do item ativo ao lado da lista — some abaixo de 1240 — e o encaixe `footer` no pé,
|
|
514
|
+
// ao lado das teclas. Sem `size="lg"`, a paleta de sempre; os encaixes só valem no `lg`.
|
|
515
|
+
export function CommandPalette({ open, onClose, items, placeholder, label, shortcuts = true, size = "md", filters, preview, footer }) {
|
|
516
|
+
const grande = size === "lg";
|
|
517
|
+
const [ativo, setAtivo] = React.useState(undefined);
|
|
477
518
|
const s = useAureaStrings();
|
|
478
519
|
const idAtalhos = React.useId();
|
|
479
520
|
// GRUPOS (0.32.0, DOC-06). Em 13/08/2026 a Aurea ficou SEM grupo, e a medição decidiu: dar a cada
|
|
@@ -496,7 +537,9 @@ export function CommandPalette({ open, onClose, items, placeholder, label, short
|
|
|
496
537
|
const portal = usePortalContainer();
|
|
497
538
|
const campo = useRef(null);
|
|
498
539
|
const executa = (item) => { onClose(); item.run(); };
|
|
499
|
-
const linha = (item) =>
|
|
540
|
+
const linha = (item) => grande
|
|
541
|
+
? _jsxs(BaseAutocomplete.Item, { value: item, className: "menu-item command-item", onClick: () => executa(item), children: [_jsx("span", { className: "command-item-tile", "data-tone": item.tone, children: item.icon && _jsx(Icon, { name: item.icon }) }), _jsxs("span", { className: "command-item-text", children: [_jsx("span", { className: "command-item-label", children: item.label }), item.description && _jsx("span", { className: "command-item-description", children: item.description })] }), item.kbd ? _jsx(Kbd, { children: item.kbd }) : _jsx(Kbd, { className: "command-item-enter", "aria-hidden": "true", children: "\u21B5" })] }, item.id)
|
|
542
|
+
: _jsxs(BaseAutocomplete.Item, { value: item, className: "menu-item command-item", onClick: () => executa(item), children: [item.icon && _jsx(Icon, { name: item.icon }), _jsx("span", { className: "command-item-label", children: item.label }), item.kbd && _jsx(Kbd, { children: item.kbd })] }, item.id);
|
|
500
543
|
// A JANELA É A DO MOTOR (14/10/2026), como na paleta de exemplo dele (1.6.0): `Dialog` por fora,
|
|
501
544
|
// `Autocomplete` `inline` por dentro. Até aqui a moldura era uma `div` feita à mão, e o Victor achou no site
|
|
502
545
|
// publicado: o clique no fundo não fechava, e depois dele o foco ia para a página — o Esc, que era escutado
|
|
@@ -505,9 +548,12 @@ export function CommandPalette({ open, onClose, items, placeholder, label, short
|
|
|
505
548
|
// (`onOpenChange`), e quem fecha é o `onClose` — mesma regra do Dialog e do Drawer daqui. Os nomes de classe
|
|
506
549
|
// ficaram: a moldura (`Viewport`) é a `.command-overlay`, a caixa (`Popup`) é a `.command-palette`.
|
|
507
550
|
return _jsx(BaseDialog.Root, { open: open, onOpenChange: o => { if (!o)
|
|
508
|
-
onClose(); }, children: _jsx(BaseDialog.Portal, { container: portal, children: _jsx(BaseDialog.Viewport, { className: "command-overlay", children: _jsxs(BaseDialog.Popup, { className: "command-palette", "aria-label": label ?? s.commandLabel, initialFocus: campo, children: [_jsxs(BaseAutocomplete.Root, { items: (grupos ?? items), itemToStringValue: (i) => i.label, mode: "list", open: true, inline: true, autoHighlight: "always", keepHighlight: true,
|
|
509
|
-
|
|
510
|
-
|
|
551
|
+
onClose(); }, children: _jsx(BaseDialog.Portal, { container: portal, children: _jsx(BaseDialog.Viewport, { className: "command-overlay", children: _jsxs(BaseDialog.Popup, { className: cx("command-palette", grande && "command-palette-lg"), "aria-label": label ?? s.commandLabel, initialFocus: campo, children: [_jsxs(BaseAutocomplete.Root, { items: (grupos ?? items), itemToStringValue: (i) => i.label, mode: "list", open: true, inline: true, autoHighlight: "always", keepHighlight: true, onItemHighlighted: grande && preview ? (v) => { if (v)
|
|
552
|
+
setAtivo(v); } : undefined, children: [grande
|
|
553
|
+
? _jsxs("div", { className: "command-field", children: [_jsx(Icon, { name: "magnifying-glass" }), _jsx(BaseAutocomplete.Input, { ref: campo, className: "command-input", "aria-label": placeholder ?? s.commandPlaceholder, placeholder: placeholder ?? s.commandPlaceholder, "aria-expanded": true, "aria-describedby": shortcuts ? idAtalhos : undefined }), _jsx(Kbd, { children: "Esc" })] })
|
|
554
|
+
: _jsx(BaseAutocomplete.Input, { ref: campo, className: "input", "aria-label": placeholder ?? s.commandPlaceholder, placeholder: placeholder ?? s.commandPlaceholder, "aria-expanded": true, "aria-describedby": shortcuts ? idAtalhos : undefined }), grande && filters != null && _jsx("div", { className: "command-filters", children: filters }), _jsxs("div", { className: grande && preview ? "command-body" : "command-body-plain", children: [_jsxs("div", { className: "menu command-list", children: [_jsx(BaseAutocomplete.Empty, { className: "combobox-empty", children: s.comboboxEmpty }), _jsx(BaseAutocomplete.List, { children: grupos
|
|
555
|
+
? (g) => _jsxs(BaseAutocomplete.Group, { items: g.items, className: "command-group", children: [g.value && _jsxs(BaseAutocomplete.GroupLabel, { className: "command-group-label", children: [g.value, grande && _jsx("span", { className: "command-group-count", children: g.items.length })] }), _jsx(BaseAutocomplete.Collection, { children: linha })] }, g.value)
|
|
556
|
+
: _jsx(BaseAutocomplete.Collection, { children: linha }) })] }), grande && preview && ativo && _jsx("div", { className: "command-preview", children: preview(ativo) })] })] }), (shortcuts || (grande && footer != null)) && _jsxs("div", { className: grande ? "command-foot" : "command-foot-plain", children: [shortcuts && _jsxs("p", { className: "command-shortcuts", id: idAtalhos, children: [_jsxs("span", { children: [_jsx(Kbd, { children: "\u2191" }), _jsx(Kbd, { children: "\u2193" }), " ", s.commandHintMove] }), _jsxs("span", { children: [_jsx(Kbd, { children: "Enter" }), " ", s.commandHintSelect] }), _jsxs("span", { children: [_jsx(Kbd, { children: "Esc" }), " ", s.commandHintClose] })] }), grande && footer] })] }) }) }) });
|
|
511
557
|
}
|
|
512
558
|
// A CASCA (15/10/2026, o Victor: "C sim"): a mesma janela do motor da `CommandPalette` acima. Até aqui era uma `div`
|
|
513
559
|
// feita à mão — o mesmo defeito que a busca do site teve: o clique fora e o Esc não fechavam, e o Tab saía da caixa.
|