@corbits/react-ui 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +174 -499
- package/README.md +228 -85
- package/dist/blocks/login/auth-layout.d.ts +1 -1
- package/dist/blocks/login/auth-layout.js +3 -33
- package/dist/blocks/login/login-form.js +6 -119
- package/dist/hooks/use-command-palette-navigation.js +18 -17
- package/dist/hooks/use-controllable-state.d.ts +2 -2
- package/dist/hooks/use-controllable-state.js +23 -15
- package/dist/hooks/use-delayed-autofocus.js +10 -11
- package/dist/hooks/use-dismissable-popover.d.ts +2 -2
- package/dist/hooks/use-dismissable-popover.js +21 -29
- package/dist/hooks/use-list-selection.js +54 -85
- package/dist/hooks/use-prefers-reduced-motion.js +8 -4
- package/dist/hooks/use-scroll-current-into-view.js +5 -7
- package/dist/index.d.ts +0 -11
- package/dist/index.js +10 -19
- package/dist/lib/artifact.js +16 -35
- package/dist/lib/chart-geometry.js +33 -20
- package/dist/lib/chart-palette.js +17 -31
- package/dist/lib/chat-message.js +32 -13
- package/dist/lib/chat-parts.js +2 -1
- package/dist/lib/csv.js +42 -26
- package/dist/lib/metrics.js +30 -48
- package/dist/lib/now-item.js +26 -25
- package/dist/lib/relative-time.js +14 -29
- package/dist/lib/theme.js +32 -30
- package/dist/lib/url.js +9 -8
- package/dist/lib/workflow-display-flow.js +37 -33
- package/dist/lib/workflow-registry.d.ts +0 -41
- package/dist/lib/workflow-registry.js +13 -23
- package/dist/lib/workflow-run-error.js +16 -20
- package/dist/lib/workflow-run-progress.js +94 -52
- package/dist/lib/workflow-run.js +17 -13
- package/dist/styles.css +11 -11
- package/dist/test/render-hook.js +11 -12
- package/dist/theme.css +51 -14
- package/dist/ui/agent-turn.d.ts +1 -1
- package/dist/ui/agent-turn.js +4 -37
- package/dist/ui/animated-number.js +15 -28
- package/dist/ui/approval-card.js +5 -90
- package/dist/ui/artifact-body.js +47 -125
- package/dist/ui/artifact-notice.d.ts +1 -1
- package/dist/ui/artifact-notice.js +9 -16
- package/dist/ui/avatar.d.ts +1 -1
- package/dist/ui/avatar.js +11 -48
- package/dist/ui/badge.js +4 -12
- package/dist/ui/bar-chart.d.ts +1 -1
- package/dist/ui/bar-chart.js +22 -74
- package/dist/ui/block-card.js +7 -45
- package/dist/ui/boot-screen.d.ts +1 -1
- package/dist/ui/boot-screen.js +4 -33
- package/dist/ui/bulk-action-bar.d.ts +1 -1
- package/dist/ui/bulk-action-bar.js +14 -33
- package/dist/ui/button.js +10 -24
- package/dist/ui/card.js +5 -25
- package/dist/ui/category-bars.js +14 -59
- package/dist/ui/chart-frame.d.ts +2 -2
- package/dist/ui/chart-frame.js +6 -85
- package/dist/ui/chat-composer.js +4 -16
- package/dist/ui/chat-dock-timing.js +7 -3
- package/dist/ui/chat-input.js +20 -100
- package/dist/ui/chat-panel.d.ts +1 -1
- package/dist/ui/chat-panel.js +7 -41
- package/dist/ui/chat-thread.js +13 -31
- package/dist/ui/checkbox.js +10 -52
- package/dist/ui/command-palette.js +71 -246
- package/dist/ui/compare-body.d.ts +1 -1
- package/dist/ui/compare-body.js +28 -98
- package/dist/ui/confirm-button.js +8 -15
- package/dist/ui/corbits-mark.js +7 -16
- package/dist/ui/csv-table.d.ts +1 -1
- package/dist/ui/csv-table.js +8 -50
- package/dist/ui/dialog.d.ts +1 -1
- package/dist/ui/dialog.js +32 -62
- package/dist/ui/dictation-status-line.js +7 -25
- package/dist/ui/dither-canvas.d.ts +1 -1
- package/dist/ui/dither-canvas.js +31 -56
- package/dist/ui/embed-body.d.ts +1 -1
- package/dist/ui/embed-body.js +7 -56
- package/dist/ui/empty-state.d.ts +1 -1
- package/dist/ui/empty-state.js +3 -26
- package/dist/ui/file-input.js +17 -37
- package/dist/ui/filter-bar.d.ts +1 -1
- package/dist/ui/filter-bar.js +11 -71
- package/dist/ui/filter-chip.d.ts +1 -1
- package/dist/ui/filter-chip.js +7 -15
- package/dist/ui/gate-block.d.ts +2 -1
- package/dist/ui/gate-block.js +4 -29
- package/dist/ui/horizontal-stepper.d.ts +1 -1
- package/dist/ui/horizontal-stepper.js +18 -45
- package/dist/ui/input.js +1 -6
- package/dist/ui/inspector-shell.d.ts +5 -5
- package/dist/ui/inspector-shell.js +14 -81
- package/dist/ui/intake-form.d.ts +1 -1
- package/dist/ui/intake-form.js +21 -97
- package/dist/ui/kind-card-grid.js +9 -31
- package/dist/ui/library-page-header.js +4 -32
- package/dist/ui/list-detail.js +5 -35
- package/dist/ui/live-run-banner.d.ts +1 -1
- package/dist/ui/live-run-banner.js +5 -15
- package/dist/ui/live-status-line.js +6 -24
- package/dist/ui/menu.js +7 -24
- package/dist/ui/message-bubble.d.ts +3 -3
- package/dist/ui/message-bubble.js +5 -44
- package/dist/ui/mic-button.d.ts +1 -1
- package/dist/ui/mic-button.js +15 -21
- package/dist/ui/mic-permission-dialog.js +5 -41
- package/dist/ui/notifications-bell.js +9 -43
- package/dist/ui/now-cards.d.ts +2 -2
- package/dist/ui/now-cards.js +16 -94
- package/dist/ui/page-panel.js +11 -11
- package/dist/ui/page-shell.js +4 -11
- package/dist/ui/parts-renderer.js +51 -149
- package/dist/ui/profile-card.js +7 -111
- package/dist/ui/progress-checklist.js +11 -49
- package/dist/ui/provider-mark.d.ts +2 -2
- package/dist/ui/provider-mark.js +9 -16
- package/dist/ui/quick-reply-chips.js +6 -14
- package/dist/ui/quote-card.js +12 -32
- package/dist/ui/reasoning-block.d.ts +1 -1
- package/dist/ui/reasoning-block.js +14 -33
- package/dist/ui/research-body.js +32 -213
- package/dist/ui/rich-empty-state.js +6 -48
- package/dist/ui/run-now-button.js +14 -15
- package/dist/ui/section.d.ts +1 -1
- package/dist/ui/section.js +4 -40
- package/dist/ui/select.js +1 -15
- package/dist/ui/selection-checkbox.d.ts +1 -1
- package/dist/ui/selection-checkbox.js +11 -29
- package/dist/ui/settings-panel.js +7 -50
- package/dist/ui/shimmer-text.js +3 -6
- package/dist/ui/sidebar-item-row.d.ts +1 -1
- package/dist/ui/sidebar-item-row.js +9 -39
- package/dist/ui/sidebar-panel.js +15 -40
- package/dist/ui/sidebar.js +15 -76
- package/dist/ui/skeleton.js +3 -7
- package/dist/ui/sortable-table.js +29 -72
- package/dist/ui/sparkline.js +14 -38
- package/dist/ui/stat-grid.js +17 -52
- package/dist/ui/status-dot.d.ts +1 -1
- package/dist/ui/status-dot.js +8 -20
- package/dist/ui/step-list.d.ts +1 -0
- package/dist/ui/step-list.js +11 -50
- package/dist/ui/switch.js +4 -16
- package/dist/ui/table.js +7 -32
- package/dist/ui/tabs.js +39 -54
- package/dist/ui/textarea.js +10 -19
- package/dist/ui/theme-provider.js +54 -78
- package/dist/ui/theme-toggle.js +13 -16
- package/dist/ui/thinking-indicator.js +3 -15
- package/dist/ui/thinking-label.js +16 -35
- package/dist/ui/thinking-mark.d.ts +1 -1
- package/dist/ui/thinking-mark.js +4 -145
- package/dist/ui/time-series-chart.js +43 -174
- package/dist/ui/toast.js +12 -20
- package/dist/ui/token-mosaic.js +5 -43
- package/dist/ui/tool-block.js +18 -70
- package/dist/ui/tool-narrative.d.ts +1 -1
- package/dist/ui/tool-narrative.js +10 -57
- package/dist/ui/tool-picker.js +57 -145
- package/dist/ui/tooltip.d.ts +1 -1
- package/dist/ui/tooltip.js +4 -33
- package/dist/ui/top-bar.js +14 -72
- package/dist/ui/trace-waterfall.d.ts +1 -1
- package/dist/ui/trace-waterfall.js +21 -93
- package/dist/ui/typing-indicator.d.ts +1 -1
- package/dist/ui/typing-indicator.js +4 -18
- package/dist/ui/view-toggle.js +10 -29
- package/dist/ui/voice-waveform.js +3 -11
- package/package.json +94 -535
package/dist/ui/block-card.js
CHANGED
|
@@ -8,59 +8,21 @@ import { cn } from "../lib/utils.js";
|
|
|
8
8
|
* can tell "the agent made this" at a glance. Lifted out of a consumer app
|
|
9
9
|
* unchanged; see `RiskBadge` below for the tone it pairs with inside
|
|
10
10
|
* `children`.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
className: cn("overflow-hidden rounded-none border border-border bg-card", className),
|
|
15
|
-
children: [
|
|
16
|
-
/*#__PURE__*/ _jsxs("div", {
|
|
17
|
-
"data-slot": "block-card-header",
|
|
18
|
-
className: "flex items-center gap-2 border-b border-border px-3.5 py-2.5 text-xs font-bold tracking-[0.02em] text-primary-emphasis",
|
|
19
|
-
children: [
|
|
20
|
-
/*#__PURE__*/ _jsx("span", {
|
|
21
|
-
"aria-hidden": true,
|
|
22
|
-
className: "size-1.5 shrink-0 rounded-none bg-current [animation:corbits-block-pulse_1.6s_ease_infinite]"
|
|
23
|
-
}),
|
|
24
|
-
/*#__PURE__*/ _jsx("span", {
|
|
25
|
-
"data-slot": "block-card-title",
|
|
26
|
-
children: title
|
|
27
|
-
})
|
|
28
|
-
]
|
|
29
|
-
}),
|
|
30
|
-
/*#__PURE__*/ _jsx("div", {
|
|
31
|
-
"data-slot": "block-card-body",
|
|
32
|
-
className: "p-4",
|
|
33
|
-
children: children
|
|
34
|
-
})
|
|
35
|
-
]
|
|
36
|
-
});
|
|
11
|
+
*/
|
|
12
|
+
export function BlockCard({ title, children, className }) {
|
|
13
|
+
return (_jsxs("div", { "data-slot": "block-card", className: cn("overflow-hidden rounded-none border border-border bg-card", className), children: [_jsxs("div", { "data-slot": "block-card-header", className: "flex items-center gap-2 border-b border-border px-3.5 py-2.5 text-xs font-bold tracking-[0.02em] text-primary-emphasis", children: [_jsx("span", { "aria-hidden": true, className: "size-1.5 shrink-0 rounded-none bg-current [animation:corbits-block-pulse_1.6s_ease_infinite]" }), _jsx("span", { "data-slot": "block-card-title", children: title })] }), _jsx("div", { "data-slot": "block-card-body", className: "p-4", children: children })] }));
|
|
37
14
|
}
|
|
38
15
|
const RISK_TONE_CLASS = {
|
|
39
16
|
low: "text-muted-foreground",
|
|
40
17
|
medium: "text-warn",
|
|
41
|
-
high: "text-destructive"
|
|
18
|
+
high: "text-destructive",
|
|
42
19
|
};
|
|
43
20
|
/**
|
|
44
21
|
* A risk callout for a block whose action carries consequence — approve this
|
|
45
22
|
* order cancellation, run this migration. `level` drives colour only; the
|
|
46
23
|
* `label` is what actually says what the risk is, so the badge is never a
|
|
47
24
|
* bare colour dot.
|
|
48
|
-
*/
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"data-risk": level,
|
|
52
|
-
className: cn("inline-flex items-center gap-1.5 text-xs font-bold [&_svg]:size-3.5", RISK_TONE_CLASS[level], className),
|
|
53
|
-
children: [
|
|
54
|
-
/*#__PURE__*/ _jsx(TriangleAlert, {
|
|
55
|
-
"aria-hidden": true
|
|
56
|
-
}),
|
|
57
|
-
/*#__PURE__*/ _jsx("span", {
|
|
58
|
-
children: label
|
|
59
|
-
}),
|
|
60
|
-
note === undefined ? null : /*#__PURE__*/ _jsx("span", {
|
|
61
|
-
className: "font-medium text-muted-foreground",
|
|
62
|
-
children: note
|
|
63
|
-
})
|
|
64
|
-
]
|
|
65
|
-
});
|
|
25
|
+
*/
|
|
26
|
+
export function RiskBadge({ level, label, note, className }) {
|
|
27
|
+
return (_jsxs("span", { "data-slot": "risk-badge", "data-risk": level, className: cn("inline-flex items-center gap-1.5 text-xs font-bold [&_svg]:size-3.5", RISK_TONE_CLASS[level], className), children: [_jsx(TriangleAlert, { "aria-hidden": true }), _jsx("span", { children: label }), note === undefined ? null : (_jsx("span", { className: "font-medium text-muted-foreground", children: note }))] }));
|
|
66
28
|
}
|
package/dist/ui/boot-screen.d.ts
CHANGED
|
@@ -20,4 +20,4 @@ export type BootScreenProps = {
|
|
|
20
20
|
* to a still frame under the theme's reduced-motion rule with nothing to do
|
|
21
21
|
* here.
|
|
22
22
|
*/
|
|
23
|
-
export declare function BootScreen({ message, brand, footer, className }: BootScreenProps): import("react").JSX.Element;
|
|
23
|
+
export declare function BootScreen({ message, brand, footer, className, }: BootScreenProps): import("react").JSX.Element;
|
package/dist/ui/boot-screen.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
3
|
import { useId } from "react";
|
|
3
4
|
import { cn } from "../lib/utils.js";
|
|
@@ -12,38 +13,8 @@ import { cn } from "../lib/utils.js";
|
|
|
12
13
|
* No spinner: the pulsing bar is decorative and `aria-hidden`, and it collapses
|
|
13
14
|
* to a still frame under the theme's reduced-motion rule with nothing to do
|
|
14
15
|
* here.
|
|
15
|
-
*/
|
|
16
|
+
*/
|
|
17
|
+
export function BootScreen({ message, brand, footer, className, }) {
|
|
16
18
|
const messageId = useId();
|
|
17
|
-
return
|
|
18
|
-
role: "status",
|
|
19
|
-
"aria-labelledby": messageId,
|
|
20
|
-
className: cn("absolute inset-0 overflow-hidden bg-background text-foreground", className),
|
|
21
|
-
children: [
|
|
22
|
-
brand === undefined ? null : /*#__PURE__*/ _jsx("div", {
|
|
23
|
-
className: "absolute top-6 left-7",
|
|
24
|
-
children: brand
|
|
25
|
-
}),
|
|
26
|
-
/*#__PURE__*/ _jsxs("div", {
|
|
27
|
-
className: "absolute inset-0 flex flex-col items-center justify-center gap-4 p-6",
|
|
28
|
-
children: [
|
|
29
|
-
/*#__PURE__*/ _jsx("span", {
|
|
30
|
-
"aria-hidden": true,
|
|
31
|
-
className: "h-0.5 w-24 overflow-hidden rounded-full bg-muted",
|
|
32
|
-
children: /*#__PURE__*/ _jsx("span", {
|
|
33
|
-
className: "block h-full w-1/3 rounded-full bg-primary [animation:corbits-boot-sweep_1.4s_ease-in-out_infinite]"
|
|
34
|
-
})
|
|
35
|
-
}),
|
|
36
|
-
/*#__PURE__*/ _jsx("p", {
|
|
37
|
-
id: messageId,
|
|
38
|
-
className: "max-w-[32ch] text-center text-xs leading-relaxed text-muted-foreground",
|
|
39
|
-
children: message
|
|
40
|
-
})
|
|
41
|
-
]
|
|
42
|
-
}),
|
|
43
|
-
footer === undefined ? null : /*#__PURE__*/ _jsx("div", {
|
|
44
|
-
className: "absolute bottom-6 left-7 font-mono text-[11px] text-muted-foreground",
|
|
45
|
-
children: footer
|
|
46
|
-
})
|
|
47
|
-
]
|
|
48
|
-
});
|
|
19
|
+
return (_jsxs("div", { role: "status", "aria-labelledby": messageId, className: cn("absolute inset-0 overflow-hidden bg-background text-foreground", className), children: [brand === undefined ? null : (_jsx("div", { className: "absolute top-6 left-7", children: brand })), _jsxs("div", { className: "absolute inset-0 flex flex-col items-center justify-center gap-4 p-6", children: [_jsx("span", { "aria-hidden": true, className: "h-0.5 w-24 overflow-hidden rounded-full bg-muted", children: _jsx("span", { className: "block h-full w-1/3 rounded-full bg-primary [animation:corbits-boot-sweep_1.4s_ease-in-out_infinite]" }) }), _jsx("p", { id: messageId, className: "max-w-[32ch] text-center text-xs leading-relaxed text-muted-foreground", children: message })] }), footer === undefined ? null : (_jsx("div", { className: "absolute bottom-6 left-7 font-mono text-[11px] text-muted-foreground", children: footer }))] }));
|
|
49
20
|
}
|
|
@@ -34,4 +34,4 @@ export type BulkActionBarProps = {
|
|
|
34
34
|
* already handled its own Escape wins instead of also clearing the
|
|
35
35
|
* selection underneath it.
|
|
36
36
|
*/
|
|
37
|
-
export declare function BulkActionBar({ count, onClear, children, label, className }: BulkActionBarProps): import("react").JSX.Element | null;
|
|
37
|
+
export declare function BulkActionBar({ count, onClear, children, label, className, }: BulkActionBarProps): import("react").JSX.Element | null;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
3
|
import { useEffect } from "react";
|
|
3
4
|
import { cn } from "../lib/utils.js";
|
|
4
5
|
/**
|
|
@@ -26,39 +27,19 @@ import { cn } from "../lib/utils.js";
|
|
|
26
27
|
* `event.defaultPrevented`, so a dialog or input stacked above the bar that
|
|
27
28
|
* already handled its own Escape wins instead of also clearing the
|
|
28
29
|
* selection underneath it.
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
*/
|
|
31
|
+
export function BulkActionBar({ count, onClear, children, label = "Bulk actions", className, }) {
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (count === 0)
|
|
34
|
+
return;
|
|
32
35
|
function onKeyDown(event) {
|
|
33
|
-
if (event.key === "Escape" && !event.defaultPrevented)
|
|
36
|
+
if (event.key === "Escape" && !event.defaultPrevented)
|
|
37
|
+
onClear();
|
|
34
38
|
}
|
|
35
39
|
window.addEventListener("keydown", onKeyDown);
|
|
36
|
-
return ()=>window.removeEventListener("keydown", onKeyDown);
|
|
37
|
-
}, [
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
]);
|
|
41
|
-
if (count === 0) return null;
|
|
42
|
-
return /*#__PURE__*/ _jsx("div", {
|
|
43
|
-
className: cn("fixed bottom-6 left-1/2 z-40 -translate-x-1/2", className),
|
|
44
|
-
children: /*#__PURE__*/ _jsxs("div", {
|
|
45
|
-
role: "group",
|
|
46
|
-
"aria-label": label,
|
|
47
|
-
className: cn("flex items-center gap-3 rounded-full border border-border bg-card px-4 py-2 shadow-lg", "motion-safe:[animation:corbits-bulk-action-bar-in_220ms_var(--ease-out)_both]"),
|
|
48
|
-
children: [
|
|
49
|
-
/*#__PURE__*/ _jsxs("span", {
|
|
50
|
-
"aria-live": "polite",
|
|
51
|
-
className: "text-sm font-medium whitespace-nowrap",
|
|
52
|
-
children: [
|
|
53
|
-
count,
|
|
54
|
-
" selected"
|
|
55
|
-
]
|
|
56
|
-
}),
|
|
57
|
-
/*#__PURE__*/ _jsx("div", {
|
|
58
|
-
className: "flex items-center gap-2",
|
|
59
|
-
children: children
|
|
60
|
-
})
|
|
61
|
-
]
|
|
62
|
-
})
|
|
63
|
-
});
|
|
40
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
41
|
+
}, [count, onClear]);
|
|
42
|
+
if (count === 0)
|
|
43
|
+
return null;
|
|
44
|
+
return (_jsx("div", { className: cn("fixed bottom-6 left-1/2 z-40 -translate-x-1/2", className), children: _jsxs("div", { role: "group", "aria-label": label, className: cn("flex items-center gap-3 rounded-full border border-border bg-card px-4 py-2 shadow-lg", "motion-safe:[animation:corbits-bulk-action-bar-in_220ms_var(--ease-out)_both]"), children: [_jsxs("span", { "aria-live": "polite", className: "text-sm font-medium whitespace-nowrap", children: [count, " selected"] }), _jsx("div", { className: "flex items-center gap-2", children: children })] }) }));
|
|
64
45
|
}
|
package/dist/ui/button.js
CHANGED
|
@@ -10,7 +10,8 @@ import { cn } from "../lib/utils.js";
|
|
|
10
10
|
// orange primary. That measures 2.69:1, a hard AA failure. `text-primary-
|
|
11
11
|
// foreground` resolves to ink in light (5.53:1) and black in dark (5.34:1),
|
|
12
12
|
// which is correct. DESIGN.md is wrong; do not "fix" this back.
|
|
13
|
-
const buttonVariantsBase = cva(
|
|
13
|
+
const buttonVariantsBase = cva(
|
|
14
|
+
// active:brightness-95 is the press state for every variant: it darkens the
|
|
14
15
|
// rendered fill whatever that fill is, so it needs no per-variant pressed
|
|
15
16
|
// token. Deliberately outside `transition-colors` — a press should land on
|
|
16
17
|
// the frame the pointer goes down, not ease in. The scale feedback gets its
|
|
@@ -24,33 +25,25 @@ const buttonVariantsBase = cva(// active:brightness-95 is the press state for ev
|
|
|
24
25
|
outline: "border border-input bg-transparent hover:bg-muted",
|
|
25
26
|
ghost: "hover:bg-muted",
|
|
26
27
|
link: "text-primary-emphasis underline-offset-4 hover:underline",
|
|
27
|
-
destructive: "bg-destructive text-destructive-foreground hover:opacity-90"
|
|
28
|
+
destructive: "bg-destructive text-destructive-foreground hover:opacity-90",
|
|
28
29
|
},
|
|
29
30
|
size: {
|
|
30
31
|
sm: "h-8 px-3",
|
|
31
32
|
md: "h-9 px-4",
|
|
32
33
|
lg: "h-10 px-6",
|
|
33
|
-
icon: "size-9"
|
|
34
|
-
}
|
|
34
|
+
icon: "size-9",
|
|
35
|
+
},
|
|
35
36
|
},
|
|
36
37
|
// link reads as inline text, not a control — it opts out of every size's
|
|
37
38
|
// fixed height/padding rather than getting a box of its own.
|
|
38
39
|
compoundVariants: [
|
|
39
40
|
{
|
|
40
41
|
variant: "link",
|
|
41
|
-
size: [
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"lg",
|
|
45
|
-
"icon"
|
|
46
|
-
],
|
|
47
|
-
class: "h-auto px-0"
|
|
48
|
-
}
|
|
42
|
+
size: ["sm", "md", "lg", "icon"],
|
|
43
|
+
class: "h-auto px-0",
|
|
44
|
+
},
|
|
49
45
|
],
|
|
50
|
-
defaultVariants: {
|
|
51
|
-
variant: "primary",
|
|
52
|
-
size: "md"
|
|
53
|
-
}
|
|
46
|
+
defaultVariants: { variant: "primary", size: "md" },
|
|
54
47
|
});
|
|
55
48
|
// cva concatenates variant, size, and compound-variant classes as plain
|
|
56
49
|
// strings with no dedup, so the compound override above only wins once
|
|
@@ -61,13 +54,6 @@ function buttonVariants(props) {
|
|
|
61
54
|
}
|
|
62
55
|
export function Button({ className, variant, size, asChild = false, ...props }) {
|
|
63
56
|
const Comp = asChild ? Slot : "button";
|
|
64
|
-
return
|
|
65
|
-
"data-slot": "button",
|
|
66
|
-
className: cn(buttonVariants({
|
|
67
|
-
variant,
|
|
68
|
-
size
|
|
69
|
-
}), className),
|
|
70
|
-
...props
|
|
71
|
-
});
|
|
57
|
+
return (_jsx(Comp, { "data-slot": "button", className: cn(buttonVariants({ variant, size }), className), ...props }));
|
|
72
58
|
}
|
|
73
59
|
export { buttonVariants };
|
package/dist/ui/card.js
CHANGED
|
@@ -1,37 +1,17 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { cn } from "../lib/utils.js";
|
|
3
3
|
export function Card({ className, ...props }) {
|
|
4
|
-
return
|
|
5
|
-
"data-slot": "card",
|
|
6
|
-
className: cn("flex flex-col gap-4 rounded-lg border border-border bg-card p-6 text-card-foreground", className),
|
|
7
|
-
...props
|
|
8
|
-
});
|
|
4
|
+
return (_jsx("div", { "data-slot": "card", className: cn("flex flex-col gap-4 rounded-lg border border-border bg-card p-6 text-card-foreground", className), ...props }));
|
|
9
5
|
}
|
|
10
6
|
export function CardHeader({ className, ...props }) {
|
|
11
|
-
return
|
|
12
|
-
"data-slot": "card-header",
|
|
13
|
-
className: cn("flex flex-col gap-1", className),
|
|
14
|
-
...props
|
|
15
|
-
});
|
|
7
|
+
return (_jsx("div", { "data-slot": "card-header", className: cn("flex flex-col gap-1", className), ...props }));
|
|
16
8
|
}
|
|
17
9
|
export function CardTitle({ className, ...props }) {
|
|
18
|
-
return
|
|
19
|
-
"data-slot": "card-title",
|
|
20
|
-
className: cn("text-base leading-none font-semibold", className),
|
|
21
|
-
...props
|
|
22
|
-
});
|
|
10
|
+
return (_jsx("h3", { "data-slot": "card-title", className: cn("text-base leading-none font-semibold", className), ...props }));
|
|
23
11
|
}
|
|
24
12
|
export function CardDescription({ className, ...props }) {
|
|
25
|
-
return
|
|
26
|
-
"data-slot": "card-description",
|
|
27
|
-
className: cn("text-sm text-muted-foreground", className),
|
|
28
|
-
...props
|
|
29
|
-
});
|
|
13
|
+
return (_jsx("p", { "data-slot": "card-description", className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
30
14
|
}
|
|
31
15
|
export function CardFooter({ className, ...props }) {
|
|
32
|
-
return
|
|
33
|
-
"data-slot": "card-footer",
|
|
34
|
-
className: cn("flex items-center gap-2", className),
|
|
35
|
-
...props
|
|
36
|
-
});
|
|
16
|
+
return (_jsx("div", { "data-slot": "card-footer", className: cn("flex items-center gap-2", className), ...props }));
|
|
37
17
|
}
|
package/dist/ui/category-bars.js
CHANGED
|
@@ -6,64 +6,19 @@ import { ChartFrame } from "./chart-frame.js";
|
|
|
6
6
|
* Dense horizontal category ranking for cost-by-model / calls-by-tool
|
|
7
7
|
* style tables. Bars share one series colour; length encodes magnitude.
|
|
8
8
|
* Absent secondary labels stay empty rather than inventing a zero.
|
|
9
|
-
*/
|
|
10
|
-
|
|
9
|
+
*/
|
|
10
|
+
export function CategoryBars({ title, description, data, valueLabel = "Value", format = formatCompact, className, }) {
|
|
11
|
+
const max = Math.max(0, ...data.map((d) => d.value));
|
|
11
12
|
const axisMax = max === 0 ? 1 : max;
|
|
12
|
-
return
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
rows: data.map((datum)=>[
|
|
24
|
-
datum.label,
|
|
25
|
-
format(datum.value),
|
|
26
|
-
datum.secondaryLabel ?? "—"
|
|
27
|
-
])
|
|
28
|
-
},
|
|
29
|
-
className: className,
|
|
30
|
-
children: /*#__PURE__*/ _jsx("div", {
|
|
31
|
-
className: "flex flex-col gap-2",
|
|
32
|
-
role: "presentation",
|
|
33
|
-
children: data.map((datum)=>{
|
|
34
|
-
const pct = datum.value / axisMax * 100;
|
|
35
|
-
return /*#__PURE__*/ _jsxs("div", {
|
|
36
|
-
className: "grid grid-cols-[minmax(6rem,10rem)_1fr_auto] items-center gap-2",
|
|
37
|
-
children: [
|
|
38
|
-
/*#__PURE__*/ _jsx("p", {
|
|
39
|
-
className: "truncate text-xs font-medium",
|
|
40
|
-
children: datum.label
|
|
41
|
-
}),
|
|
42
|
-
/*#__PURE__*/ _jsx("div", {
|
|
43
|
-
className: "h-3 w-full bg-muted",
|
|
44
|
-
children: /*#__PURE__*/ _jsx("div", {
|
|
45
|
-
className: cn("h-full bg-primary-emphasis"),
|
|
46
|
-
style: {
|
|
47
|
-
width: `${pct}%`
|
|
48
|
-
}
|
|
49
|
-
})
|
|
50
|
-
}),
|
|
51
|
-
/*#__PURE__*/ _jsxs("div", {
|
|
52
|
-
className: "min-w-[3.5rem] text-right font-mono text-[11px] leading-tight",
|
|
53
|
-
children: [
|
|
54
|
-
/*#__PURE__*/ _jsx("p", {
|
|
55
|
-
className: "font-semibold",
|
|
56
|
-
children: format(datum.value)
|
|
57
|
-
}),
|
|
58
|
-
datum.secondaryLabel === undefined ? null : /*#__PURE__*/ _jsx("p", {
|
|
59
|
-
className: "text-muted-foreground",
|
|
60
|
-
children: datum.secondaryLabel
|
|
61
|
-
})
|
|
62
|
-
]
|
|
63
|
-
})
|
|
64
|
-
]
|
|
65
|
-
}, datum.label);
|
|
66
|
-
})
|
|
67
|
-
})
|
|
68
|
-
});
|
|
13
|
+
return (_jsx(ChartFrame, { title: title, ...(description === undefined ? {} : { description }), table: {
|
|
14
|
+
columns: ["Category", valueLabel, "Detail"],
|
|
15
|
+
rows: data.map((datum) => [
|
|
16
|
+
datum.label,
|
|
17
|
+
format(datum.value),
|
|
18
|
+
datum.secondaryLabel ?? "—",
|
|
19
|
+
]),
|
|
20
|
+
}, className: className, children: _jsx("div", { className: "flex flex-col gap-2", role: "presentation", children: data.map((datum) => {
|
|
21
|
+
const pct = (datum.value / axisMax) * 100;
|
|
22
|
+
return (_jsxs("div", { className: "grid grid-cols-[minmax(6rem,10rem)_1fr_auto] items-center gap-2", children: [_jsx("p", { className: "truncate text-xs font-medium", children: datum.label }), _jsx("div", { className: "h-3 w-full bg-muted", children: _jsx("div", { className: cn("h-full bg-primary-emphasis"), style: { width: `${pct}%` } }) }), _jsxs("div", { className: "min-w-[3.5rem] text-right font-mono text-[11px] leading-tight", children: [_jsx("p", { className: "font-semibold", children: format(datum.value) }), datum.secondaryLabel === undefined ? null : (_jsx("p", { className: "text-muted-foreground", children: datum.secondaryLabel }))] })] }, datum.label));
|
|
23
|
+
}) }) }));
|
|
69
24
|
}
|
package/dist/ui/chart-frame.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ export type ChartFrameProps = {
|
|
|
29
29
|
readonly table: ChartTable;
|
|
30
30
|
/** The plot itself — an `<svg>`. */
|
|
31
31
|
readonly children: ReactNode;
|
|
32
|
-
readonly className?: string;
|
|
32
|
+
readonly className?: string | undefined;
|
|
33
33
|
};
|
|
34
34
|
/**
|
|
35
35
|
* The frame every chart here sits in: a caption, a legend, the plot, and the
|
|
@@ -51,4 +51,4 @@ export type ChartFrameProps = {
|
|
|
51
51
|
* cross-reference. Text never wears the series colour: a mid-lightness hue that
|
|
52
52
|
* is correct for a 24px bar is unreadable at 12px.
|
|
53
53
|
*/
|
|
54
|
-
export declare function ChartFrame({ title, description, legend, table, children, className }: ChartFrameProps): import("react").JSX.Element;
|
|
54
|
+
export declare function ChartFrame({ title, description, legend, table, children, className, }: ChartFrameProps): import("react").JSX.Element;
|
package/dist/ui/chart-frame.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { cn } from "../lib/utils.js";
|
|
3
|
-
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "./table.js";
|
|
3
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "./table.js";
|
|
4
4
|
/**
|
|
5
5
|
* The frame every chart here sits in: a caption, a legend, the plot, and the
|
|
6
6
|
* same data as a table.
|
|
@@ -20,89 +20,10 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from ".
|
|
|
20
20
|
* swatch with text — the text is the identity channel, the swatch is the
|
|
21
21
|
* cross-reference. Text never wears the series colour: a mid-lightness hue that
|
|
22
22
|
* is correct for a 24px bar is unreadable at 12px.
|
|
23
|
-
*/
|
|
23
|
+
*/
|
|
24
|
+
export function ChartFrame({ title, description, legend, table, children, className, }) {
|
|
24
25
|
const showLegend = legend !== undefined && legend.length > 1;
|
|
25
|
-
return
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
/*#__PURE__*/ _jsxs("figcaption", {
|
|
29
|
-
className: "flex flex-col gap-0.5",
|
|
30
|
-
children: [
|
|
31
|
-
/*#__PURE__*/ _jsx("span", {
|
|
32
|
-
className: "text-sm font-semibold",
|
|
33
|
-
children: title
|
|
34
|
-
}),
|
|
35
|
-
description === undefined ? null : /*#__PURE__*/ _jsx("span", {
|
|
36
|
-
className: "text-xs text-muted-foreground",
|
|
37
|
-
children: description
|
|
38
|
-
})
|
|
39
|
-
]
|
|
40
|
-
}),
|
|
41
|
-
showLegend ? /*#__PURE__*/ _jsx("ul", {
|
|
42
|
-
className: "flex flex-wrap items-center gap-x-4 gap-y-1",
|
|
43
|
-
children: legend.map((entry)=>/*#__PURE__*/ _jsxs("li", {
|
|
44
|
-
className: "flex items-center gap-1.5 text-xs text-muted-foreground",
|
|
45
|
-
children: [
|
|
46
|
-
entry.dash === undefined ? /*#__PURE__*/ _jsx("span", {
|
|
47
|
-
"aria-hidden": true,
|
|
48
|
-
className: "size-2.5 shrink-0 rounded-xs",
|
|
49
|
-
style: {
|
|
50
|
-
backgroundColor: entry.color
|
|
51
|
-
}
|
|
52
|
-
}) : /*#__PURE__*/ _jsx("svg", {
|
|
53
|
-
"aria-hidden": true,
|
|
54
|
-
viewBox: "0 0 20 4",
|
|
55
|
-
className: "h-1 w-5 shrink-0 overflow-visible",
|
|
56
|
-
children: /*#__PURE__*/ _jsx("line", {
|
|
57
|
-
x1: 0,
|
|
58
|
-
y1: 2,
|
|
59
|
-
x2: 20,
|
|
60
|
-
y2: 2,
|
|
61
|
-
stroke: entry.color,
|
|
62
|
-
strokeWidth: 2.5,
|
|
63
|
-
strokeLinecap: "butt",
|
|
64
|
-
strokeDasharray: entry.dash
|
|
65
|
-
})
|
|
66
|
-
}),
|
|
67
|
-
entry.label
|
|
68
|
-
]
|
|
69
|
-
}, entry.label))
|
|
70
|
-
}) : null,
|
|
71
|
-
children,
|
|
72
|
-
/*#__PURE__*/ _jsxs("details", {
|
|
73
|
-
className: "text-xs",
|
|
74
|
-
children: [
|
|
75
|
-
/*#__PURE__*/ _jsx("summary", {
|
|
76
|
-
className: "cursor-pointer text-muted-foreground hover:text-foreground",
|
|
77
|
-
children: "Show the data"
|
|
78
|
-
}),
|
|
79
|
-
/*#__PURE__*/ _jsx("div", {
|
|
80
|
-
className: "mt-2",
|
|
81
|
-
children: /*#__PURE__*/ _jsxs(Table, {
|
|
82
|
-
"aria-label": `${title} — data`,
|
|
83
|
-
children: [
|
|
84
|
-
/*#__PURE__*/ _jsx(TableHeader, {
|
|
85
|
-
children: /*#__PURE__*/ _jsx(TableRow, {
|
|
86
|
-
children: table.columns.map((column, index)=>/*#__PURE__*/ _jsx(TableHead, {
|
|
87
|
-
scope: "col",
|
|
88
|
-
className: index === 0 ? undefined : "text-right",
|
|
89
|
-
children: column
|
|
90
|
-
}, column))
|
|
91
|
-
})
|
|
92
|
-
}),
|
|
93
|
-
/*#__PURE__*/ _jsx(TableBody, {
|
|
94
|
-
children: table.rows.map((row, rowIndex)=>/*#__PURE__*/ _jsx(TableRow, {
|
|
95
|
-
children: row.map((cell, cellIndex)=>/*#__PURE__*/ _jsx(TableCell, {
|
|
96
|
-
className: cellIndex === 0 ? undefined : "text-right font-mono tabular-nums",
|
|
97
|
-
children: cell
|
|
98
|
-
}, cellIndex))
|
|
99
|
-
}, rowIndex))
|
|
100
|
-
})
|
|
101
|
-
]
|
|
102
|
-
})
|
|
103
|
-
})
|
|
104
|
-
]
|
|
105
|
-
})
|
|
106
|
-
]
|
|
107
|
-
});
|
|
26
|
+
return (_jsxs("figure", { className: cn("flex flex-col gap-3", className), children: [_jsxs("figcaption", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-sm font-semibold", children: title }), description === undefined ? null : (_jsx("span", { className: "text-xs text-muted-foreground", children: description }))] }), showLegend ? (_jsx("ul", { className: "flex flex-wrap items-center gap-x-4 gap-y-1", children: legend.map((entry) => (_jsxs("li", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [entry.dash === undefined ? (_jsx("span", { "aria-hidden": true, className: "size-2.5 shrink-0 rounded-xs", style: { backgroundColor: entry.color } })) : (_jsx("svg", { "aria-hidden": true, viewBox: "0 0 20 4", className: "h-1 w-5 shrink-0 overflow-visible", children: _jsx("line", { x1: 0, y1: 2, x2: 20, y2: 2, stroke: entry.color, strokeWidth: 2.5, strokeLinecap: "butt", strokeDasharray: entry.dash }) })), entry.label] }, entry.label))) })) : null, children, _jsxs("details", { className: "text-xs", children: [_jsx("summary", { className: "cursor-pointer text-muted-foreground hover:text-foreground", children: "Show the data" }), _jsx("div", { className: "mt-2", children: _jsxs(Table, { "aria-label": `${title} — data`, children: [_jsx(TableHeader, { children: _jsx(TableRow, { children: table.columns.map((column, index) => (_jsx(TableHead, { scope: "col", className: index === 0 ? undefined : "text-right", children: column }, column))) }) }), _jsx(TableBody, { children: table.rows.map((row, rowIndex) => (_jsx(TableRow, { children: row.map((cell, cellIndex) => (_jsx(TableCell, { className: cellIndex === 0
|
|
27
|
+
? undefined
|
|
28
|
+
: "text-right font-mono tabular-nums", children: cell }, cellIndex))) }, rowIndex))) })] }) })] })] }));
|
|
108
29
|
}
|
package/dist/ui/chat-composer.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
3
|
import { useRef } from "react";
|
|
3
4
|
import { useDelayedAutofocus } from "../hooks/use-delayed-autofocus.js";
|
|
@@ -10,23 +11,10 @@ import { QuickReplyChips } from "./quick-reply-chips.js";
|
|
|
10
11
|
* always-on, because a suggestion list next to ten prior turns is not a
|
|
11
12
|
* suggestion anymore — it is clutter competing with what the user already
|
|
12
13
|
* said.
|
|
13
|
-
*/
|
|
14
|
+
*/
|
|
15
|
+
export function ChatComposer({ suggestions = [], onSuggestionSelect, busy = false, autoFocusOn = false, className, ...inputProps }) {
|
|
14
16
|
const textareaRef = useRef(null);
|
|
15
17
|
useDelayedAutofocus(textareaRef, autoFocusOn);
|
|
16
18
|
const showSuggestions = suggestions.length > 0 && onSuggestionSelect !== undefined;
|
|
17
|
-
return
|
|
18
|
-
className: cn("flex flex-col gap-2", className),
|
|
19
|
-
children: [
|
|
20
|
-
showSuggestions ? /*#__PURE__*/ _jsx(QuickReplyChips, {
|
|
21
|
-
replies: suggestions,
|
|
22
|
-
onSelect: onSuggestionSelect
|
|
23
|
-
}) : null,
|
|
24
|
-
/*#__PURE__*/ _jsx(ChatInput, {
|
|
25
|
-
...inputProps,
|
|
26
|
-
working: busy,
|
|
27
|
-
disabled: busy,
|
|
28
|
-
textareaRef: textareaRef
|
|
29
|
-
})
|
|
30
|
-
]
|
|
31
|
-
});
|
|
19
|
+
return (_jsxs("div", { className: cn("flex flex-col gap-2", className), children: [showSuggestions ? (_jsx(QuickReplyChips, { replies: suggestions, onSelect: onSuggestionSelect })) : null, _jsx(ChatInput, { ...inputProps, working: busy, disabled: busy, textareaRef: textareaRef })] }));
|
|
32
20
|
}
|
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
* The dock's one source of truth for motion timing. Every duration that has
|
|
3
3
|
* to line up with another — the entrance pop, the scrim fade, the autofocus
|
|
4
4
|
* delay — lives here so fixing one never means hunting the others down.
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
5
|
+
*/
|
|
6
|
+
/** How long the closed→docked entrance pop takes, in milliseconds. */
|
|
7
|
+
export const CHAT_DOCK_ENTRANCE_MS = 280;
|
|
8
|
+
/** The scrim's own fade, coordinated to finish alongside the entrance. */
|
|
9
|
+
export const CHAT_DOCK_SCRIM_MS = CHAT_DOCK_ENTRANCE_MS;
|
|
7
10
|
/**
|
|
8
11
|
* The composer's autofocus delay. Must be `>=` the entrance duration — focus
|
|
9
12
|
* landing before the panel has finished animating steals the caret out from
|
|
10
13
|
* under a still-moving element.
|
|
11
|
-
*/
|
|
14
|
+
*/
|
|
15
|
+
export const CHAT_DOCK_AUTOFOCUS_DELAY_MS = CHAT_DOCK_ENTRANCE_MS;
|