@tangle-network/ui 11.12.0 → 11.13.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/CHANGELOG.md +17 -0
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/auth/auth.d.ts +53 -0
- package/dist/{auth-DOETfnd9.js → auth/auth.js} +7 -37
- package/dist/auth/login-layout.d.ts +20 -0
- package/dist/auth/login-layout.js +36 -0
- package/dist/auth.d.ts +2 -1
- package/dist/auth.js +2 -1
- package/dist/chat/agent-timeline.d.ts +83 -0
- package/dist/chat/agent-timeline.js +236 -0
- package/dist/chat/chat-container.d.ts +51 -0
- package/dist/chat/chat-container.js +309 -0
- package/dist/chat/chat-message.d.ts +22 -0
- package/dist/chat/chat-message.js +38 -0
- package/dist/chat/message-list.d.ts +32 -0
- package/dist/chat/message-list.js +37 -0
- package/dist/chat/thinking-indicator.d.ts +6 -0
- package/dist/chat/thinking-indicator.js +38 -0
- package/dist/chat/user-message.d.ts +21 -0
- package/dist/chat/user-message.js +42 -0
- package/dist/chat.d.ts +6 -1
- package/dist/chat.js +6 -1
- package/dist/editor/document-editor-pane.d.ts +37 -0
- package/dist/editor/document-editor-pane.js +199 -0
- package/dist/editor/editor-lazy.js +37 -0
- package/dist/editor/editor-loading.js +21 -0
- package/dist/editor/editor-peers.d.ts +6 -0
- package/dist/editor/editor-peers.js +155 -0
- package/dist/editor/editor-provider.d.ts +97 -0
- package/dist/editor/editor-provider.js +253 -0
- package/dist/editor/editor-toolbar.d.ts +11 -0
- package/dist/editor/editor-toolbar.js +106 -0
- package/dist/editor/markdown-conversion.js +23 -0
- package/dist/editor/markdown-document-editor.js +103 -0
- package/dist/editor/tiptap-editor.d.ts +45 -0
- package/dist/editor/tiptap-editor.js +271 -0
- package/dist/editor/use-editor.d.ts +67 -0
- package/dist/editor/use-editor.js +158 -0
- package/dist/editor.d.ts +6 -119
- package/dist/editor.js +5 -1
- package/dist/files/file-artifact-pane.d.ts +47 -0
- package/dist/files/file-artifact-pane.js +114 -0
- package/dist/files/file-format.d.ts +51 -0
- package/dist/{file-format-BgXbr-Ib.js → files/file-format.js} +1 -1
- package/dist/files/file-preview.d.ts +27 -0
- package/dist/files/file-preview.js +359 -0
- package/dist/files/file-tabs.d.ts +19 -0
- package/dist/files/file-tabs.js +48 -0
- package/dist/files/file-tree.d.ts +31 -0
- package/dist/files/file-tree.js +135 -0
- package/dist/files/rich-file-tree.d.ts +62 -0
- package/dist/files/rich-file-tree.js +122 -0
- package/dist/files.d.ts +6 -1
- package/dist/files.js +6 -2
- package/dist/hooks/use-auth.d.ts +40 -0
- package/dist/hooks/use-auth.js +91 -0
- package/dist/hooks/use-auto-scroll.d.ts +11 -0
- package/dist/hooks/use-auto-scroll.js +48 -0
- package/dist/hooks/use-dropdown-menu.d.ts +12 -0
- package/dist/hooks/use-dropdown-menu.js +31 -0
- package/dist/hooks/use-live-time.d.ts +7 -0
- package/dist/hooks/use-live-time.js +22 -0
- package/dist/hooks/use-realtime-session.d.ts +32 -0
- package/dist/hooks/use-realtime-session.js +235 -0
- package/dist/hooks/use-run-collapse-state.d.ts +13 -0
- package/dist/hooks/use-run-collapse-state.js +24 -0
- package/dist/hooks/use-run-groups.d.ts +11 -0
- package/dist/hooks/use-run-groups.js +85 -0
- package/dist/hooks/use-sdk-session.d.ts +59 -0
- package/dist/hooks/use-sdk-session.js +322 -0
- package/dist/hooks/use-sse-stream.d.ts +124 -0
- package/dist/hooks/use-sse-stream.js +229 -0
- package/dist/hooks/use-tool-call-stream.d.ts +23 -0
- package/dist/hooks/use-tool-call-stream.js +75 -0
- package/dist/hooks.d.ts +11 -49
- package/dist/hooks.js +10 -110
- package/dist/index.d.ts +99 -25
- package/dist/index.js +86 -36
- package/dist/lib/focus.d.ts +55 -0
- package/dist/{focus-BcE_SHqz.js → lib/focus.js} +1 -1
- package/dist/lib/utils.d.ts +4 -0
- package/dist/{utils-C_uf36nf.js → lib/utils.js} +1 -1
- package/dist/{code-block-B9miUPht.d.ts → markdown/code-block.d.ts} +5 -6
- package/dist/{code-block-B36KVUSN.js → markdown/code-block.js} +22 -47
- package/dist/{markdown-C0atSabr.d.ts → markdown/markdown.d.ts} +4 -5
- package/dist/{markdown-Db08KAYF.js → markdown/markdown.js} +3 -3
- package/dist/markdown.d.ts +2 -2
- package/dist/markdown.js +2 -2
- package/dist/{openui-artifact-renderer-fkBQaoLO.d.ts → openui/openui-artifact-renderer.d.ts} +20 -21
- package/dist/{openui-artifact-renderer-DG_i2lOR.js → openui/openui-artifact-renderer.js} +9 -7
- package/dist/{schema-BpW9rSSG.js → openui/schema-compiled.js} +2 -354
- package/dist/{schema-DAstk-J4.d.ts → openui/schema-data.d.ts} +3 -24
- package/dist/openui/schema-data.js +206 -0
- package/dist/openui-schema.d.ts +22 -3
- package/dist/openui-schema.js +138 -1
- package/dist/openui.d.ts +3 -2
- package/dist/openui.js +3 -2
- package/dist/{artifact-pane-BL_DFWNl.d.ts → primitives/artifact-pane.d.ts} +3 -4
- package/dist/{artifact-pane-DMXT9a8U.js → primitives/artifact-pane.js} +2 -2
- package/dist/primitives/avatar.d.ts +8 -0
- package/dist/primitives/avatar.js +25 -0
- package/dist/primitives/badge.d.ts +22 -0
- package/dist/primitives/badge.js +47 -0
- package/dist/{button-yoIv77e2.d.ts → primitives/button.d.ts} +2 -2
- package/dist/primitives/button.js +113 -0
- package/dist/primitives/card.d.ts +18 -0
- package/dist/primitives/card.js +52 -0
- package/dist/primitives/code-block.d.ts +6 -0
- package/dist/primitives/code-block.js +13 -0
- package/dist/primitives/dialog.d.ts +23 -0
- package/dist/primitives/dialog.js +59 -0
- package/dist/primitives/drop-zone.d.ts +23 -0
- package/dist/primitives/drop-zone.js +104 -0
- package/dist/primitives/dropdown-menu.d.ts +29 -0
- package/dist/{dropdown-menu-BpcLa5vF.js → primitives/dropdown-menu.js} +2 -23
- package/dist/primitives/empty-state.d.ts +11 -0
- package/dist/primitives/empty-state.js +32 -0
- package/dist/primitives/heading.d.ts +23 -0
- package/dist/primitives/heading.js +38 -0
- package/dist/primitives/input.d.ts +23 -0
- package/dist/primitives/input.js +110 -0
- package/dist/primitives/label.d.ts +6 -0
- package/dist/primitives/label.js +16 -0
- package/dist/primitives/metric-strip.d.ts +48 -0
- package/dist/primitives/metric-strip.js +52 -0
- package/dist/primitives/page-header.d.ts +25 -0
- package/dist/primitives/page-header.js +47 -0
- package/dist/primitives/page-shell.d.ts +14 -0
- package/dist/primitives/page-shell.js +17 -0
- package/dist/primitives/progress.d.ts +9 -0
- package/dist/primitives/progress.js +29 -0
- package/dist/primitives/segmented-control.d.ts +40 -0
- package/dist/primitives/segmented-control.js +57 -0
- package/dist/primitives/select.d.ts +15 -0
- package/dist/primitives/select.js +74 -0
- package/dist/primitives/sidebar-drop-zone.d.ts +21 -0
- package/dist/primitives/sidebar-drop-zone.js +88 -0
- package/dist/primitives/skeleton.d.ts +10 -0
- package/dist/primitives/skeleton.js +50 -0
- package/dist/primitives/stat-card.d.ts +16 -0
- package/dist/primitives/stat-card.js +60 -0
- package/dist/primitives/status-pill.d.ts +44 -0
- package/dist/primitives/status-pill.js +119 -0
- package/dist/primitives/switch.d.ts +6 -0
- package/dist/primitives/switch.js +16 -0
- package/dist/primitives/table.d.ts +22 -0
- package/dist/primitives/table.js +63 -0
- package/dist/primitives/tabs.d.ts +13 -0
- package/dist/{tabs-BVHR6NkO.js → primitives/tabs.js} +3 -3
- package/dist/primitives/terminal-display.d.ts +25 -0
- package/dist/primitives/terminal-display.js +109 -0
- package/dist/primitives/text-shimmer.d.ts +16 -0
- package/dist/{text-shimmer-BUUo6I-g.js → primitives/text-shimmer.js} +2 -2
- package/dist/primitives/theme-toggle.d.ts +11 -0
- package/dist/primitives/theme-toggle.js +154 -0
- package/dist/primitives/toast.d.ts +29 -0
- package/dist/primitives/toast.js +142 -0
- package/dist/primitives/toolbar.d.ts +55 -0
- package/dist/primitives/toolbar.js +37 -0
- package/dist/primitives/upload-progress.d.ts +23 -0
- package/dist/primitives/upload-progress.js +72 -0
- package/dist/primitives.d.ts +35 -5
- package/dist/primitives.js +35 -9
- package/dist/{index-COgqsFAQ.d.ts → redaction/redacted-document.d.ts} +6 -7
- package/dist/{redaction-CGGB2ENG.js → redaction/redacted-document.js} +2 -2
- package/dist/redaction.d.ts +1 -1
- package/dist/redaction.js +1 -1
- package/dist/run/expandable-content.js +41 -0
- package/dist/run/expanded-tool-detail.d.ts +12 -0
- package/dist/run/expanded-tool-detail.js +163 -0
- package/dist/run/inline-thinking-item.d.ts +11 -0
- package/dist/run/inline-thinking-item.js +60 -0
- package/dist/run/inline-tool-item.d.ts +25 -0
- package/dist/run/inline-tool-item.js +63 -0
- package/dist/run/run-group.d.ts +26 -0
- package/dist/{run-group-BWGeesgs.js → run/run-group.js} +9 -60
- package/dist/run/run-item-primitives.d.ts +5 -0
- package/dist/{run-ZsIKPA6J.js → run/run-item-primitives.js} +2 -2
- package/dist/run/run-row-shell.d.ts +53 -0
- package/dist/run/run-row-shell.js +114 -0
- package/dist/{tool-call-feed-BeB1_4pX.d.ts → run/tool-call-feed.d.ts} +7 -12
- package/dist/{tool-call-feed-BpmMLpPX.js → run/tool-call-feed.js} +4 -4
- package/dist/run/tool-call-step.d.ts +5 -0
- package/dist/run/tool-call-step.js +82 -0
- package/dist/run.d.ts +8 -2
- package/dist/run.js +7 -4
- package/dist/sdk-hooks.d.ts +8 -1
- package/dist/sdk-hooks.js +8 -2
- package/dist/stores/active-sessions-store.d.ts +83 -0
- package/dist/{active-sessions-store-Gt1R0rFG.js → stores/active-sessions-store.js} +1 -1
- package/dist/stores/chat-store.d.ts +14 -0
- package/dist/stores/chat-store.js +33 -0
- package/dist/stores.d.ts +3 -16
- package/dist/stores.js +2 -33
- package/dist/tool-previews/command-preview.d.ts +11 -0
- package/dist/tool-previews/command-preview.js +91 -0
- package/dist/tool-previews/diff-preview.d.ts +7 -0
- package/dist/tool-previews/diff-preview.js +76 -0
- package/dist/tool-previews/glob-results-preview.d.ts +7 -0
- package/dist/tool-previews/glob-results-preview.js +53 -0
- package/dist/tool-previews/grep-results-preview.d.ts +7 -0
- package/dist/tool-previews/grep-results-preview.js +99 -0
- package/dist/tool-previews/preview-primitives.js +58 -0
- package/dist/tool-previews/question-preview.d.ts +7 -0
- package/dist/tool-previews/question-preview.js +63 -0
- package/dist/tool-previews/web-search-preview.d.ts +7 -0
- package/dist/tool-previews/web-search-preview.js +78 -0
- package/dist/tool-previews/write-file-preview.d.ts +11 -0
- package/dist/tool-previews/write-file-preview.js +52 -0
- package/dist/tool-previews.d.ts +7 -1
- package/dist/tool-previews.js +7 -1
- package/dist/{branding-26d5ARIr.d.ts → types/branding.d.ts} +2 -3
- package/dist/{message-vhUI0c5G.d.ts → types/message.d.ts} +2 -3
- package/dist/{parts-5mhy9yJ3.d.ts → types/parts.d.ts} +8 -9
- package/dist/{run-OyWmIDqu.d.ts → types/run.d.ts} +9 -10
- package/dist/{tool-display-DgmL5rIU.d.ts → types/tool-display.d.ts} +5 -6
- package/dist/types.d.ts +5 -5
- package/dist/utils/copy-text.d.ts +7 -0
- package/dist/{utils-Bl_CZ0Qp.js → utils/copy-text.js} +1 -11
- package/dist/utils/format.d.ts +22 -0
- package/dist/{format-DfcLWqMa.js → utils/format.js} +1 -1
- package/dist/utils/time-ago.d.ts +3 -0
- package/dist/utils/time-ago.js +11 -0
- package/dist/utils/tool-display.d.ts +16 -0
- package/dist/{tool-display-BAuAVa43.js → utils/tool-display.js} +1 -1
- package/dist/utils.d.ts +6 -1
- package/dist/utils.js +6 -5
- package/package.json +2 -2
- package/src/files/rich-file-tree.stories.tsx +1 -1
- package/src/files/rich-file-tree.tsx +12 -9
- package/src/markdown/code-block.test.tsx +46 -2
- package/src/markdown/code-block.tsx +23 -60
- package/src/primitives/button.stories.tsx +37 -1
- package/src/primitives/button.test.tsx +230 -0
- package/src/primitives/button.tsx +62 -14
- package/src/primitives/card-anatomy.stories.tsx +51 -0
- package/src/primitives/card.test.tsx +71 -0
- package/src/primitives/card.tsx +25 -13
- package/src/primitives/heading.stories.tsx +35 -0
- package/src/primitives/heading.test.tsx +56 -0
- package/src/primitives/heading.tsx +76 -0
- package/src/primitives/index.ts +8 -0
- package/src/primitives/input.stories.tsx +28 -0
- package/src/primitives/input.test.tsx +161 -0
- package/src/primitives/input.tsx +34 -28
- package/src/primitives/page-header.stories.tsx +51 -0
- package/src/primitives/page-header.test.tsx +48 -0
- package/src/primitives/page-header.tsx +35 -35
- package/src/primitives/page-shell.stories.tsx +89 -0
- package/src/primitives/page-shell.test.tsx +24 -0
- package/src/primitives/page-shell.tsx +26 -0
- package/src/primitives/table-wrapper.stories.tsx +54 -0
- package/src/primitives/table.test.tsx +72 -0
- package/src/primitives/table.tsx +33 -12
- package/src/primitives/theme-toggle.test.tsx +167 -0
- package/src/primitives/theme-toggle.tsx +111 -39
- package/dist/active-sessions-store-nl70ZnMC.d.ts +0 -84
- package/dist/button-C87nEe2R.js +0 -78
- package/dist/chat-DDvF2oGQ.js +0 -672
- package/dist/diff-preview-BcK3nRXb.js +0 -533
- package/dist/document-editor-pane-BilJfiCo.d.ts +0 -136
- package/dist/document-editor-pane-POsq5Q0o.js +0 -1279
- package/dist/files-hywocVZz.js +0 -753
- package/dist/index-2UntyjBb.d.ts +0 -52
- package/dist/index-BgUHilZm.d.ts +0 -108
- package/dist/index-CJ8wRfiC.d.ts +0 -236
- package/dist/index-CPDET_s1.d.ts +0 -549
- package/dist/index-Cg6gYAqh.d.ts +0 -73
- package/dist/index-Cs7j8V7l.d.ts +0 -203
- package/dist/index-DjKxO357.d.ts +0 -128
- package/dist/primitives-Bx59fT-U.js +0 -1239
- package/dist/table-Bss73DhB.js +0 -146
- package/dist/tool-call-step-DNebqhmX.js +0 -434
- package/dist/use-auto-scroll-C5Pjeqon.js +0 -153
- package/dist/use-sse-stream-DjqRuDft.js +0 -884
- package/dist/use-sse-stream-Dm6R5YWz.d.ts +0 -282
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { cn } from "../lib/utils.js";
|
|
2
|
+
import { useCallback, useRef, useState } from "react";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
//#region src/primitives/drop-zone.tsx
|
|
5
|
+
/**
|
|
6
|
+
* DropZone — full-window drag-and-drop file upload overlay.
|
|
7
|
+
*
|
|
8
|
+
* Detects when files are dragged over the browser window and shows a
|
|
9
|
+
* customizable overlay. Products provide the onDrop handler and optional
|
|
10
|
+
* custom overlay content.
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* <DropZone onDrop={files => uploadToR2(files)} accept=".pdf,.csv">
|
|
14
|
+
* <YourApp />
|
|
15
|
+
* </DropZone>
|
|
16
|
+
*/
|
|
17
|
+
function DropZone({ onDrop, accept, disabled, overlay, title = "Drop files to upload", description = "Your files will be securely stored in the workspace.", icon = "cloud_upload", children, className }) {
|
|
18
|
+
const [dragOver, setDragOver] = useState(false);
|
|
19
|
+
const counter = useRef(0);
|
|
20
|
+
const isAccepted = useCallback((file) => {
|
|
21
|
+
if (!accept) return true;
|
|
22
|
+
const extensions = accept.split(",").map((ext) => ext.trim().toLowerCase());
|
|
23
|
+
const fileName = file.name.toLowerCase();
|
|
24
|
+
return extensions.some((ext) => fileName.endsWith(ext));
|
|
25
|
+
}, [accept]);
|
|
26
|
+
const handleDragEnter = useCallback((e) => {
|
|
27
|
+
e.preventDefault();
|
|
28
|
+
if (disabled) return;
|
|
29
|
+
counter.current++;
|
|
30
|
+
if (e.dataTransfer?.types.includes("Files")) setDragOver(true);
|
|
31
|
+
}, [disabled]);
|
|
32
|
+
const handleDragLeave = useCallback((e) => {
|
|
33
|
+
e.preventDefault();
|
|
34
|
+
counter.current--;
|
|
35
|
+
if (counter.current === 0) setDragOver(false);
|
|
36
|
+
}, []);
|
|
37
|
+
const handleDragOver = useCallback((e) => {
|
|
38
|
+
e.preventDefault();
|
|
39
|
+
if (!disabled) e.dataTransfer.dropEffect = "copy";
|
|
40
|
+
}, [disabled]);
|
|
41
|
+
const handleDrop = useCallback((e) => {
|
|
42
|
+
e.preventDefault();
|
|
43
|
+
counter.current = 0;
|
|
44
|
+
setDragOver(false);
|
|
45
|
+
if (disabled) return;
|
|
46
|
+
const allFiles = Array.from(e.dataTransfer?.files || []);
|
|
47
|
+
const accepted = accept ? allFiles.filter(isAccepted) : allFiles;
|
|
48
|
+
if (accepted.length > 0) onDrop(accepted);
|
|
49
|
+
}, [
|
|
50
|
+
disabled,
|
|
51
|
+
accept,
|
|
52
|
+
isAccepted,
|
|
53
|
+
onDrop
|
|
54
|
+
]);
|
|
55
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
56
|
+
onDragEnter: handleDragEnter,
|
|
57
|
+
onDragLeave: handleDragLeave,
|
|
58
|
+
onDragOver: handleDragOver,
|
|
59
|
+
onDrop: handleDrop,
|
|
60
|
+
className: cn("relative", className),
|
|
61
|
+
children: [dragOver && (overlay || /* @__PURE__ */ jsx("div", {
|
|
62
|
+
className: "fixed inset-0 z-[100] flex items-center justify-center pointer-events-none bg-background",
|
|
63
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
64
|
+
className: "rounded-2xl border-2 border-dashed border-border bg-card p-16 text-center shadow-[var(--shadow-dropdown)] max-w-lg mx-auto",
|
|
65
|
+
children: [
|
|
66
|
+
/* @__PURE__ */ jsx("div", {
|
|
67
|
+
className: "mx-auto mb-6 flex h-20 w-20 items-center justify-center rounded-2xl border border-border bg-[var(--accent-surface-soft)]",
|
|
68
|
+
children: typeof icon === "string" ? /* @__PURE__ */ jsxs("svg", {
|
|
69
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
70
|
+
viewBox: "0 0 24 24",
|
|
71
|
+
fill: "none",
|
|
72
|
+
stroke: "currentColor",
|
|
73
|
+
strokeWidth: "1.5",
|
|
74
|
+
strokeLinecap: "round",
|
|
75
|
+
strokeLinejoin: "round",
|
|
76
|
+
className: "h-10 w-10 text-[var(--accent-text)]",
|
|
77
|
+
children: [
|
|
78
|
+
/* @__PURE__ */ jsx("title", { children: "Upload" }),
|
|
79
|
+
/* @__PURE__ */ jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
80
|
+
/* @__PURE__ */ jsx("polyline", { points: "17 8 12 3 7 8" }),
|
|
81
|
+
/* @__PURE__ */ jsx("line", {
|
|
82
|
+
x1: "12",
|
|
83
|
+
x2: "12",
|
|
84
|
+
y1: "3",
|
|
85
|
+
y2: "15"
|
|
86
|
+
})
|
|
87
|
+
]
|
|
88
|
+
}) : icon
|
|
89
|
+
}),
|
|
90
|
+
/* @__PURE__ */ jsx("h2", {
|
|
91
|
+
className: "text-2xl font-bold text-foreground",
|
|
92
|
+
children: title
|
|
93
|
+
}),
|
|
94
|
+
/* @__PURE__ */ jsx("p", {
|
|
95
|
+
className: "mt-2 text-sm text-muted-foreground",
|
|
96
|
+
children: description
|
|
97
|
+
})
|
|
98
|
+
]
|
|
99
|
+
})
|
|
100
|
+
})), children]
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
//#endregion
|
|
104
|
+
export { DropZone };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
3
|
+
//#region src/primitives/dropdown-menu.d.ts
|
|
4
|
+
declare const DropdownMenu: React.FC<DropdownMenuPrimitive.DropdownMenuProps>;
|
|
5
|
+
declare const DropdownMenuTrigger: React.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
6
|
+
declare const DropdownMenuGroup: React.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuGroupProps & React.RefAttributes<HTMLDivElement>>;
|
|
7
|
+
declare const DropdownMenuPortal: React.FC<DropdownMenuPrimitive.DropdownMenuPortalProps>;
|
|
8
|
+
declare const DropdownMenuSub: React.FC<DropdownMenuPrimitive.DropdownMenuSubProps>;
|
|
9
|
+
declare const DropdownMenuRadioGroup: React.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuRadioGroupProps & React.RefAttributes<HTMLDivElement>>;
|
|
10
|
+
declare const DropdownMenuSubTrigger: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuSubTriggerProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
|
|
11
|
+
inset?: boolean;
|
|
12
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
13
|
+
declare const DropdownMenuSubContent: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuSubContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
14
|
+
declare const DropdownMenuContent: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
15
|
+
declare const DropdownMenuItem: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuItemProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
|
|
16
|
+
inset?: boolean;
|
|
17
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
18
|
+
declare const DropdownMenuCheckboxItem: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuCheckboxItemProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
19
|
+
declare const DropdownMenuRadioItem: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuRadioItemProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
20
|
+
declare const DropdownMenuLabel: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuLabelProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
|
|
21
|
+
inset?: boolean;
|
|
22
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
23
|
+
declare const DropdownMenuSeparator: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuSeparatorProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
24
|
+
declare function DropdownMenuShortcut({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>): React.JSX.Element;
|
|
25
|
+
declare namespace DropdownMenuShortcut {
|
|
26
|
+
var displayName: string;
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger };
|
|
@@ -1,29 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { cn } from "../lib/utils.js";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
4
|
import { Check, ChevronRight, Circle } from "lucide-react";
|
|
5
|
-
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
6
5
|
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
7
|
-
//#region src/primitives/avatar.tsx
|
|
8
|
-
const Avatar = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(AvatarPrimitive.Root, {
|
|
9
|
-
ref,
|
|
10
|
-
className: cn("relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full", className),
|
|
11
|
-
...props
|
|
12
|
-
}));
|
|
13
|
-
Avatar.displayName = AvatarPrimitive.Root.displayName;
|
|
14
|
-
const AvatarImage = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(AvatarPrimitive.Image, {
|
|
15
|
-
ref,
|
|
16
|
-
className: cn("aspect-square h-full w-full", className),
|
|
17
|
-
...props
|
|
18
|
-
}));
|
|
19
|
-
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
|
20
|
-
const AvatarFallback = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(AvatarPrimitive.Fallback, {
|
|
21
|
-
ref,
|
|
22
|
-
className: cn("flex h-full w-full items-center justify-center rounded-full bg-muted font-medium text-sm", className),
|
|
23
|
-
...props
|
|
24
|
-
}));
|
|
25
|
-
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
|
|
26
|
-
//#endregion
|
|
27
6
|
//#region src/primitives/dropdown-menu.tsx
|
|
28
7
|
const DropdownMenu = DropdownMenuPrimitive.Root;
|
|
29
8
|
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
@@ -98,4 +77,4 @@ const DropdownMenuShortcut = ({ className, ...props }) => {
|
|
|
98
77
|
};
|
|
99
78
|
DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
|
|
100
79
|
//#endregion
|
|
101
|
-
export {
|
|
80
|
+
export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
//#region src/primitives/empty-state.d.ts
|
|
3
|
+
export interface EmptyStateProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
icon?: React.ReactNode;
|
|
5
|
+
title: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
action?: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
declare const EmptyState: React.ForwardRefExoticComponent<EmptyStateProps & React.RefAttributes<HTMLDivElement>>;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { EmptyState };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { cn } from "../lib/utils.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
//#region src/primitives/empty-state.tsx
|
|
5
|
+
const EmptyState = React.forwardRef(({ className, icon, title, description, action, ...props }, ref) => {
|
|
6
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
7
|
+
ref,
|
|
8
|
+
className: cn("flex flex-col items-center justify-center px-4 py-16 text-center", className),
|
|
9
|
+
...props,
|
|
10
|
+
children: [
|
|
11
|
+
icon && /* @__PURE__ */ jsx("div", {
|
|
12
|
+
className: "mb-4 rounded-full bg-muted p-4 text-muted-foreground",
|
|
13
|
+
children: icon
|
|
14
|
+
}),
|
|
15
|
+
/* @__PURE__ */ jsx("h3", {
|
|
16
|
+
className: "font-semibold text-lg",
|
|
17
|
+
children: title
|
|
18
|
+
}),
|
|
19
|
+
description && /* @__PURE__ */ jsx("p", {
|
|
20
|
+
className: "mt-2 max-w-sm text-muted-foreground text-sm",
|
|
21
|
+
children: description
|
|
22
|
+
}),
|
|
23
|
+
action && /* @__PURE__ */ jsx("div", {
|
|
24
|
+
className: "mt-6",
|
|
25
|
+
children: action
|
|
26
|
+
})
|
|
27
|
+
]
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
EmptyState.displayName = "EmptyState";
|
|
31
|
+
//#endregion
|
|
32
|
+
export { EmptyState };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
//#region src/primitives/heading.d.ts
|
|
3
|
+
/** Visual roles ported from sandbox-ui/src/primitives/heading.tsx. */
|
|
4
|
+
export type HeadingVariant = "display" | "hero" | "page" | "section" | "subsection" | "eyebrow";
|
|
5
|
+
export interface HeadingProps extends Omit<React.HTMLAttributes<HTMLElement>, "role"> {
|
|
6
|
+
/** Visual treatment, independent of the rendered element. Defaults to section. */
|
|
7
|
+
variant?: HeadingVariant;
|
|
8
|
+
/** Semantic element; changing it does not change the visual variant. */
|
|
9
|
+
as?: React.ElementType;
|
|
10
|
+
/**
|
|
11
|
+
* Native ARIA role, or Sandbox's existing visual-role input. Only the six
|
|
12
|
+
* legacy visual values are consumed; they are never emitted as ARIA roles.
|
|
13
|
+
* Prefer variant for new code. An explicit variant wins over a legacy role.
|
|
14
|
+
*/
|
|
15
|
+
role?: React.AriaRole | HeadingVariant;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* One renderer for page, section and card titles. Use at most one default
|
|
19
|
+
* display/page h1 per page; choose `as` according to the document hierarchy.
|
|
20
|
+
*/
|
|
21
|
+
declare const Heading: React.ForwardRefExoticComponent<HeadingProps & React.RefAttributes<HTMLElement>>;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { Heading };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { cn } from "../lib/utils.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/primitives/heading.tsx
|
|
5
|
+
const VARIANT_CLASS = {
|
|
6
|
+
display: "font-display font-bold text-foreground text-[length:var(--font-size-display,3rem)] leading-[var(--line-height-display,1.05)] tracking-[var(--tracking-tight,-0.02em)]",
|
|
7
|
+
hero: "font-display font-bold text-foreground text-[length:var(--font-size-hero,2.5rem)] leading-[1.1] tracking-[var(--tracking-tight,-0.02em)]",
|
|
8
|
+
page: "font-display font-semibold text-foreground text-[length:var(--font-size-3xl,1.875rem)] leading-[var(--line-height-heading,1.15)] tracking-[var(--tracking-tight,-0.02em)]",
|
|
9
|
+
section: "font-display font-semibold text-foreground text-[length:var(--font-size-xl,1.25rem)] leading-[1.3] tracking-[var(--tracking-snug,-0.01em)]",
|
|
10
|
+
subsection: "font-semibold text-foreground text-[length:var(--font-size-lg,1rem)] leading-[1.4]",
|
|
11
|
+
eyebrow: "font-semibold uppercase text-muted-foreground text-[length:var(--font-size-sm,0.75rem)] leading-none tracking-[var(--tracking-wide,0.08em)]"
|
|
12
|
+
};
|
|
13
|
+
const DEFAULT_TAG = {
|
|
14
|
+
display: "h1",
|
|
15
|
+
hero: "h2",
|
|
16
|
+
page: "h1",
|
|
17
|
+
section: "h2",
|
|
18
|
+
subsection: "h3",
|
|
19
|
+
eyebrow: "p"
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* One renderer for page, section and card titles. Use at most one default
|
|
23
|
+
* display/page h1 per page; choose `as` according to the document hierarchy.
|
|
24
|
+
*/
|
|
25
|
+
const Heading = React.forwardRef(({ variant, role, as, className, ...props }, ref) => {
|
|
26
|
+
const legacyVariant = role && Object.prototype.hasOwnProperty.call(VARIANT_CLASS, role) ? role : void 0;
|
|
27
|
+
const visualVariant = variant ?? legacyVariant ?? "section";
|
|
28
|
+
const Tag = as ?? DEFAULT_TAG[visualVariant];
|
|
29
|
+
return /* @__PURE__ */ jsx(Tag, {
|
|
30
|
+
ref,
|
|
31
|
+
className: cn("[overflow-wrap:anywhere]", VARIANT_CLASS[visualVariant], className),
|
|
32
|
+
role: legacyVariant ? void 0 : role,
|
|
33
|
+
...props
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
Heading.displayName = "Heading";
|
|
37
|
+
//#endregion
|
|
38
|
+
export { Heading };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { VariantProps } from "class-variance-authority";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
//#region src/primitives/input.d.ts
|
|
4
|
+
declare const inputVariants: (props?: ({
|
|
5
|
+
variant?: "default" | "error" | "sandbox" | null | undefined;
|
|
6
|
+
size?: "default" | "lg" | "sm" | null | undefined;
|
|
7
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
8
|
+
export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size">, VariantProps<typeof inputVariants> {
|
|
9
|
+
label?: string;
|
|
10
|
+
error?: string;
|
|
11
|
+
hint?: string;
|
|
12
|
+
}
|
|
13
|
+
declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
|
|
14
|
+
export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
15
|
+
/** Both values render the same field. */
|
|
16
|
+
variant?: "default" | "sandbox";
|
|
17
|
+
label?: string;
|
|
18
|
+
error?: string;
|
|
19
|
+
hint?: string;
|
|
20
|
+
}
|
|
21
|
+
declare const Textarea: React.ForwardRefExoticComponent<TextareaProps & React.RefAttributes<HTMLTextAreaElement>>;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { Input, Textarea };
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { focusField, focusFieldInvalid } from "../lib/focus.js";
|
|
3
|
+
import { cn } from "../lib/utils.js";
|
|
4
|
+
import { Label } from "./label.js";
|
|
5
|
+
import { cva } from "class-variance-authority";
|
|
6
|
+
import * as React from "react";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
//#region src/primitives/input.tsx
|
|
9
|
+
const inputVariants = cva(cn("flex w-full rounded-lg border bg-card px-4 py-2 text-sm placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 file:border-0 file:bg-transparent file:font-medium file:text-sm", focusField), {
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
default: "",
|
|
13
|
+
sandbox: "",
|
|
14
|
+
error: focusFieldInvalid
|
|
15
|
+
},
|
|
16
|
+
size: {
|
|
17
|
+
default: "h-11",
|
|
18
|
+
sm: "h-9 px-3",
|
|
19
|
+
lg: "h-12 px-5"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
defaultVariants: {
|
|
23
|
+
variant: "default",
|
|
24
|
+
size: "default"
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
function descriptionIds(...ids) {
|
|
28
|
+
return [...new Set(ids.join(" ").split(/\s+/).filter(Boolean))].join(" ") || void 0;
|
|
29
|
+
}
|
|
30
|
+
const Input = React.forwardRef(({ className, type, variant, size, label, error, hint, id, "aria-describedby": describedBy, "aria-invalid": invalid, ...props }, ref) => {
|
|
31
|
+
const generatedId = React.useId();
|
|
32
|
+
const inputId = id ?? generatedId;
|
|
33
|
+
const hintId = hint ? `${inputId}-hint` : void 0;
|
|
34
|
+
const errorId = error ? `${inputId}-error` : void 0;
|
|
35
|
+
const input = /* @__PURE__ */ jsx("input", {
|
|
36
|
+
type,
|
|
37
|
+
id: inputId,
|
|
38
|
+
className: cn(inputVariants({
|
|
39
|
+
variant: error ? "error" : variant,
|
|
40
|
+
size,
|
|
41
|
+
className
|
|
42
|
+
})),
|
|
43
|
+
ref,
|
|
44
|
+
...props,
|
|
45
|
+
"aria-describedby": descriptionIds(describedBy, hintId, errorId),
|
|
46
|
+
"aria-invalid": error || variant === "error" ? true : invalid
|
|
47
|
+
});
|
|
48
|
+
if (!label && !error && !hint) return input;
|
|
49
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
50
|
+
className: "w-full space-y-1.5",
|
|
51
|
+
children: [
|
|
52
|
+
label && /* @__PURE__ */ jsx(Label, {
|
|
53
|
+
htmlFor: inputId,
|
|
54
|
+
className: "block",
|
|
55
|
+
children: label
|
|
56
|
+
}),
|
|
57
|
+
input,
|
|
58
|
+
error && /* @__PURE__ */ jsx("p", {
|
|
59
|
+
id: errorId,
|
|
60
|
+
className: "text-[var(--surface-danger-text)] text-sm font-medium",
|
|
61
|
+
children: error
|
|
62
|
+
}),
|
|
63
|
+
hint && /* @__PURE__ */ jsx("p", {
|
|
64
|
+
id: hintId,
|
|
65
|
+
className: "text-[var(--text-dim)] text-sm",
|
|
66
|
+
children: hint
|
|
67
|
+
})
|
|
68
|
+
]
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
Input.displayName = "Input";
|
|
72
|
+
const Textarea = React.forwardRef(({ className, variant: _variant, label, error, hint, id, "aria-describedby": describedBy, "aria-invalid": invalid, ...props }, ref) => {
|
|
73
|
+
const generatedId = React.useId();
|
|
74
|
+
const textareaId = id ?? generatedId;
|
|
75
|
+
const hintId = hint ? `${textareaId}-hint` : void 0;
|
|
76
|
+
const errorId = error ? `${textareaId}-error` : void 0;
|
|
77
|
+
const textarea = /* @__PURE__ */ jsx("textarea", {
|
|
78
|
+
id: textareaId,
|
|
79
|
+
className: cn("flex min-h-[120px] w-full resize-y rounded-lg border bg-card px-4 py-3 text-sm", "placeholder:text-muted-foreground", "disabled:cursor-not-allowed disabled:opacity-50", focusField, error && "border-[var(--surface-danger-border)] hover:border-[var(--surface-danger-border)] focus:border-[var(--focus-border-danger)] focus:ring-[var(--focus-halo-danger)]", className),
|
|
80
|
+
ref,
|
|
81
|
+
...props,
|
|
82
|
+
"aria-describedby": descriptionIds(describedBy, hintId, errorId),
|
|
83
|
+
"aria-invalid": error ? true : invalid
|
|
84
|
+
});
|
|
85
|
+
if (!label && !error && !hint) return textarea;
|
|
86
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
87
|
+
className: "w-full space-y-1.5",
|
|
88
|
+
children: [
|
|
89
|
+
label && /* @__PURE__ */ jsx(Label, {
|
|
90
|
+
htmlFor: textareaId,
|
|
91
|
+
className: "block",
|
|
92
|
+
children: label
|
|
93
|
+
}),
|
|
94
|
+
textarea,
|
|
95
|
+
error && /* @__PURE__ */ jsx("p", {
|
|
96
|
+
id: errorId,
|
|
97
|
+
className: "text-[var(--surface-danger-text)] text-sm",
|
|
98
|
+
children: error
|
|
99
|
+
}),
|
|
100
|
+
hint && /* @__PURE__ */ jsx("p", {
|
|
101
|
+
id: hintId,
|
|
102
|
+
className: "text-[var(--text-dim)] text-sm",
|
|
103
|
+
children: hint
|
|
104
|
+
})
|
|
105
|
+
]
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
Textarea.displayName = "Textarea";
|
|
109
|
+
//#endregion
|
|
110
|
+
export { Input, Textarea };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
3
|
+
//#region src/primitives/label.d.ts
|
|
4
|
+
declare const Label: React.ForwardRefExoticComponent<Omit<LabelPrimitive.LabelProps & React.RefAttributes<HTMLLabelElement>, "ref"> & React.RefAttributes<HTMLLabelElement>>;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { Label };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../lib/utils.js";
|
|
3
|
+
import { cva } from "class-variance-authority";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
7
|
+
//#region src/primitives/label.tsx
|
|
8
|
+
const labelVariants = cva("font-medium text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70");
|
|
9
|
+
const Label = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(LabelPrimitive.Root, {
|
|
10
|
+
ref,
|
|
11
|
+
className: cn(labelVariants(), className),
|
|
12
|
+
...props
|
|
13
|
+
}));
|
|
14
|
+
Label.displayName = LabelPrimitive.Root.displayName;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { Label };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { StatusTone } from "./status-pill.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
//#region src/primitives/metric-strip.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* The headline figures for a console page, as ONE statement rather than four.
|
|
6
|
+
*
|
|
7
|
+
* A row of separate stat cards is the default and it is usually wrong here.
|
|
8
|
+
* Each card is a box that must be tall enough for its longest member, so a row
|
|
9
|
+
* mixing "$248.55 / Personal wallet" against a bare "0" leaves the short ones
|
|
10
|
+
* mostly empty; and four bordered boxes read as four unrelated facts when they
|
|
11
|
+
* are four readings of one account. `MetricStrip` puts them on one plane
|
|
12
|
+
* divided by hairlines: same information, one object, no holes.
|
|
13
|
+
*
|
|
14
|
+
* The divider is a border on the item rather than a `divide-*` utility on the
|
|
15
|
+
* parent, because these wrap. `divide-x` draws from DOM order and leaves a
|
|
16
|
+
* stray rule at the start of every wrapped line; a per-item leading border
|
|
17
|
+
* suppressed at each row start does not.
|
|
18
|
+
*/
|
|
19
|
+
export interface MetricStripProps extends React.HTMLAttributes<HTMLDListElement> {
|
|
20
|
+
children: React.ReactNode;
|
|
21
|
+
}
|
|
22
|
+
declare const MetricStrip: React.ForwardRefExoticComponent<MetricStripProps & React.RefAttributes<HTMLDListElement>>;
|
|
23
|
+
export interface MetricProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
24
|
+
label: React.ReactNode;
|
|
25
|
+
value: React.ReactNode;
|
|
26
|
+
/** The qualifying line: which wallet, which window, what the limit is. */
|
|
27
|
+
hint?: React.ReactNode;
|
|
28
|
+
/** Raises the value's tone and shows a pill beside the label. A metric is
|
|
29
|
+
* `attention` only when a person has to DO something — not merely when a
|
|
30
|
+
* number is zero. */
|
|
31
|
+
attention?: {
|
|
32
|
+
tone: StatusTone;
|
|
33
|
+
label: string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* One reading inside a `MetricStrip`.
|
|
38
|
+
*
|
|
39
|
+
* `<dt>` carries the label and `<dd>` the value, so the pair is announced as a
|
|
40
|
+
* described term rather than as two loose strings — the semantic that makes a
|
|
41
|
+
* figure legible without the visual grouping.
|
|
42
|
+
*
|
|
43
|
+
* The value is `tabular-nums`: these sit in a row and change on a timer, and
|
|
44
|
+
* proportional digits make the column jitter every time a 1 becomes an 8.
|
|
45
|
+
*/
|
|
46
|
+
declare const Metric: React.ForwardRefExoticComponent<MetricProps & React.RefAttributes<HTMLDivElement>>;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { Metric, MetricStrip };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { cn } from "../lib/utils.js";
|
|
2
|
+
import { StatusPill } from "./status-pill.js";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/primitives/metric-strip.tsx
|
|
6
|
+
const MetricStrip = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx("dl", {
|
|
7
|
+
ref,
|
|
8
|
+
className: cn("grid grid-cols-2 rounded-[var(--radius-lg)] border border-border bg-card shadow-[var(--shadow-card)] sm:grid-cols-4", className),
|
|
9
|
+
...props,
|
|
10
|
+
children
|
|
11
|
+
}));
|
|
12
|
+
MetricStrip.displayName = "MetricStrip";
|
|
13
|
+
/**
|
|
14
|
+
* One reading inside a `MetricStrip`.
|
|
15
|
+
*
|
|
16
|
+
* `<dt>` carries the label and `<dd>` the value, so the pair is announced as a
|
|
17
|
+
* described term rather than as two loose strings — the semantic that makes a
|
|
18
|
+
* figure legible without the visual grouping.
|
|
19
|
+
*
|
|
20
|
+
* The value is `tabular-nums`: these sit in a row and change on a timer, and
|
|
21
|
+
* proportional digits make the column jitter every time a 1 becomes an 8.
|
|
22
|
+
*/
|
|
23
|
+
const Metric = React.forwardRef(({ className, label, value, hint, attention, ...props }, ref) => /* @__PURE__ */ jsxs("div", {
|
|
24
|
+
ref,
|
|
25
|
+
className: cn("border-border p-4 sm:p-5", "max-sm:[&:not(:nth-child(2n+1))]:border-l", "sm:[&:not(:nth-child(4n+1))]:border-l", className),
|
|
26
|
+
...props,
|
|
27
|
+
children: [
|
|
28
|
+
/* @__PURE__ */ jsxs("dt", {
|
|
29
|
+
className: "flex items-center gap-2 text-muted-foreground text-sm",
|
|
30
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
31
|
+
className: "truncate",
|
|
32
|
+
children: label
|
|
33
|
+
}), attention && /* @__PURE__ */ jsx(StatusPill, {
|
|
34
|
+
tone: attention.tone,
|
|
35
|
+
children: attention.label
|
|
36
|
+
})]
|
|
37
|
+
}),
|
|
38
|
+
/* @__PURE__ */ jsx("dd", {
|
|
39
|
+
className: cn("mt-1 truncate font-semibold text-xl tabular-nums tracking-tight lg:text-2xl", attention?.tone === "danger" && "text-[var(--surface-danger-text)]"),
|
|
40
|
+
title: typeof value === "string" ? value : void 0,
|
|
41
|
+
children: value
|
|
42
|
+
}),
|
|
43
|
+
hint && /* @__PURE__ */ jsx("dd", {
|
|
44
|
+
className: "mt-0.5 truncate text-[var(--text-dim)] text-xs",
|
|
45
|
+
title: typeof hint === "string" ? hint : void 0,
|
|
46
|
+
children: hint
|
|
47
|
+
})
|
|
48
|
+
]
|
|
49
|
+
}));
|
|
50
|
+
Metric.displayName = "Metric";
|
|
51
|
+
//#endregion
|
|
52
|
+
export { Metric, MetricStrip };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
//#region src/primitives/page-header.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* A page masthead with separate title, prose, actions and qualifying metadata.
|
|
5
|
+
* Brand's existing props and header ref are preserved. Sandbox's existing
|
|
6
|
+
* action/eyebrow/titleAs inputs map into the same renderer, not a second header.
|
|
7
|
+
*/
|
|
8
|
+
export interface PageHeaderProps extends Omit<React.HTMLAttributes<HTMLElement>, "title"> {
|
|
9
|
+
title: React.ReactNode;
|
|
10
|
+
description?: React.ReactNode;
|
|
11
|
+
/** Canonical action slot. If supplied (even null), takes precedence over action. */
|
|
12
|
+
actions?: React.ReactNode;
|
|
13
|
+
meta?: React.ReactNode;
|
|
14
|
+
titleId?: string;
|
|
15
|
+
/** Existing nested-surface treatment: h2 and section typography. */
|
|
16
|
+
level?: 1 | 2;
|
|
17
|
+
/** Existing Sandbox action slot; used only when actions is undefined. */
|
|
18
|
+
action?: React.ReactNode;
|
|
19
|
+
eyebrow?: React.ReactNode;
|
|
20
|
+
/** Existing Sandbox semantic override; takes precedence over level's tag only. */
|
|
21
|
+
titleAs?: React.ElementType;
|
|
22
|
+
}
|
|
23
|
+
declare const PageHeader: React.ForwardRefExoticComponent<PageHeaderProps & React.RefAttributes<HTMLElement>>;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { PageHeader };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { cn } from "../lib/utils.js";
|
|
2
|
+
import { Heading } from "./heading.js";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/primitives/page-header.tsx
|
|
6
|
+
const hasContent = (node) => Boolean(node) || node === 0;
|
|
7
|
+
const PageHeader = React.forwardRef(({ className, title, description, actions, action, eyebrow, meta, titleId, titleAs, level = 1, ...props }, ref) => {
|
|
8
|
+
const resolvedActions = actions === void 0 ? action : actions;
|
|
9
|
+
return /* @__PURE__ */ jsxs("header", {
|
|
10
|
+
ref,
|
|
11
|
+
className: cn("mb-6 min-w-0", className),
|
|
12
|
+
...props,
|
|
13
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
14
|
+
className: "flex min-w-0 flex-wrap items-start justify-between gap-x-6 gap-y-3",
|
|
15
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
16
|
+
className: "min-w-0 flex-[1_1_16rem]",
|
|
17
|
+
children: [
|
|
18
|
+
hasContent(eyebrow) && /* @__PURE__ */ jsx(Heading, {
|
|
19
|
+
variant: "eyebrow",
|
|
20
|
+
className: "mb-1.5",
|
|
21
|
+
children: eyebrow
|
|
22
|
+
}),
|
|
23
|
+
/* @__PURE__ */ jsx(Heading, {
|
|
24
|
+
id: titleId,
|
|
25
|
+
variant: level === 1 ? "page" : "section",
|
|
26
|
+
as: titleAs ?? (level === 1 ? "h1" : "h2"),
|
|
27
|
+
className: "text-balance",
|
|
28
|
+
children: title
|
|
29
|
+
}),
|
|
30
|
+
hasContent(description) && /* @__PURE__ */ jsx("p", {
|
|
31
|
+
className: "mt-1 max-w-prose text-muted-foreground text-sm [overflow-wrap:anywhere]",
|
|
32
|
+
children: description
|
|
33
|
+
})
|
|
34
|
+
]
|
|
35
|
+
}), hasContent(resolvedActions) && /* @__PURE__ */ jsx("div", {
|
|
36
|
+
className: "flex min-w-0 max-w-full flex-wrap items-center gap-2 [overflow-wrap:anywhere] [&>*]:min-w-0 [&>*]:max-w-full",
|
|
37
|
+
children: resolvedActions
|
|
38
|
+
})]
|
|
39
|
+
}), hasContent(meta) && /* @__PURE__ */ jsx("div", {
|
|
40
|
+
className: "mt-3 flex min-w-0 flex-wrap items-center gap-x-4 gap-y-2 text-[var(--text-dim)] text-xs [overflow-wrap:anywhere]",
|
|
41
|
+
children: meta
|
|
42
|
+
})]
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
PageHeader.displayName = "PageHeader";
|
|
46
|
+
//#endregion
|
|
47
|
+
export { PageHeader };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
//#region src/primitives/page-shell.d.ts
|
|
3
|
+
export interface PageShellProps {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Ported from sandbox-ui/src/primitives/page-shell.tsx. An optional bounded
|
|
9
|
+
* width, gutter and vertical rhythm, not an application shell or a card grid.
|
|
10
|
+
* The caller owns landmarks, routing, auth, navigation and data state. Use
|
|
11
|
+
* className to override the bound/gutters, or omit it for a workbench layout.
|
|
12
|
+
*/
|
|
13
|
+
export declare function PageShell({ children, className }: PageShellProps): import("react").JSX.Element;
|
|
14
|
+
//#endregion
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { cn } from "../lib/utils.js";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
//#region src/primitives/page-shell.tsx
|
|
4
|
+
/**
|
|
5
|
+
* Ported from sandbox-ui/src/primitives/page-shell.tsx. An optional bounded
|
|
6
|
+
* width, gutter and vertical rhythm, not an application shell or a card grid.
|
|
7
|
+
* The caller owns landmarks, routing, auth, navigation and data state. Use
|
|
8
|
+
* className to override the bound/gutters, or omit it for a workbench layout.
|
|
9
|
+
*/
|
|
10
|
+
function PageShell({ children, className }) {
|
|
11
|
+
return /* @__PURE__ */ jsx("div", {
|
|
12
|
+
className: cn("mx-auto min-w-0 w-full max-w-6xl space-y-8 px-6 py-8 lg:px-8", className),
|
|
13
|
+
children
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { PageShell };
|