@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/corbits-mark.js
CHANGED
|
@@ -10,24 +10,15 @@ import { cn } from "../lib/utils.js";
|
|
|
10
10
|
* It fills with `currentColor`, so it takes the colour of whatever it sits in
|
|
11
11
|
* and needs no dark-mode variant. Size it with a class; there is no `size` prop
|
|
12
12
|
* because `className` already does that job in a Tailwind codebase.
|
|
13
|
-
*/
|
|
14
|
-
|
|
13
|
+
*/
|
|
14
|
+
export const CORBITS_MARK_PATH = "M392.899 189.107L397.586 197.031C397.586 197.031 399.539 202.891 399.539 204.844L403.094 222.422C407 222.813 407.39 226.328 409.734 227.109C412.078 228.281 415.203 231.797 416.765 235.313C417.156 236.875 418.718 240.781 420.671 244.688C422.234 247.422 422.625 250.156 424.578 251.719L426.921 254.062C432.39 258.359 432.781 261.484 433.171 272.422C432.781 280.625 434.734 295.078 435.906 301.328C436.296 302.891 436.296 302.891 437.468 303.281C438.25 304.063 437.078 302.891 437.859 303.281C439.031 304.063 443.328 304.844 449.187 307.188C451.921 307.969 454.265 309.141 455.046 313.828C456.609 320.469 464.421 350.938 467.156 369.688L468.328 385.313L447.977 371.026C443.68 353.057 435.867 327.667 433.914 323.76C431.57 321.026 423.758 320.245 419.461 319.463C416.336 319.073 413.992 317.12 412.43 312.042C412.43 308.135 411.649 301.495 410.086 292.51C408.914 285.088 408.914 281.182 408.914 277.276C408.914 272.198 406.57 270.245 400.32 263.995L397.977 259.307C391.336 246.807 390.945 244.854 387.039 244.073C385.376 244.024 384.994 238.473 383.562 235.313C383.562 234.141 384.734 231.016 383.562 225.156L368.288 212.656C361.648 212.266 357.352 225.825 353.445 232.466L348.367 244.966L342.899 261.372L341.727 263.326L340.555 266.06L330.008 281.294L326.102 287.544L324.93 289.107L317.117 299.263L308.524 309.029L291.727 327.779L287.039 334.029L284.305 335.982L270.242 352.779L267.508 355.513L265.555 358.638L264.383 359.81L256.18 368.404L248.367 375.044L246.805 376.607L241.336 380.904C238.602 384.029 231.57 384.531 228.055 384.531C225.71 382.578 216.248 381.938 217.508 379.62L226.883 372.588L228.836 371.026L234.695 364.776L237.039 362.432L242.508 357.354C247.195 352.667 251.102 349.151 253.055 340.948C254.227 336.651 264.383 326.104 268.289 321.807L269.07 321.417L295.242 293.682L315.273 261.372L318.397 253.56C320.35 249.654 320.741 247.086 321.522 244.464C322.013 242.815 326.6 216.563 324.93 212.656C323.26 208.75 332.088 195.551 326.209 189.721C323.866 187.768 320.35 185.815 318.397 183.862C313.507 178.972 300.038 175.659 301.6 169.409L300.711 159.81C303.445 148.482 306.57 135.982 303.445 135.982C301.492 135.982 290.945 149.654 286.258 155.513L285.086 156.685C276.883 168.013 266.336 177.779 258.133 191.841L242.899 218.404L237.039 226.997C235.476 228.281 229.617 232.188 227.663 232.188C221.804 228.281 222.586 225.825 217.508 234.419L203.055 260.201L201.492 264.107L200.711 265.279L197.977 270.357L196.414 273.872L182.742 296.919L173.758 314.107L170.242 319.185L168.68 321.919L167.117 323.984L163.992 327.779C163.958 327.968 156.476 332.069 155.399 331.797C154.321 331.525 148.835 329.953 147.586 327.779C146.337 325.605 148.281 323.835 149.149 322.7C154.227 316.06 153.445 310.313 153.445 308.359C153.445 306.406 151.492 298.594 151.492 296.641C151.492 294.688 151.102 294.688 151.492 284.922C152.274 273.594 143.289 274.654 144.852 265.279C145.633 259.029 146.414 251.216 143.289 253.56C141.727 253.56 129.617 266.841 124.149 273.482L114.774 285.982L99.5392 305.122L96.0236 308.247L90.5548 313.716L87.4298 315.669C84.6954 319.966 77.2736 323.091 73.3673 329.732L67.1173 340.279L64.7736 344.966L61.6486 349.654L60.4767 350.826L57.7423 355.513L55.3986 358.247L42.1173 375.826L35.0861 383.247C33.7739 384.117 33.1434 384.48 32.3517 384.531C31.5599 384.582 32.3525 374.383 32.3525 374.383L33.1329 370.859L33.9142 369.185C36.6486 363.325 41.3361 357.076 46.0236 350.826C51.1017 343.404 57.3517 329.732 63.6017 320.747L68.6798 316.06L75.3204 308.247C78.0548 306.294 81.9611 301.997 86.2579 296.529L87.8204 295.357L94.8517 286.763C100.711 278.56 116.727 261.372 126.492 251.997L128.055 249.766L130.789 247.31C137.43 241.451 143.68 233.247 148.758 233.247C156.961 233.638 162.43 240.279 167.117 244.966L184.305 261.372C185.867 262.935 187.43 262.154 188.211 260.591C200.32 237.935 210.867 216.841 219.461 216.06H226.492L229.617 213.716C236.258 202.779 244.07 187.935 250.711 178.169C258.524 167.622 283.914 134.81 298.758 121.138C302.274 117.232 305.008 115.781 307.742 115C311.649 115 315.555 116.841 319.07 119.575C333.524 131.685 356.961 157.857 366.336 168.404L372.195 173.091L387.039 181.294L390.556 185.313L392.899 189.107Z";
|
|
15
|
+
/** The mark's viewBox, exported so non-SVG consumers can map path space to pixels. */
|
|
16
|
+
export const CORBITS_MARK_VIEWBOX = {
|
|
15
17
|
x: 32,
|
|
16
18
|
y: 115,
|
|
17
19
|
width: 437,
|
|
18
|
-
height: 270
|
|
20
|
+
height: 270,
|
|
19
21
|
};
|
|
20
|
-
export function CorbitsMark({ title = "Corbits", decorative = false, className }) {
|
|
21
|
-
return
|
|
22
|
-
viewBox: "32 115 437 270",
|
|
23
|
-
fill: "none",
|
|
24
|
-
role: decorative ? undefined : "img",
|
|
25
|
-
"aria-hidden": decorative ? true : undefined,
|
|
26
|
-
"aria-label": decorative ? undefined : title,
|
|
27
|
-
className: cn("size-6", className),
|
|
28
|
-
children: /*#__PURE__*/ _jsx("path", {
|
|
29
|
-
d: CORBITS_MARK_PATH,
|
|
30
|
-
fill: "currentColor"
|
|
31
|
-
})
|
|
32
|
-
});
|
|
22
|
+
export function CorbitsMark({ title = "Corbits", decorative = false, className, }) {
|
|
23
|
+
return (_jsx("svg", { viewBox: "32 115 437 270", fill: "none", role: decorative ? undefined : "img", "aria-hidden": decorative ? true : undefined, "aria-label": decorative ? undefined : title, className: cn("size-6", className), children: _jsx("path", { d: CORBITS_MARK_PATH, fill: "currentColor" }) }));
|
|
33
24
|
}
|
package/dist/ui/csv-table.d.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* freely and headers are routinely empty or repeated ("", two "Name" columns);
|
|
17
17
|
* a content key would collide and drop data.
|
|
18
18
|
*/
|
|
19
|
-
export declare function CsvTable({ text, caption }: {
|
|
19
|
+
export declare function CsvTable({ text, caption, }: {
|
|
20
20
|
readonly text: string;
|
|
21
21
|
readonly caption?: string;
|
|
22
22
|
}): import("react").JSX.Element;
|
package/dist/ui/csv-table.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
3
|
import { useMemo } from "react";
|
|
3
4
|
import { capCsv, isTabular, parseCsv } from "../lib/csv.js";
|
|
4
|
-
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "./table.js";
|
|
5
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "./table.js";
|
|
5
6
|
/**
|
|
6
7
|
* CSV text, rendered as a table when that is honest and as raw text when it is
|
|
7
8
|
* not.
|
|
@@ -19,23 +20,16 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from ".
|
|
|
19
20
|
* Columns and rows are keyed by index, never by content. CSV rows duplicate
|
|
20
21
|
* freely and headers are routinely empty or repeated ("", two "Name" columns);
|
|
21
22
|
* a content key would collide and drop data.
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
]);
|
|
23
|
+
*/
|
|
24
|
+
export function CsvTable({ text, caption = "CSV contents", }) {
|
|
25
|
+
const parsed = useMemo(() => parseCsv(text), [text]);
|
|
26
26
|
if (parsed === null) {
|
|
27
|
-
return
|
|
28
|
-
className: "rounded-md border border-border bg-muted px-4 py-6 text-center text-sm text-muted-foreground",
|
|
29
|
-
children: "This file is too large to preview — download it to see the whole thing."
|
|
30
|
-
});
|
|
27
|
+
return (_jsx("p", { className: "rounded-md border border-border bg-muted px-4 py-6 text-center text-sm text-muted-foreground", children: "This file is too large to preview \u2014 download it to see the whole thing." }));
|
|
31
28
|
}
|
|
32
29
|
if (!isTabular(parsed)) {
|
|
33
30
|
// Height-capped with its own scroll: a multi-thousand-line file as one
|
|
34
31
|
// <pre> is the same DOM freeze the size guard exists to prevent.
|
|
35
|
-
return
|
|
36
|
-
className: "max-h-96 overflow-auto rounded-md border border-border bg-muted p-3 font-mono text-xs",
|
|
37
|
-
children: text
|
|
38
|
-
});
|
|
32
|
+
return (_jsx("pre", { className: "max-h-96 overflow-auto rounded-md border border-border bg-muted p-3 font-mono text-xs", children: text }));
|
|
39
33
|
}
|
|
40
34
|
const capped = capCsv(parsed);
|
|
41
35
|
const notes = [];
|
|
@@ -45,41 +39,5 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from ".
|
|
|
45
39
|
if (capped.columnsTruncated) {
|
|
46
40
|
notes.push(`${capped.headers.length.toLocaleString()} of ${capped.totalColumns.toLocaleString()} columns`);
|
|
47
41
|
}
|
|
48
|
-
return
|
|
49
|
-
className: "flex flex-col gap-2",
|
|
50
|
-
children: [
|
|
51
|
-
/*#__PURE__*/ _jsx("div", {
|
|
52
|
-
className: "max-h-[32rem] overflow-auto rounded-md border border-border",
|
|
53
|
-
children: /*#__PURE__*/ _jsxs(Table, {
|
|
54
|
-
"aria-label": caption,
|
|
55
|
-
children: [
|
|
56
|
-
/*#__PURE__*/ _jsx(TableHeader, {
|
|
57
|
-
children: /*#__PURE__*/ _jsx(TableRow, {
|
|
58
|
-
children: capped.headers.map((header, index)=>/*#__PURE__*/ _jsx(TableHead, {
|
|
59
|
-
scope: "col",
|
|
60
|
-
children: header
|
|
61
|
-
}, index))
|
|
62
|
-
})
|
|
63
|
-
}),
|
|
64
|
-
/*#__PURE__*/ _jsx(TableBody, {
|
|
65
|
-
children: capped.rows.map((row, rowIndex)=>/*#__PURE__*/ _jsx(TableRow, {
|
|
66
|
-
children: capped.headers.map((_, cellIndex)=>/*#__PURE__*/ _jsx(TableCell, {
|
|
67
|
-
className: "font-mono text-xs",
|
|
68
|
-
children: row[cellIndex] ?? ""
|
|
69
|
-
}, cellIndex))
|
|
70
|
-
}, rowIndex))
|
|
71
|
-
})
|
|
72
|
-
]
|
|
73
|
-
})
|
|
74
|
-
}),
|
|
75
|
-
notes.length === 0 ? null : /*#__PURE__*/ _jsxs("p", {
|
|
76
|
-
className: "text-xs text-muted-foreground",
|
|
77
|
-
children: [
|
|
78
|
-
"Showing ",
|
|
79
|
-
notes.join(" and "),
|
|
80
|
-
" — download for the full file."
|
|
81
|
-
]
|
|
82
|
-
})
|
|
83
|
-
]
|
|
84
|
-
});
|
|
42
|
+
return (_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("div", { className: "max-h-[32rem] overflow-auto rounded-md border border-border", children: _jsxs(Table, { "aria-label": caption, children: [_jsx(TableHeader, { children: _jsx(TableRow, { children: capped.headers.map((header, index) => (_jsx(TableHead, { scope: "col", children: header }, index))) }) }), _jsx(TableBody, { children: capped.rows.map((row, rowIndex) => (_jsx(TableRow, { children: capped.headers.map((_, cellIndex) => (_jsx(TableCell, { className: "font-mono text-xs", children: row[cellIndex] ?? "" }, cellIndex))) }, rowIndex))) })] }) }), notes.length === 0 ? null : (_jsxs("p", { className: "text-xs text-muted-foreground", children: ["Showing ", notes.join(" and "), " \u2014 download for the full file."] }))] }));
|
|
85
43
|
}
|
package/dist/ui/dialog.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export declare const DialogTrigger: React.ForwardRefExoticComponent<DialogPrimit
|
|
|
24
24
|
export declare const DialogClose: React.ForwardRefExoticComponent<DialogPrimitive.DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
|
|
25
25
|
export type DialogSide = "center" | "left" | "right";
|
|
26
26
|
export declare function DialogContent({ className, children, side, ...props }: React.ComponentProps<typeof DialogPrimitive.Content> & {
|
|
27
|
-
side?: DialogSide;
|
|
27
|
+
side?: DialogSide | undefined;
|
|
28
28
|
}): React.JSX.Element;
|
|
29
29
|
/** `pr-8` keeps the title clear of the close control in the corner. */
|
|
30
30
|
export declare function DialogHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
package/dist/ui/dialog.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 * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
3
4
|
import { XIcon } from "lucide-react";
|
|
@@ -20,86 +21,55 @@ import { cn } from "../lib/utils.js";
|
|
|
20
21
|
* inside `DialogBody` rather than growing past the viewport. `left` and
|
|
21
22
|
* `right` are full-height sheets; they also use `DialogBody` so the header and
|
|
22
23
|
* footer stay put while the middle scrolls.
|
|
23
|
-
*/
|
|
24
|
+
*/
|
|
25
|
+
export const Dialog = DialogPrimitive.Root;
|
|
24
26
|
export const DialogTrigger = DialogPrimitive.Trigger;
|
|
25
27
|
export const DialogClose = DialogPrimitive.Close;
|
|
26
28
|
const SIDE_CLASS = {
|
|
27
29
|
// Guttered width + capped height so the surface never kisses the viewport
|
|
28
30
|
// edge or spills past ~one form-screen of content. Overflow is clipped here;
|
|
29
31
|
// scroll lives on DialogBody.
|
|
30
|
-
center: "top-1/2 left-1/2 w-[min(calc(100vw-2rem),32rem)] max-h-[min(90dvh,42rem)] " +
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
center: "top-1/2 left-1/2 w-[min(calc(100vw-2rem),32rem)] max-h-[min(90dvh,42rem)] " +
|
|
33
|
+
"overflow-hidden -translate-x-1/2 -translate-y-1/2 rounded-lg border " +
|
|
34
|
+
"max-sm:w-[min(calc(100vw-1.25rem),32rem)] max-sm:max-h-[min(92dvh,42rem)] " +
|
|
35
|
+
"data-[state=open]:animate-[corbits-dialog-in_150ms_ease-out] data-[state=closed]:animate-[corbits-dialog-out_120ms_ease-in]",
|
|
36
|
+
right: "inset-y-0 right-0 w-full max-w-lg border-l " +
|
|
37
|
+
"data-[state=open]:animate-[corbits-drawer-in-right_200ms_ease-out] data-[state=closed]:animate-[corbits-drawer-out-right_160ms_ease-in]",
|
|
38
|
+
left: "inset-y-0 left-0 w-full max-w-lg border-r " +
|
|
39
|
+
"data-[state=open]:animate-[corbits-drawer-in-left_200ms_ease-out] data-[state=closed]:animate-[corbits-drawer-out-left_160ms_ease-in]",
|
|
33
40
|
};
|
|
34
41
|
export function DialogContent({ className, children, side = "center", ...props }) {
|
|
35
|
-
return
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}),
|
|
40
|
-
/*#__PURE__*/ _jsxs(DialogPrimitive.Content, {
|
|
41
|
-
"data-slot": "dialog-content",
|
|
42
|
-
"data-side": side,
|
|
43
|
-
className: cn("fixed z-50 flex flex-col gap-4 border-border bg-popover p-6 text-popover-foreground shadow-lg", // Keyframes are installed into your globals.css by this registry item.
|
|
44
|
-
SIDE_CLASS[side], className),
|
|
45
|
-
...props,
|
|
46
|
-
children: [
|
|
47
|
-
children,
|
|
48
|
-
/*#__PURE__*/ _jsx(DialogPrimitive.Close, {
|
|
49
|
-
"aria-label": "Close",
|
|
50
|
-
className: cn("absolute top-[0.85rem] right-[0.85rem] inline-flex size-[1.8rem] items-center justify-center", "rounded-[0.45rem] p-0 text-muted-foreground transition-colors", "hover:bg-foreground/5 hover:text-foreground", // Soft primary-tint focus instead of the theme outline — the close
|
|
42
|
+
return (_jsxs(DialogPrimitive.Portal, { children: [_jsx(DialogPrimitive.Overlay, { className: "fixed inset-0 z-50 bg-black/50 backdrop-blur-[2px] data-[state=open]:animate-[corbits-fade-in_150ms_ease-out] data-[state=closed]:animate-[corbits-fade-out_120ms_ease-in]" }), _jsxs(DialogPrimitive.Content, { "data-slot": "dialog-content", "data-side": side, className: cn("fixed z-50 flex flex-col gap-4 border-border bg-popover p-6 text-popover-foreground shadow-lg",
|
|
43
|
+
// Keyframes are installed into your globals.css by this registry item.
|
|
44
|
+
SIDE_CLASS[side], className), ...props, children: [children, _jsx(DialogPrimitive.Close, { "aria-label": "Close", className: cn("absolute top-[0.85rem] right-[0.85rem] inline-flex size-[1.8rem] items-center justify-center", "rounded-[0.45rem] p-0 text-muted-foreground transition-colors", "hover:bg-foreground/5 hover:text-foreground",
|
|
45
|
+
// Soft primary-tint focus instead of the theme outline — the close
|
|
51
46
|
// control sits on the popover surface and a hard ring reads heavy.
|
|
52
|
-
"focus-visible:text-foreground focus-visible:outline-none", "focus-visible:shadow-[0_0_0_3px_color-mix(in_srgb,var(--primary)_22%,transparent)]"),
|
|
53
|
-
children: /*#__PURE__*/ _jsx(XIcon, {
|
|
54
|
-
className: "size-4"
|
|
55
|
-
})
|
|
56
|
-
})
|
|
57
|
-
]
|
|
58
|
-
})
|
|
59
|
-
]
|
|
60
|
-
});
|
|
47
|
+
"focus-visible:text-foreground focus-visible:outline-none", "focus-visible:shadow-[0_0_0_3px_color-mix(in_srgb,var(--primary)_22%,transparent)]"), children: _jsx(XIcon, { className: "size-4" }) })] })] }));
|
|
61
48
|
}
|
|
62
|
-
/** `pr-8` keeps the title clear of the close control in the corner. */
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
className: cn("flex shrink-0 flex-col gap-1 pr-8", className),
|
|
66
|
-
...props
|
|
67
|
-
});
|
|
49
|
+
/** `pr-8` keeps the title clear of the close control in the corner. */
|
|
50
|
+
export function DialogHeader({ className, ...props }) {
|
|
51
|
+
return (_jsx("div", { "data-slot": "dialog-header", className: cn("flex shrink-0 flex-col gap-1 pr-8", className), ...props }));
|
|
68
52
|
}
|
|
69
|
-
/** Scrolls; the header and footer stay put. Needed by tall centre dialogs and side sheets. */
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
className: cn("min-h-0 flex-auto overflow-y-auto overscroll-contain [scrollbar-width:thin]", className),
|
|
73
|
-
...props
|
|
74
|
-
});
|
|
53
|
+
/** Scrolls; the header and footer stay put. Needed by tall centre dialogs and side sheets. */
|
|
54
|
+
export function DialogBody({ className, ...props }) {
|
|
55
|
+
return (_jsx("div", { "data-slot": "dialog-body", className: cn("min-h-0 flex-auto overflow-y-auto overscroll-contain [scrollbar-width:thin]", className), ...props }));
|
|
75
56
|
}
|
|
76
57
|
export function DialogFooter({ className, ...props }) {
|
|
77
|
-
return
|
|
78
|
-
|
|
79
|
-
className: cn(// Stable bar: pinned to the bottom of the flex column, subtle top rule
|
|
58
|
+
return (_jsx("div", { "data-slot": "dialog-footer", className: cn(
|
|
59
|
+
// Stable bar: pinned to the bottom of the flex column, subtle top rule
|
|
80
60
|
// and wash so actions read as chrome rather than more body content.
|
|
81
|
-
"mt-auto flex shrink-0 flex-wrap items-center justify-end gap-2", "border-t border-foreground/10 bg-foreground/[0.025] pt-[0.85rem]",
|
|
61
|
+
"mt-auto flex shrink-0 flex-wrap items-center justify-end gap-2", "border-t border-foreground/10 bg-foreground/[0.025] pt-[0.85rem]",
|
|
62
|
+
// Narrow viewports: stack full-width so primary/secondary hit areas
|
|
82
63
|
// don't compete for a single row of thumb space.
|
|
83
|
-
"max-sm:flex-col max-sm:flex-nowrap max-sm:items-stretch max-sm:[&>*]:w-full", className),
|
|
84
|
-
...props
|
|
85
|
-
});
|
|
64
|
+
"max-sm:flex-col max-sm:flex-nowrap max-sm:items-stretch max-sm:[&>*]:w-full", className), ...props }));
|
|
86
65
|
}
|
|
87
66
|
export function DialogTitle({ className, ...props }) {
|
|
88
|
-
return
|
|
89
|
-
className: cn("m-0 text-[0.95rem] font-[650] leading-[1.3] tracking-[-0.01em] text-foreground", className),
|
|
90
|
-
...props
|
|
91
|
-
});
|
|
67
|
+
return (_jsx(DialogPrimitive.Title, { className: cn("m-0 text-[0.95rem] font-[650] leading-[1.3] tracking-[-0.01em] text-foreground", className), ...props }));
|
|
92
68
|
}
|
|
93
69
|
export function DialogDescription({ className, ...props }) {
|
|
94
|
-
return
|
|
95
|
-
className: cn("m-0 text-[0.8125rem] leading-[1.4] text-muted-foreground", className),
|
|
96
|
-
...props
|
|
97
|
-
});
|
|
70
|
+
return (_jsx(DialogPrimitive.Description, { className: cn("m-0 text-[0.8125rem] leading-[1.4] text-muted-foreground", className), ...props }));
|
|
98
71
|
}
|
|
99
|
-
/** Uppercase field label used inside dialog forms. */
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
className: cn("text-[10.5px] font-bold uppercase tracking-[0.06em] text-muted-foreground", className),
|
|
103
|
-
...props
|
|
104
|
-
});
|
|
72
|
+
/** Uppercase field label used inside dialog forms. */
|
|
73
|
+
export function DialogFieldLabel({ className, ...props }) {
|
|
74
|
+
return (_jsx("label", { "data-slot": "dialog-field-label", className: cn("text-[10.5px] font-bold uppercase tracking-[0.06em] text-muted-foreground", className), ...props }));
|
|
105
75
|
}
|
|
@@ -6,33 +6,15 @@ import { cn } from "../lib/utils.js";
|
|
|
6
6
|
* with a waveform, a starting message, or a refusal — never more than one of
|
|
7
7
|
* these, and absent entirely once `state` is `"idle"` or `"unsupported"`, so
|
|
8
8
|
* the row does not otherwise change the composer's shape.
|
|
9
|
-
*/
|
|
10
|
-
|
|
9
|
+
*/
|
|
10
|
+
export function DictationStatusLine({ state, levels = [], startingLabel = "Starting microphone…", listeningLabel = "Listening:", errorMessage, className, }) {
|
|
11
|
+
if (state === "idle" || state === "unsupported")
|
|
12
|
+
return null;
|
|
11
13
|
if (state === "denied") {
|
|
12
|
-
return
|
|
13
|
-
role: "alert",
|
|
14
|
-
className: cn("text-xs text-destructive", className),
|
|
15
|
-
children: errorMessage ?? "Microphone access was blocked."
|
|
16
|
-
});
|
|
14
|
+
return (_jsx("p", { role: "alert", className: cn("text-xs text-destructive", className), children: errorMessage ?? "Microphone access was blocked." }));
|
|
17
15
|
}
|
|
18
16
|
if (state === "starting") {
|
|
19
|
-
return
|
|
20
|
-
"aria-live": "polite",
|
|
21
|
-
className: cn("text-xs text-muted-foreground", className),
|
|
22
|
-
children: startingLabel
|
|
23
|
-
});
|
|
17
|
+
return (_jsx("p", { "aria-live": "polite", className: cn("text-xs text-muted-foreground", className), children: startingLabel }));
|
|
24
18
|
}
|
|
25
|
-
return
|
|
26
|
-
"aria-live": "polite",
|
|
27
|
-
className: cn("flex items-center gap-2 text-xs text-muted-foreground", className),
|
|
28
|
-
children: [
|
|
29
|
-
/*#__PURE__*/ _jsx("span", {
|
|
30
|
-
children: listeningLabel
|
|
31
|
-
}),
|
|
32
|
-
/*#__PURE__*/ _jsx(VoiceWaveform, {
|
|
33
|
-
levels: levels,
|
|
34
|
-
className: "text-ok"
|
|
35
|
-
})
|
|
36
|
-
]
|
|
37
|
-
});
|
|
19
|
+
return (_jsxs("p", { "aria-live": "polite", className: cn("flex items-center gap-2 text-xs text-muted-foreground", className), children: [_jsx("span", { children: listeningLabel }), _jsx(VoiceWaveform, { levels: levels, className: "text-ok" })] }));
|
|
38
20
|
}
|
|
@@ -28,4 +28,4 @@ export type DitherCanvasProps = {
|
|
|
28
28
|
* that the grid is resampled by the compositor on a retina display and the
|
|
29
29
|
* crisp dot pattern — the entire effect — turns to mush.
|
|
30
30
|
*/
|
|
31
|
-
export declare function DitherCanvas({ cell, color, warpRadius, className }: DitherCanvasProps): import("react").JSX.Element;
|
|
31
|
+
export declare function DitherCanvas({ cell, color, warpRadius, className, }: DitherCanvasProps): import("react").JSX.Element;
|
package/dist/ui/dither-canvas.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
3
|
import { useEffect, useRef } from "react";
|
|
3
4
|
import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
|
|
@@ -10,32 +11,13 @@ import { cn } from "../lib/utils.js";
|
|
|
10
11
|
* recomputed cheaply every frame, and the pattern crawls when anything moves.
|
|
11
12
|
* An ordered matrix is a pure function of position, so a frame costs one pass
|
|
12
13
|
* and the texture stays locked to the surface instead of swimming.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
[
|
|
21
|
-
12,
|
|
22
|
-
4,
|
|
23
|
-
14,
|
|
24
|
-
6
|
|
25
|
-
],
|
|
26
|
-
[
|
|
27
|
-
3,
|
|
28
|
-
11,
|
|
29
|
-
1,
|
|
30
|
-
9
|
|
31
|
-
],
|
|
32
|
-
[
|
|
33
|
-
15,
|
|
34
|
-
7,
|
|
35
|
-
13,
|
|
36
|
-
5
|
|
37
|
-
]
|
|
38
|
-
].map((row)=>row.map((value)=>(value + 0.5) / 16));
|
|
14
|
+
*/
|
|
15
|
+
const BAYER = [
|
|
16
|
+
[0, 8, 2, 10],
|
|
17
|
+
[12, 4, 14, 6],
|
|
18
|
+
[3, 11, 1, 9],
|
|
19
|
+
[15, 7, 13, 5],
|
|
20
|
+
].map((row) => row.map((value) => (value + 0.5) / 16));
|
|
39
21
|
/**
|
|
40
22
|
* A dithered field that reacts to the pointer — decoration for a full-bleed
|
|
41
23
|
* panel, and nothing else.
|
|
@@ -56,14 +38,17 @@ import { cn } from "../lib/utils.js";
|
|
|
56
38
|
* The canvas is sized in device pixels and scaled by `devicePixelRatio`. Without
|
|
57
39
|
* that the grid is resampled by the compositor on a retina display and the
|
|
58
40
|
* crisp dot pattern — the entire effect — turns to mush.
|
|
59
|
-
*/
|
|
41
|
+
*/
|
|
42
|
+
export function DitherCanvas({ cell = 4, color, warpRadius = 160, className, }) {
|
|
60
43
|
const ref = useRef(null);
|
|
61
44
|
const reduce = usePrefersReducedMotion();
|
|
62
|
-
useEffect(()=>{
|
|
45
|
+
useEffect(() => {
|
|
63
46
|
const canvas = ref.current;
|
|
64
|
-
if (canvas === null)
|
|
47
|
+
if (canvas === null)
|
|
48
|
+
return;
|
|
65
49
|
const context = canvas.getContext("2d");
|
|
66
|
-
if (context === null)
|
|
50
|
+
if (context === null)
|
|
51
|
+
return;
|
|
67
52
|
// Resolved once per mount: reading a custom property costs a style
|
|
68
53
|
// recalculation, which is not something to do sixty times a second. The
|
|
69
54
|
// fallback reads the canvas's own computed `color` rather than a literal
|
|
@@ -73,14 +58,11 @@ import { cn } from "../lib/utils.js";
|
|
|
73
58
|
const computed = getComputedStyle(canvas);
|
|
74
59
|
const themeInk = computed.getPropertyValue("--primary").trim();
|
|
75
60
|
const ink = color ?? (themeInk === "" ? computed.color : themeInk);
|
|
76
|
-
const pointer = {
|
|
77
|
-
x: -1e6,
|
|
78
|
-
y: -1e6
|
|
79
|
-
};
|
|
61
|
+
const pointer = { x: -1e6, y: -1e6 };
|
|
80
62
|
let frame = 0;
|
|
81
63
|
let width = 0;
|
|
82
64
|
let height = 0;
|
|
83
|
-
const resize = ()=>{
|
|
65
|
+
const resize = () => {
|
|
84
66
|
const ratio = window.devicePixelRatio || 1;
|
|
85
67
|
const box = canvas.getBoundingClientRect();
|
|
86
68
|
width = box.width;
|
|
@@ -89,14 +71,14 @@ import { cn } from "../lib/utils.js";
|
|
|
89
71
|
canvas.height = Math.max(1, Math.round(height * ratio));
|
|
90
72
|
context.setTransform(ratio, 0, 0, ratio, 0, 0);
|
|
91
73
|
};
|
|
92
|
-
const draw = (time)=>{
|
|
74
|
+
const draw = (time) => {
|
|
93
75
|
context.clearRect(0, 0, width, height);
|
|
94
76
|
context.fillStyle = ink;
|
|
95
77
|
const drift = reduce ? 0 : time / 3000;
|
|
96
78
|
const columns = Math.ceil(width / cell);
|
|
97
79
|
const rows = Math.ceil(height / cell);
|
|
98
|
-
for(let row = 0; row < rows; row += 1){
|
|
99
|
-
for(let column = 0; column < columns; column += 1){
|
|
80
|
+
for (let row = 0; row < rows; row += 1) {
|
|
81
|
+
for (let column = 0; column < columns; column += 1) {
|
|
100
82
|
const x = column * cell;
|
|
101
83
|
const y = row * cell;
|
|
102
84
|
// Base field: a soft diagonal gradient with a slow sine drift, so the
|
|
@@ -123,47 +105,40 @@ import { cn } from "../lib/utils.js";
|
|
|
123
105
|
}
|
|
124
106
|
}
|
|
125
107
|
};
|
|
126
|
-
const loop = (time)=>{
|
|
108
|
+
const loop = (time) => {
|
|
127
109
|
draw(time);
|
|
128
110
|
frame = requestAnimationFrame(loop);
|
|
129
111
|
};
|
|
130
|
-
const onPointerMove = (event)=>{
|
|
112
|
+
const onPointerMove = (event) => {
|
|
131
113
|
const box = canvas.getBoundingClientRect();
|
|
132
114
|
pointer.x = event.clientX - box.left;
|
|
133
115
|
pointer.y = event.clientY - box.top;
|
|
134
116
|
};
|
|
135
|
-
const onPointerLeave = ()=>{
|
|
117
|
+
const onPointerLeave = () => {
|
|
136
118
|
pointer.x = -1e6;
|
|
137
119
|
pointer.y = -1e6;
|
|
138
120
|
};
|
|
139
121
|
resize();
|
|
140
|
-
const observer = new ResizeObserver(()=>{
|
|
122
|
+
const observer = new ResizeObserver(() => {
|
|
141
123
|
resize();
|
|
142
|
-
if (reduce)
|
|
124
|
+
if (reduce)
|
|
125
|
+
draw(0);
|
|
143
126
|
});
|
|
144
127
|
observer.observe(canvas);
|
|
145
128
|
if (reduce) {
|
|
146
129
|
draw(0);
|
|
147
|
-
}
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
148
132
|
frame = requestAnimationFrame(loop);
|
|
149
133
|
canvas.addEventListener("pointermove", onPointerMove);
|
|
150
134
|
canvas.addEventListener("pointerleave", onPointerLeave);
|
|
151
135
|
}
|
|
152
|
-
return ()=>{
|
|
136
|
+
return () => {
|
|
153
137
|
cancelAnimationFrame(frame);
|
|
154
138
|
observer.disconnect();
|
|
155
139
|
canvas.removeEventListener("pointermove", onPointerMove);
|
|
156
140
|
canvas.removeEventListener("pointerleave", onPointerLeave);
|
|
157
141
|
};
|
|
158
|
-
}, [
|
|
159
|
-
|
|
160
|
-
color,
|
|
161
|
-
warpRadius,
|
|
162
|
-
reduce
|
|
163
|
-
]);
|
|
164
|
-
return /*#__PURE__*/ _jsx("canvas", {
|
|
165
|
-
ref: ref,
|
|
166
|
-
"aria-hidden": true,
|
|
167
|
-
className: cn("block size-full", className)
|
|
168
|
-
});
|
|
142
|
+
}, [cell, color, warpRadius, reduce]);
|
|
143
|
+
return (_jsx("canvas", { ref: ref, "aria-hidden": true, className: cn("block size-full", className) }));
|
|
169
144
|
}
|
package/dist/ui/embed-body.d.ts
CHANGED
|
@@ -27,4 +27,4 @@ export type EmbedBodyProps = {
|
|
|
27
27
|
* the direct link is always present rather than being a fallback we would have
|
|
28
28
|
* to detect our way into.
|
|
29
29
|
*/
|
|
30
|
-
export declare function EmbedBody({ url, title, description, downloadUrl, aspect, className }: EmbedBodyProps): import("react").JSX.Element;
|
|
30
|
+
export declare function EmbedBody({ url, title, description, downloadUrl, aspect, className, }: EmbedBodyProps): import("react").JSX.Element;
|
package/dist/ui/embed-body.js
CHANGED
|
@@ -17,10 +17,9 @@ import { buttonVariants } from "./button.js";
|
|
|
17
17
|
* `allow-top-navigation` (redirect the tab out from under them),
|
|
18
18
|
* `allow-popups` (open a tab that outlives the frame), and `allow-forms` (POST
|
|
19
19
|
* credentials somewhere). A viewer needs none of the three.
|
|
20
|
-
*/
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
];
|
|
20
|
+
*/
|
|
21
|
+
const EMBED_SANDBOX = "allow-scripts allow-same-origin allow-presentation";
|
|
22
|
+
const EMBED_ALLOWED_PROTOCOLS = ["https:"];
|
|
24
23
|
/**
|
|
25
24
|
* A third-party URL, framed.
|
|
26
25
|
*
|
|
@@ -34,59 +33,11 @@ const EMBED_ALLOWED_PROTOCOLS = [
|
|
|
34
33
|
* login wall, and an iframe that renders blank fires no error we can catch — so
|
|
35
34
|
* the direct link is always present rather than being a fallback we would have
|
|
36
35
|
* to detect our way into.
|
|
37
|
-
*/
|
|
36
|
+
*/
|
|
37
|
+
export function EmbedBody({ url, title, description, downloadUrl, aspect = "wide", className, }) {
|
|
38
38
|
if (!isSafeUrl(url, EMBED_ALLOWED_PROTOCOLS)) {
|
|
39
|
-
return
|
|
40
|
-
message: "This link is missing or is not a secure (https) address, so it cannot be shown."
|
|
41
|
-
});
|
|
39
|
+
return (_jsx(ArtifactNotice, { message: "This link is missing or is not a secure (https) address, so it cannot be shown." }));
|
|
42
40
|
}
|
|
43
41
|
const safeDownloadUrl = toSafeHref(downloadUrl);
|
|
44
|
-
return
|
|
45
|
-
className: cn("flex w-full flex-col gap-3", className),
|
|
46
|
-
children: [
|
|
47
|
-
description === undefined ? null : /*#__PURE__*/ _jsx("p", {
|
|
48
|
-
className: "max-w-prose text-sm text-muted-foreground",
|
|
49
|
-
children: description
|
|
50
|
-
}),
|
|
51
|
-
/*#__PURE__*/ _jsx("div", {
|
|
52
|
-
className: cn("w-full overflow-hidden rounded-lg border border-border bg-card", aspect === "wide" ? "aspect-video" : "aspect-[3/4] max-h-[75vh]"),
|
|
53
|
-
children: /*#__PURE__*/ _jsx("iframe", {
|
|
54
|
-
src: url,
|
|
55
|
-
title: title,
|
|
56
|
-
sandbox: EMBED_SANDBOX,
|
|
57
|
-
allow: "fullscreen",
|
|
58
|
-
className: "size-full border-0"
|
|
59
|
-
})
|
|
60
|
-
}),
|
|
61
|
-
/*#__PURE__*/ _jsxs("div", {
|
|
62
|
-
className: "flex items-center gap-2",
|
|
63
|
-
children: [
|
|
64
|
-
/*#__PURE__*/ _jsxs("a", {
|
|
65
|
-
href: url,
|
|
66
|
-
target: "_blank",
|
|
67
|
-
rel: "noopener noreferrer",
|
|
68
|
-
className: buttonVariants({
|
|
69
|
-
variant: "outline",
|
|
70
|
-
size: "sm"
|
|
71
|
-
}),
|
|
72
|
-
children: [
|
|
73
|
-
/*#__PURE__*/ _jsx(ExternalLink, {
|
|
74
|
-
"aria-hidden": true
|
|
75
|
-
}),
|
|
76
|
-
"Open in a new tab"
|
|
77
|
-
]
|
|
78
|
-
}),
|
|
79
|
-
safeDownloadUrl === undefined ? null : /*#__PURE__*/ _jsx("a", {
|
|
80
|
-
href: safeDownloadUrl,
|
|
81
|
-
download: true,
|
|
82
|
-
className: buttonVariants({
|
|
83
|
-
variant: "ghost",
|
|
84
|
-
size: "sm"
|
|
85
|
-
}),
|
|
86
|
-
children: "Download"
|
|
87
|
-
})
|
|
88
|
-
]
|
|
89
|
-
})
|
|
90
|
-
]
|
|
91
|
-
});
|
|
42
|
+
return (_jsxs("div", { className: cn("flex w-full flex-col gap-3", className), children: [description === undefined ? null : (_jsx("p", { className: "max-w-prose text-sm text-muted-foreground", children: description })), _jsx("div", { className: cn("w-full overflow-hidden rounded-lg border border-border bg-card", aspect === "wide" ? "aspect-video" : "aspect-[3/4] max-h-[75vh]"), children: _jsx("iframe", { src: url, title: title, sandbox: EMBED_SANDBOX, allow: "fullscreen", className: "size-full border-0" }) }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("a", { href: url, target: "_blank", rel: "noopener noreferrer", className: buttonVariants({ variant: "outline", size: "sm" }), children: [_jsx(ExternalLink, { "aria-hidden": true }), "Open in a new tab"] }), safeDownloadUrl === undefined ? null : (_jsx("a", { href: safeDownloadUrl, download: true, className: buttonVariants({ variant: "ghost", size: "sm" }), children: "Download" }))] })] }));
|
|
92
43
|
}
|
package/dist/ui/empty-state.d.ts
CHANGED
|
@@ -23,4 +23,4 @@ export type EmptyStateProps = {
|
|
|
23
23
|
* Not a `role="status"`. An empty state is the rendered result of a finished
|
|
24
24
|
* load, not an announcement — the surface that was loading owns that.
|
|
25
25
|
*/
|
|
26
|
-
export declare function EmptyState({ title, description, icon, action, className }: EmptyStateProps): import("react").JSX.Element;
|
|
26
|
+
export declare function EmptyState({ title, description, icon, action, className, }: EmptyStateProps): import("react").JSX.Element;
|
package/dist/ui/empty-state.js
CHANGED
|
@@ -13,30 +13,7 @@ import { cn } from "../lib/utils.js";
|
|
|
13
13
|
*
|
|
14
14
|
* Not a `role="status"`. An empty state is the rendered result of a finished
|
|
15
15
|
* load, not an announcement — the surface that was loading owns that.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
className: cn("flex flex-col items-center gap-3 px-6 py-12 text-center", className),
|
|
20
|
-
children: [
|
|
21
|
-
icon === undefined ? null : /*#__PURE__*/ _jsx("span", {
|
|
22
|
-
"aria-hidden": true,
|
|
23
|
-
className: "grid size-11 place-items-center rounded-full bg-muted text-muted-foreground [&_svg]:size-5",
|
|
24
|
-
children: icon
|
|
25
|
-
}),
|
|
26
|
-
/*#__PURE__*/ _jsxs("div", {
|
|
27
|
-
className: "flex flex-col gap-1",
|
|
28
|
-
children: [
|
|
29
|
-
/*#__PURE__*/ _jsx("p", {
|
|
30
|
-
className: "text-sm font-medium",
|
|
31
|
-
children: title
|
|
32
|
-
}),
|
|
33
|
-
description === undefined ? null : /*#__PURE__*/ _jsx("p", {
|
|
34
|
-
className: "max-w-prose text-xs leading-relaxed text-muted-foreground",
|
|
35
|
-
children: description
|
|
36
|
-
})
|
|
37
|
-
]
|
|
38
|
-
}),
|
|
39
|
-
action
|
|
40
|
-
]
|
|
41
|
-
});
|
|
16
|
+
*/
|
|
17
|
+
export function EmptyState({ title, description, icon, action, className, }) {
|
|
18
|
+
return (_jsxs("div", { "data-slot": "empty-state", className: cn("flex flex-col items-center gap-3 px-6 py-12 text-center", className), children: [icon === undefined ? null : (_jsx("span", { "aria-hidden": true, className: "grid size-11 place-items-center rounded-full bg-muted text-muted-foreground [&_svg]:size-5", children: icon })), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("p", { className: "text-sm font-medium", children: title }), description === undefined ? null : (_jsx("p", { className: "max-w-prose text-xs leading-relaxed text-muted-foreground", children: description }))] }), action] }));
|
|
42
19
|
}
|