@tangle-network/ui 11.12.0 → 11.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (276) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/_virtual/_rolldown/runtime.js +13 -0
  3. package/dist/auth/auth.d.ts +53 -0
  4. package/dist/{auth-DOETfnd9.js → auth/auth.js} +7 -37
  5. package/dist/auth/login-layout.d.ts +20 -0
  6. package/dist/auth/login-layout.js +36 -0
  7. package/dist/auth.d.ts +2 -1
  8. package/dist/auth.js +2 -1
  9. package/dist/chat/agent-timeline.d.ts +83 -0
  10. package/dist/chat/agent-timeline.js +236 -0
  11. package/dist/chat/chat-container.d.ts +51 -0
  12. package/dist/chat/chat-container.js +309 -0
  13. package/dist/chat/chat-message.d.ts +22 -0
  14. package/dist/chat/chat-message.js +38 -0
  15. package/dist/chat/message-list.d.ts +32 -0
  16. package/dist/chat/message-list.js +37 -0
  17. package/dist/chat/thinking-indicator.d.ts +6 -0
  18. package/dist/chat/thinking-indicator.js +38 -0
  19. package/dist/chat/user-message.d.ts +21 -0
  20. package/dist/chat/user-message.js +42 -0
  21. package/dist/chat.d.ts +6 -1
  22. package/dist/chat.js +6 -1
  23. package/dist/editor/document-editor-pane.d.ts +37 -0
  24. package/dist/editor/document-editor-pane.js +199 -0
  25. package/dist/editor/editor-lazy.js +37 -0
  26. package/dist/editor/editor-loading.js +21 -0
  27. package/dist/editor/editor-peers.d.ts +6 -0
  28. package/dist/editor/editor-peers.js +155 -0
  29. package/dist/editor/editor-provider.d.ts +97 -0
  30. package/dist/editor/editor-provider.js +253 -0
  31. package/dist/editor/editor-toolbar.d.ts +11 -0
  32. package/dist/editor/editor-toolbar.js +106 -0
  33. package/dist/editor/markdown-conversion.js +23 -0
  34. package/dist/editor/markdown-document-editor.js +103 -0
  35. package/dist/editor/tiptap-editor.d.ts +45 -0
  36. package/dist/editor/tiptap-editor.js +271 -0
  37. package/dist/editor/use-editor.d.ts +67 -0
  38. package/dist/editor/use-editor.js +158 -0
  39. package/dist/editor.d.ts +6 -119
  40. package/dist/editor.js +5 -1
  41. package/dist/files/file-artifact-pane.d.ts +47 -0
  42. package/dist/files/file-artifact-pane.js +114 -0
  43. package/dist/files/file-format.d.ts +51 -0
  44. package/dist/{file-format-BgXbr-Ib.js → files/file-format.js} +1 -1
  45. package/dist/files/file-preview.d.ts +27 -0
  46. package/dist/files/file-preview.js +359 -0
  47. package/dist/files/file-tabs.d.ts +19 -0
  48. package/dist/files/file-tabs.js +48 -0
  49. package/dist/files/file-tree.d.ts +31 -0
  50. package/dist/files/file-tree.js +135 -0
  51. package/dist/files/rich-file-tree.d.ts +62 -0
  52. package/dist/files/rich-file-tree.js +122 -0
  53. package/dist/files.d.ts +6 -1
  54. package/dist/files.js +6 -2
  55. package/dist/hooks/use-auth.d.ts +40 -0
  56. package/dist/hooks/use-auth.js +91 -0
  57. package/dist/hooks/use-auto-scroll.d.ts +11 -0
  58. package/dist/hooks/use-auto-scroll.js +48 -0
  59. package/dist/hooks/use-dropdown-menu.d.ts +12 -0
  60. package/dist/hooks/use-dropdown-menu.js +31 -0
  61. package/dist/hooks/use-live-time.d.ts +7 -0
  62. package/dist/hooks/use-live-time.js +22 -0
  63. package/dist/hooks/use-realtime-session.d.ts +32 -0
  64. package/dist/hooks/use-realtime-session.js +235 -0
  65. package/dist/hooks/use-run-collapse-state.d.ts +13 -0
  66. package/dist/hooks/use-run-collapse-state.js +24 -0
  67. package/dist/hooks/use-run-groups.d.ts +11 -0
  68. package/dist/hooks/use-run-groups.js +85 -0
  69. package/dist/hooks/use-sdk-session.d.ts +59 -0
  70. package/dist/hooks/use-sdk-session.js +322 -0
  71. package/dist/hooks/use-sse-stream.d.ts +124 -0
  72. package/dist/hooks/use-sse-stream.js +229 -0
  73. package/dist/hooks/use-tool-call-stream.d.ts +23 -0
  74. package/dist/hooks/use-tool-call-stream.js +75 -0
  75. package/dist/hooks.d.ts +11 -49
  76. package/dist/hooks.js +10 -110
  77. package/dist/index.d.ts +99 -25
  78. package/dist/index.js +86 -36
  79. package/dist/lib/focus.d.ts +55 -0
  80. package/dist/{focus-BcE_SHqz.js → lib/focus.js} +1 -1
  81. package/dist/lib/utils.d.ts +4 -0
  82. package/dist/{utils-C_uf36nf.js → lib/utils.js} +1 -1
  83. package/dist/{code-block-B9miUPht.d.ts → markdown/code-block.d.ts} +5 -6
  84. package/dist/{code-block-B36KVUSN.js → markdown/code-block.js} +60 -55
  85. package/dist/{markdown-C0atSabr.d.ts → markdown/markdown.d.ts} +4 -5
  86. package/dist/{markdown-Db08KAYF.js → markdown/markdown.js} +3 -3
  87. package/dist/markdown.d.ts +2 -2
  88. package/dist/markdown.js +2 -2
  89. package/dist/{openui-artifact-renderer-fkBQaoLO.d.ts → openui/openui-artifact-renderer.d.ts} +20 -21
  90. package/dist/{openui-artifact-renderer-DG_i2lOR.js → openui/openui-artifact-renderer.js} +9 -7
  91. package/dist/{schema-BpW9rSSG.js → openui/schema-compiled.js} +2 -354
  92. package/dist/{schema-DAstk-J4.d.ts → openui/schema-data.d.ts} +3 -24
  93. package/dist/openui/schema-data.js +206 -0
  94. package/dist/openui-schema.d.ts +22 -3
  95. package/dist/openui-schema.js +138 -1
  96. package/dist/openui.d.ts +3 -2
  97. package/dist/openui.js +3 -2
  98. package/dist/{artifact-pane-BL_DFWNl.d.ts → primitives/artifact-pane.d.ts} +3 -4
  99. package/dist/{artifact-pane-DMXT9a8U.js → primitives/artifact-pane.js} +2 -2
  100. package/dist/primitives/avatar.d.ts +8 -0
  101. package/dist/primitives/avatar.js +25 -0
  102. package/dist/primitives/badge.d.ts +22 -0
  103. package/dist/primitives/badge.js +47 -0
  104. package/dist/{button-yoIv77e2.d.ts → primitives/button.d.ts} +2 -2
  105. package/dist/primitives/button.js +113 -0
  106. package/dist/primitives/card.d.ts +18 -0
  107. package/dist/primitives/card.js +52 -0
  108. package/dist/primitives/code-block.d.ts +6 -0
  109. package/dist/primitives/code-block.js +13 -0
  110. package/dist/primitives/dialog.d.ts +23 -0
  111. package/dist/primitives/dialog.js +59 -0
  112. package/dist/primitives/drop-zone.d.ts +23 -0
  113. package/dist/primitives/drop-zone.js +104 -0
  114. package/dist/primitives/dropdown-menu.d.ts +29 -0
  115. package/dist/{dropdown-menu-BpcLa5vF.js → primitives/dropdown-menu.js} +2 -23
  116. package/dist/primitives/empty-state.d.ts +11 -0
  117. package/dist/primitives/empty-state.js +32 -0
  118. package/dist/primitives/heading.d.ts +23 -0
  119. package/dist/primitives/heading.js +38 -0
  120. package/dist/primitives/input.d.ts +23 -0
  121. package/dist/primitives/input.js +110 -0
  122. package/dist/primitives/label.d.ts +6 -0
  123. package/dist/primitives/label.js +16 -0
  124. package/dist/primitives/metric-strip.d.ts +48 -0
  125. package/dist/primitives/metric-strip.js +52 -0
  126. package/dist/primitives/page-header.d.ts +25 -0
  127. package/dist/primitives/page-header.js +47 -0
  128. package/dist/primitives/page-shell.d.ts +14 -0
  129. package/dist/primitives/page-shell.js +17 -0
  130. package/dist/primitives/progress.d.ts +9 -0
  131. package/dist/primitives/progress.js +29 -0
  132. package/dist/primitives/segmented-control.d.ts +40 -0
  133. package/dist/primitives/segmented-control.js +57 -0
  134. package/dist/primitives/select.d.ts +15 -0
  135. package/dist/primitives/select.js +74 -0
  136. package/dist/primitives/sidebar-drop-zone.d.ts +21 -0
  137. package/dist/primitives/sidebar-drop-zone.js +88 -0
  138. package/dist/primitives/skeleton.d.ts +10 -0
  139. package/dist/primitives/skeleton.js +50 -0
  140. package/dist/primitives/stat-card.d.ts +16 -0
  141. package/dist/primitives/stat-card.js +60 -0
  142. package/dist/primitives/status-pill.d.ts +44 -0
  143. package/dist/primitives/status-pill.js +119 -0
  144. package/dist/primitives/switch.d.ts +6 -0
  145. package/dist/primitives/switch.js +16 -0
  146. package/dist/primitives/table.d.ts +22 -0
  147. package/dist/primitives/table.js +63 -0
  148. package/dist/primitives/tabs.d.ts +13 -0
  149. package/dist/{tabs-BVHR6NkO.js → primitives/tabs.js} +3 -3
  150. package/dist/primitives/terminal-display.d.ts +25 -0
  151. package/dist/primitives/terminal-display.js +109 -0
  152. package/dist/primitives/text-shimmer.d.ts +16 -0
  153. package/dist/{text-shimmer-BUUo6I-g.js → primitives/text-shimmer.js} +2 -2
  154. package/dist/primitives/theme-toggle.d.ts +11 -0
  155. package/dist/primitives/theme-toggle.js +154 -0
  156. package/dist/primitives/toast.d.ts +29 -0
  157. package/dist/primitives/toast.js +142 -0
  158. package/dist/primitives/toolbar.d.ts +55 -0
  159. package/dist/primitives/toolbar.js +37 -0
  160. package/dist/primitives/upload-progress.d.ts +23 -0
  161. package/dist/primitives/upload-progress.js +72 -0
  162. package/dist/primitives.d.ts +35 -5
  163. package/dist/primitives.js +35 -9
  164. package/dist/{index-COgqsFAQ.d.ts → redaction/redacted-document.d.ts} +6 -7
  165. package/dist/{redaction-CGGB2ENG.js → redaction/redacted-document.js} +2 -2
  166. package/dist/redaction.d.ts +1 -1
  167. package/dist/redaction.js +1 -1
  168. package/dist/run/expandable-content.js +41 -0
  169. package/dist/run/expanded-tool-detail.d.ts +12 -0
  170. package/dist/run/expanded-tool-detail.js +163 -0
  171. package/dist/run/inline-thinking-item.d.ts +11 -0
  172. package/dist/run/inline-thinking-item.js +60 -0
  173. package/dist/run/inline-tool-item.d.ts +25 -0
  174. package/dist/run/inline-tool-item.js +63 -0
  175. package/dist/run/run-group.d.ts +26 -0
  176. package/dist/{run-group-BWGeesgs.js → run/run-group.js} +9 -60
  177. package/dist/run/run-item-primitives.d.ts +5 -0
  178. package/dist/{run-ZsIKPA6J.js → run/run-item-primitives.js} +2 -2
  179. package/dist/run/run-row-shell.d.ts +53 -0
  180. package/dist/run/run-row-shell.js +114 -0
  181. package/dist/{tool-call-feed-BeB1_4pX.d.ts → run/tool-call-feed.d.ts} +7 -12
  182. package/dist/{tool-call-feed-BpmMLpPX.js → run/tool-call-feed.js} +4 -4
  183. package/dist/run/tool-call-step.d.ts +5 -0
  184. package/dist/run/tool-call-step.js +82 -0
  185. package/dist/run.d.ts +8 -2
  186. package/dist/run.js +7 -4
  187. package/dist/sdk-hooks.d.ts +8 -1
  188. package/dist/sdk-hooks.js +8 -2
  189. package/dist/stores/active-sessions-store.d.ts +83 -0
  190. package/dist/{active-sessions-store-Gt1R0rFG.js → stores/active-sessions-store.js} +1 -1
  191. package/dist/stores/chat-store.d.ts +14 -0
  192. package/dist/stores/chat-store.js +33 -0
  193. package/dist/stores.d.ts +3 -16
  194. package/dist/stores.js +2 -33
  195. package/dist/tool-previews/command-preview.d.ts +11 -0
  196. package/dist/tool-previews/command-preview.js +91 -0
  197. package/dist/tool-previews/diff-preview.d.ts +7 -0
  198. package/dist/tool-previews/diff-preview.js +76 -0
  199. package/dist/tool-previews/glob-results-preview.d.ts +7 -0
  200. package/dist/tool-previews/glob-results-preview.js +53 -0
  201. package/dist/tool-previews/grep-results-preview.d.ts +7 -0
  202. package/dist/tool-previews/grep-results-preview.js +99 -0
  203. package/dist/tool-previews/preview-primitives.js +58 -0
  204. package/dist/tool-previews/question-preview.d.ts +7 -0
  205. package/dist/tool-previews/question-preview.js +63 -0
  206. package/dist/tool-previews/web-search-preview.d.ts +7 -0
  207. package/dist/tool-previews/web-search-preview.js +78 -0
  208. package/dist/tool-previews/write-file-preview.d.ts +11 -0
  209. package/dist/tool-previews/write-file-preview.js +52 -0
  210. package/dist/tool-previews.d.ts +7 -1
  211. package/dist/tool-previews.js +7 -1
  212. package/dist/{branding-26d5ARIr.d.ts → types/branding.d.ts} +2 -3
  213. package/dist/{message-vhUI0c5G.d.ts → types/message.d.ts} +2 -3
  214. package/dist/{parts-5mhy9yJ3.d.ts → types/parts.d.ts} +8 -9
  215. package/dist/{run-OyWmIDqu.d.ts → types/run.d.ts} +9 -10
  216. package/dist/{tool-display-DgmL5rIU.d.ts → types/tool-display.d.ts} +5 -6
  217. package/dist/types.d.ts +5 -5
  218. package/dist/utils/copy-text.d.ts +7 -0
  219. package/dist/{utils-Bl_CZ0Qp.js → utils/copy-text.js} +1 -11
  220. package/dist/utils/format.d.ts +22 -0
  221. package/dist/{format-DfcLWqMa.js → utils/format.js} +1 -1
  222. package/dist/utils/time-ago.d.ts +3 -0
  223. package/dist/utils/time-ago.js +11 -0
  224. package/dist/utils/tool-display.d.ts +16 -0
  225. package/dist/{tool-display-BAuAVa43.js → utils/tool-display.js} +1 -1
  226. package/dist/utils.d.ts +6 -1
  227. package/dist/utils.js +6 -5
  228. package/package.json +2 -2
  229. package/src/files/rich-file-tree.stories.tsx +1 -1
  230. package/src/files/rich-file-tree.tsx +12 -9
  231. package/src/markdown/code-block.test.tsx +80 -2
  232. package/src/markdown/code-block.tsx +76 -80
  233. package/src/primitives/button.stories.tsx +37 -1
  234. package/src/primitives/button.test.tsx +230 -0
  235. package/src/primitives/button.tsx +62 -14
  236. package/src/primitives/card-anatomy.stories.tsx +51 -0
  237. package/src/primitives/card.test.tsx +71 -0
  238. package/src/primitives/card.tsx +25 -13
  239. package/src/primitives/heading.stories.tsx +35 -0
  240. package/src/primitives/heading.test.tsx +56 -0
  241. package/src/primitives/heading.tsx +76 -0
  242. package/src/primitives/index.ts +8 -0
  243. package/src/primitives/input.stories.tsx +28 -0
  244. package/src/primitives/input.test.tsx +161 -0
  245. package/src/primitives/input.tsx +34 -28
  246. package/src/primitives/page-header.stories.tsx +51 -0
  247. package/src/primitives/page-header.test.tsx +48 -0
  248. package/src/primitives/page-header.tsx +35 -35
  249. package/src/primitives/page-shell.stories.tsx +89 -0
  250. package/src/primitives/page-shell.test.tsx +24 -0
  251. package/src/primitives/page-shell.tsx +26 -0
  252. package/src/primitives/table-wrapper.stories.tsx +54 -0
  253. package/src/primitives/table.test.tsx +72 -0
  254. package/src/primitives/table.tsx +33 -12
  255. package/src/primitives/theme-toggle.test.tsx +167 -0
  256. package/src/primitives/theme-toggle.tsx +111 -39
  257. package/dist/active-sessions-store-nl70ZnMC.d.ts +0 -84
  258. package/dist/button-C87nEe2R.js +0 -78
  259. package/dist/chat-DDvF2oGQ.js +0 -672
  260. package/dist/diff-preview-BcK3nRXb.js +0 -533
  261. package/dist/document-editor-pane-BilJfiCo.d.ts +0 -136
  262. package/dist/document-editor-pane-POsq5Q0o.js +0 -1279
  263. package/dist/files-hywocVZz.js +0 -753
  264. package/dist/index-2UntyjBb.d.ts +0 -52
  265. package/dist/index-BgUHilZm.d.ts +0 -108
  266. package/dist/index-CJ8wRfiC.d.ts +0 -236
  267. package/dist/index-CPDET_s1.d.ts +0 -549
  268. package/dist/index-Cg6gYAqh.d.ts +0 -73
  269. package/dist/index-Cs7j8V7l.d.ts +0 -203
  270. package/dist/index-DjKxO357.d.ts +0 -128
  271. package/dist/primitives-Bx59fT-U.js +0 -1239
  272. package/dist/table-Bss73DhB.js +0 -146
  273. package/dist/tool-call-step-DNebqhmX.js +0 -434
  274. package/dist/use-auto-scroll-C5Pjeqon.js +0 -153
  275. package/dist/use-sse-stream-DjqRuDft.js +0 -884
  276. package/dist/use-sse-stream-Dm6R5YWz.d.ts +0 -282
@@ -1,1239 +0,0 @@
1
- import { a as focusRingInset, i as focusRing, n as focusFieldInvalid, r as focusFieldWithin, t as focusField } from "./focus-BcE_SHqz.js";
2
- import { t as cn } from "./utils-C_uf36nf.js";
3
- import { d as Card } from "./table-Bss73DhB.js";
4
- import { cva } from "class-variance-authority";
5
- import * as React from "react";
6
- import { useCallback, useEffect, useRef, useState } from "react";
7
- import { jsx, jsxs } from "react/jsx-runtime";
8
- import * as DialogPrimitive from "@radix-ui/react-dialog";
9
- import { AlertCircle, AlertTriangle, Check, CheckCircle2, ChevronDown, ChevronUp, FileText, Info, Loader2, RefreshCw, Upload, X } from "lucide-react";
10
- import * as SelectPrimitive from "@radix-ui/react-select";
11
- import * as ProgressPrimitive from "@radix-ui/react-progress";
12
- import * as SwitchPrimitives from "@radix-ui/react-switch";
13
- import * as LabelPrimitive from "@radix-ui/react-label";
14
- import { Logo, TangleKnot } from "@tangle-network/brand";
15
- //#region src/primitives/dialog.tsx
16
- const Dialog = DialogPrimitive.Root;
17
- const DialogTrigger = DialogPrimitive.Trigger;
18
- const DialogPortal = DialogPrimitive.Portal;
19
- const DialogClose = DialogPrimitive.Close;
20
- const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Overlay, {
21
- ref,
22
- className: cn("fixed inset-0 z-50 bg-black/40", "data-[state=closed]:animate-out data-[state=open]:animate-in", "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", className),
23
- ...props
24
- }));
25
- DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
26
- const DialogContent = React.forwardRef(({ className, children, variant = "default", ...props }, ref) => {
27
- return /* @__PURE__ */ jsxs(DialogPortal, { children: [/* @__PURE__ */ jsx(DialogOverlay, {}), /* @__PURE__ */ jsxs(DialogPrimitive.Content, {
28
- ref,
29
- className: cn("fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%]", "gap-4 rounded-lg border bg-card p-6 shadow-lg duration-200", "data-[state=closed]:animate-out data-[state=open]:animate-in", "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", "data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%]", "data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]", {
30
- default: "border-border",
31
- sandbox: "border-[var(--border-accent)] shadow-[var(--shadow-accent)]"
32
- }[variant], className),
33
- ...props,
34
- children: [children, /* @__PURE__ */ jsxs(DialogPrimitive.Close, {
35
- className: cn("absolute top-4 right-4 rounded-sm opacity-70 transition-[opacity,box-shadow] hover:opacity-100 focus-visible:opacity-100 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground", focusRing),
36
- children: [/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
37
- className: "sr-only",
38
- children: "Close"
39
- })]
40
- })]
41
- })] });
42
- });
43
- DialogContent.displayName = DialogPrimitive.Content.displayName;
44
- const DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
45
- className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className),
46
- ...props
47
- });
48
- DialogHeader.displayName = "DialogHeader";
49
- const DialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
50
- className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className),
51
- ...props
52
- });
53
- DialogFooter.displayName = "DialogFooter";
54
- const DialogTitle = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Title, {
55
- ref,
56
- className: cn("font-semibold text-lg leading-none tracking-tight", className),
57
- ...props
58
- }));
59
- DialogTitle.displayName = DialogPrimitive.Title.displayName;
60
- const DialogDescription = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Description, {
61
- ref,
62
- className: cn("text-muted-foreground text-sm", className),
63
- ...props
64
- }));
65
- DialogDescription.displayName = DialogPrimitive.Description.displayName;
66
- //#endregion
67
- //#region src/primitives/input.tsx
68
- 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), {
69
- variants: {
70
- variant: {
71
- default: "",
72
- sandbox: "",
73
- error: focusFieldInvalid
74
- },
75
- size: {
76
- default: "h-11",
77
- sm: "h-9 px-3",
78
- lg: "h-12 px-5"
79
- }
80
- },
81
- defaultVariants: {
82
- variant: "default",
83
- size: "default"
84
- }
85
- });
86
- const Input = React.forwardRef(({ className, type, variant, size, label, error, hint, id, ...props }, ref) => {
87
- const inputId = id ?? label?.toLowerCase().replace(/\s+/g, "-");
88
- const input = /* @__PURE__ */ jsx("input", {
89
- type,
90
- id: inputId,
91
- className: cn(inputVariants({
92
- variant: error ? "error" : variant,
93
- size,
94
- className
95
- })),
96
- ref,
97
- ...props
98
- });
99
- if (!label && !error && !hint) return input;
100
- return /* @__PURE__ */ jsxs("div", {
101
- className: "w-full space-y-1.5",
102
- children: [
103
- label && /* @__PURE__ */ jsx("label", {
104
- htmlFor: inputId,
105
- className: "block font-medium text-foreground text-sm",
106
- children: label
107
- }),
108
- input,
109
- error && /* @__PURE__ */ jsx("p", {
110
- className: "text-[var(--surface-danger-text)] text-sm font-medium",
111
- children: error
112
- }),
113
- hint && !error && /* @__PURE__ */ jsx("p", {
114
- className: "text-[var(--text-dim)] text-sm",
115
- children: hint
116
- })
117
- ]
118
- });
119
- });
120
- Input.displayName = "Input";
121
- const Textarea = React.forwardRef(({ className, variant: _variant, label, error, hint, id, ...props }, ref) => {
122
- const textareaId = id ?? label?.toLowerCase().replace(/\s+/g, "-");
123
- const textarea = /* @__PURE__ */ jsx("textarea", {
124
- id: textareaId,
125
- 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),
126
- ref,
127
- ...props
128
- });
129
- if (!label && !error && !hint) return textarea;
130
- return /* @__PURE__ */ jsxs("div", {
131
- className: "w-full space-y-1.5",
132
- children: [
133
- label && /* @__PURE__ */ jsx("label", {
134
- htmlFor: textareaId,
135
- className: "block font-medium text-muted-foreground text-sm",
136
- children: label
137
- }),
138
- textarea,
139
- error && /* @__PURE__ */ jsx("p", {
140
- className: "text-[var(--surface-danger-text)] text-sm",
141
- children: error
142
- }),
143
- hint && !error && /* @__PURE__ */ jsx("p", {
144
- className: "text-[var(--text-dim)] text-sm",
145
- children: hint
146
- })
147
- ]
148
- });
149
- });
150
- Textarea.displayName = "Textarea";
151
- //#endregion
152
- //#region src/primitives/select.tsx
153
- const Select = SelectPrimitive.Root;
154
- const SelectGroup = SelectPrimitive.Group;
155
- const SelectValue = SelectPrimitive.Value;
156
- const SelectTrigger = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(SelectPrimitive.Trigger, {
157
- ref,
158
- className: cn("flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border bg-card px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1", focusField, className),
159
- ...props,
160
- children: [children, /* @__PURE__ */ jsx(SelectPrimitive.Icon, {
161
- asChild: true,
162
- children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 opacity-50" })
163
- })]
164
- }));
165
- SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
166
- const SelectScrollUpButton = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.ScrollUpButton, {
167
- ref,
168
- className: cn("flex cursor-default items-center justify-center py-1", className),
169
- ...props,
170
- children: /* @__PURE__ */ jsx(ChevronUp, { className: "h-4 w-4" })
171
- }));
172
- SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
173
- const SelectScrollDownButton = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.ScrollDownButton, {
174
- ref,
175
- className: cn("flex cursor-default items-center justify-center py-1", className),
176
- ...props,
177
- children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" })
178
- }));
179
- SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
180
- const SelectContent = React.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(SelectPrimitive.Content, {
181
- ref,
182
- className: cn("data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border border-border bg-card text-foreground shadow-[var(--shadow-card)] data-[state=closed]:animate-out data-[state=open]:animate-in", position === "popper" && "data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=bottom]:translate-y-1 data-[side=top]:-translate-y-1", className),
183
- position,
184
- ...props,
185
- children: [
186
- /* @__PURE__ */ jsx(SelectScrollUpButton, {}),
187
- /* @__PURE__ */ jsx(SelectPrimitive.Viewport, {
188
- className: cn("p-1", position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"),
189
- children
190
- }),
191
- /* @__PURE__ */ jsx(SelectScrollDownButton, {})
192
- ]
193
- }) }));
194
- SelectContent.displayName = SelectPrimitive.Content.displayName;
195
- const SelectLabel = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Label, {
196
- ref,
197
- className: cn("px-2 py-1.5 font-semibold text-sm", className),
198
- ...props
199
- }));
200
- SelectLabel.displayName = SelectPrimitive.Label.displayName;
201
- const SelectItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(SelectPrimitive.Item, {
202
- ref,
203
- className: cn("relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pr-8 pl-2 text-sm outline-none focus:bg-muted/50 focus:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", className),
204
- ...props,
205
- children: [/* @__PURE__ */ jsx("span", {
206
- className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center",
207
- children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) })
208
- }), /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })]
209
- }));
210
- SelectItem.displayName = SelectPrimitive.Item.displayName;
211
- const SelectSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Separator, {
212
- ref,
213
- className: cn("-mx-1 my-1 h-px bg-border", className),
214
- ...props
215
- }));
216
- SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
217
- //#endregion
218
- //#region src/primitives/segmented-control.tsx
219
- function SegmentedControl({ value, onValueChange, options, variant = "row", className, ...rest }) {
220
- if (typeof process !== "undefined" && process?.env?.NODE_ENV !== "production" && !rest["aria-label"] && !rest["aria-labelledby"]) console.warn("[SegmentedControl] role=\"radiogroup\" requires either aria-label or aria-labelledby for accessibility.");
221
- const optionRefs = React.useRef(/* @__PURE__ */ new Map());
222
- const hasMatch = options.some((o) => o.value === value);
223
- const handleKeyDown = (e) => {
224
- if (options.length === 0) return;
225
- let idx = options.findIndex((o) => o.value === value);
226
- if (idx === -1) idx = 0;
227
- let next;
228
- if (e.key === "ArrowRight" || e.key === "ArrowDown") next = (idx + 1) % options.length;
229
- else if (e.key === "ArrowLeft" || e.key === "ArrowUp") next = (idx - 1 + options.length) % options.length;
230
- else if (e.key === "Home") next = 0;
231
- else if (e.key === "End") next = options.length - 1;
232
- if (next !== void 0) {
233
- e.preventDefault();
234
- if (options[next].value !== value) onValueChange(options[next].value);
235
- optionRefs.current.get(options[next].value)?.focus();
236
- }
237
- };
238
- return /* @__PURE__ */ jsx("div", {
239
- role: "radiogroup",
240
- id: rest.id,
241
- "aria-label": rest["aria-label"],
242
- "aria-labelledby": rest["aria-labelledby"],
243
- onKeyDown: handleKeyDown,
244
- className: cn("flex gap-1", variant === "row" && "flex-wrap items-center rounded-lg border border-border bg-card p-1", variant === "tabs" && "flex-nowrap items-end border-b border-border pb-0 overflow-x-auto", className),
245
- children: options.map((option, i) => {
246
- const active = option.value === value;
247
- return /* @__PURE__ */ jsxs("button", {
248
- ref: (el) => {
249
- if (el) optionRefs.current.set(option.value, el);
250
- else optionRefs.current.delete(option.value);
251
- },
252
- type: "button",
253
- role: "radio",
254
- "aria-checked": active,
255
- tabIndex: active || !hasMatch && i === 0 ? 0 : -1,
256
- onClick: () => {
257
- if (!active) onValueChange(option.value);
258
- },
259
- className: cn("relative inline-flex items-center gap-2 whitespace-nowrap text-sm transition-[color,background-color,border-color,box-shadow]", variant === "row" && ["rounded-md px-3 py-1.5", focusRing], variant === "tabs" && ["rounded-none border-b-2 -mb-px px-4 py-2", focusRingInset], active ? variant === "row" ? "border border-transparent bg-[var(--accent-surface)] text-[var(--accent-text)] font-semibold" : "border-[var(--accent-text)] text-[var(--accent-text)] font-semibold" : variant === "row" ? "border border-transparent text-muted-foreground hover:text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"),
260
- children: [/* @__PURE__ */ jsx("span", { children: option.label }), option.adornment && /* @__PURE__ */ jsx("span", {
261
- className: cn("text-xs", active ? "text-[var(--accent-text)]/80" : "text-muted-foreground"),
262
- children: option.adornment
263
- })]
264
- }, option.value);
265
- })
266
- });
267
- }
268
- //#endregion
269
- //#region src/primitives/progress.tsx
270
- const Progress = React.forwardRef(({ className, value, variant = "default", showValue = false, ...props }, ref) => {
271
- const indicatorVariants = {
272
- default: "bg-primary",
273
- sandbox: "bg-[image:var(--accent-gradient-strong)]"
274
- };
275
- return /* @__PURE__ */ jsxs("div", {
276
- className: "relative",
277
- children: [/* @__PURE__ */ jsx(ProgressPrimitive.Root, {
278
- ref,
279
- className: cn("relative h-2 w-full overflow-hidden rounded-full bg-muted", className),
280
- ...props,
281
- children: /* @__PURE__ */ jsx(ProgressPrimitive.Indicator, {
282
- className: cn("h-full w-full flex-1 transition-all duration-300 ease-out", indicatorVariants[variant]),
283
- style: { transform: `translateX(-${100 - (value || 0)}%)` }
284
- })
285
- }), showValue && /* @__PURE__ */ jsxs("span", {
286
- className: "absolute -top-6 right-0 text-muted-foreground text-xs",
287
- children: [value, "%"]
288
- })]
289
- });
290
- });
291
- Progress.displayName = ProgressPrimitive.Root.displayName;
292
- //#endregion
293
- //#region src/primitives/switch.tsx
294
- const Switch = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(SwitchPrimitives.Root, {
295
- className: cn("peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-[background-color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input", focusRing, className),
296
- ...props,
297
- ref,
298
- children: /* @__PURE__ */ jsx(SwitchPrimitives.Thumb, { className: cn("pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0") })
299
- }));
300
- Switch.displayName = SwitchPrimitives.Root.displayName;
301
- //#endregion
302
- //#region src/primitives/skeleton.tsx
303
- function Skeleton({ className, ...props }) {
304
- return /* @__PURE__ */ jsx("div", {
305
- className: cn("animate-pulse rounded-lg bg-muted/50", className),
306
- ...props
307
- });
308
- }
309
- function SkeletonCard({ className }) {
310
- return /* @__PURE__ */ jsxs("div", {
311
- className: cn("space-y-4 rounded-xl border border-border bg-card p-6", className),
312
- children: [
313
- /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-3/4" }),
314
- /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/2" }),
315
- /* @__PURE__ */ jsxs("div", {
316
- className: "space-y-2 pt-4",
317
- children: [
318
- /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-full" }),
319
- /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-5/6" }),
320
- /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-4/6" })
321
- ]
322
- })
323
- ]
324
- });
325
- }
326
- function SkeletonTable({ rows = 5 }) {
327
- return /* @__PURE__ */ jsxs("div", {
328
- className: "space-y-3",
329
- children: [/* @__PURE__ */ jsxs("div", {
330
- className: "flex gap-4 border-border border-b pb-2",
331
- children: [
332
- /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/4" }),
333
- /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/4" }),
334
- /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/4" }),
335
- /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/4" })
336
- ]
337
- }), Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsxs("div", {
338
- className: "flex gap-4",
339
- children: [
340
- /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/4" }),
341
- /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/4" }),
342
- /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/4" }),
343
- /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/4" })
344
- ]
345
- }, i))]
346
- });
347
- }
348
- //#endregion
349
- //#region src/primitives/toast.tsx
350
- const toastVariants = cva("pointer-events-auto relative flex w-full items-center justify-between gap-3 overflow-hidden rounded-lg border p-4 shadow-lg transition-all", {
351
- variants: { variant: {
352
- default: "border-border bg-background text-foreground",
353
- success: "border-[var(--surface-success-border)] bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]",
354
- error: "border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)]",
355
- warning: "border-[var(--surface-warning-border)] bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)]",
356
- info: "border-[var(--surface-info-border)] bg-[var(--surface-info-bg)] text-[var(--surface-info-text)]"
357
- } },
358
- defaultVariants: { variant: "default" }
359
- });
360
- const icons = {
361
- success: CheckCircle2,
362
- error: AlertCircle,
363
- warning: AlertTriangle,
364
- info: Info,
365
- default: Info
366
- };
367
- function ToastComponent({ id, title, description, variant = "default", onDismiss }) {
368
- const Icon = icons[variant];
369
- return /* @__PURE__ */ jsxs("div", {
370
- className: cn(toastVariants({ variant })),
371
- role: "alert",
372
- "aria-live": "polite",
373
- children: [/* @__PURE__ */ jsxs("div", {
374
- className: "flex items-start gap-3",
375
- children: [/* @__PURE__ */ jsx(Icon, {
376
- className: "h-5 w-5 shrink-0",
377
- "aria-hidden": "true"
378
- }), /* @__PURE__ */ jsxs("div", {
379
- className: "flex-1",
380
- children: [/* @__PURE__ */ jsx("p", {
381
- className: "font-medium text-sm",
382
- children: title
383
- }), description && /* @__PURE__ */ jsx("p", {
384
- className: "mt-1 text-sm opacity-80",
385
- children: description
386
- })]
387
- })]
388
- }), /* @__PURE__ */ jsx("button", {
389
- type: "button",
390
- onClick: () => onDismiss(id),
391
- className: cn("shrink-0 rounded-md p-1 opacity-70 transition-[opacity,box-shadow] hover:opacity-100 focus-visible:opacity-100", focusRing),
392
- "aria-label": "Dismiss notification",
393
- children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
394
- })]
395
- });
396
- }
397
- function ToastContainer({ toasts, onDismiss }) {
398
- return /* @__PURE__ */ jsx("div", {
399
- role: "region",
400
- className: "fixed right-4 bottom-4 z-50 flex max-w-md flex-col gap-2",
401
- "aria-label": "Notifications",
402
- children: toasts.map((toast) => /* @__PURE__ */ jsx(ToastComponent, {
403
- ...toast,
404
- onDismiss
405
- }, toast.id))
406
- });
407
- }
408
- const ToastContext = React.createContext(null);
409
- function ToastProvider({ children }) {
410
- const [toasts, setToasts] = React.useState([]);
411
- const dismiss = React.useCallback((id) => {
412
- setToasts((prev) => prev.filter((t) => t.id !== id));
413
- }, []);
414
- const toast = React.useCallback((input) => {
415
- const id = Math.random().toString(36).slice(2);
416
- const newToast = {
417
- id,
418
- ...input
419
- };
420
- setToasts((prev) => [...prev, newToast]);
421
- const duration = input.duration ?? 5e3;
422
- if (duration > 0) setTimeout(() => dismiss(id), duration);
423
- }, [dismiss]);
424
- const success = React.useCallback((title, description) => {
425
- toast({
426
- title,
427
- description,
428
- variant: "success"
429
- });
430
- }, [toast]);
431
- const error = React.useCallback((title, description) => {
432
- toast({
433
- title,
434
- description,
435
- variant: "error"
436
- });
437
- }, [toast]);
438
- const warning = React.useCallback((title, description) => {
439
- toast({
440
- title,
441
- description,
442
- variant: "warning"
443
- });
444
- }, [toast]);
445
- const info = React.useCallback((title, description) => {
446
- toast({
447
- title,
448
- description,
449
- variant: "info"
450
- });
451
- }, [toast]);
452
- const value = React.useMemo(() => ({
453
- toasts,
454
- toast,
455
- success,
456
- error,
457
- warning,
458
- info,
459
- dismiss
460
- }), [
461
- toasts,
462
- toast,
463
- success,
464
- error,
465
- warning,
466
- info,
467
- dismiss
468
- ]);
469
- return /* @__PURE__ */ jsxs(ToastContext.Provider, {
470
- value,
471
- children: [children, /* @__PURE__ */ jsx(ToastContainer, {
472
- toasts,
473
- onDismiss: dismiss
474
- })]
475
- });
476
- }
477
- function useToast() {
478
- const context = React.useContext(ToastContext);
479
- if (!context) throw new Error("useToast must be used within a ToastProvider");
480
- return context;
481
- }
482
- //#endregion
483
- //#region src/primitives/label.tsx
484
- const labelVariants = cva("font-medium text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70");
485
- const Label = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(LabelPrimitive.Root, {
486
- ref,
487
- className: cn(labelVariants(), className),
488
- ...props
489
- }));
490
- Label.displayName = LabelPrimitive.Root.displayName;
491
- //#endregion
492
- //#region src/primitives/empty-state.tsx
493
- const EmptyState = React.forwardRef(({ className, icon, title, description, action, ...props }, ref) => {
494
- return /* @__PURE__ */ jsxs("div", {
495
- ref,
496
- className: cn("flex flex-col items-center justify-center px-4 py-16 text-center", className),
497
- ...props,
498
- children: [
499
- icon && /* @__PURE__ */ jsx("div", {
500
- className: "mb-4 rounded-full bg-muted p-4 text-muted-foreground",
501
- children: icon
502
- }),
503
- /* @__PURE__ */ jsx("h3", {
504
- className: "font-semibold text-lg",
505
- children: title
506
- }),
507
- description && /* @__PURE__ */ jsx("p", {
508
- className: "mt-2 max-w-sm text-muted-foreground text-sm",
509
- children: description
510
- }),
511
- action && /* @__PURE__ */ jsx("div", {
512
- className: "mt-6",
513
- children: action
514
- })
515
- ]
516
- });
517
- });
518
- EmptyState.displayName = "EmptyState";
519
- //#endregion
520
- //#region src/primitives/stat-card.tsx
521
- const StatCard = React.forwardRef(({ className, variant = "default", title, value, subtitle, icon, trend, ...props }, ref) => {
522
- const iconColors = {
523
- default: "text-muted-foreground",
524
- sandbox: "text-[var(--accent-text)]"
525
- };
526
- const trendColors = {
527
- positive: "text-[var(--surface-success-text)]",
528
- negative: "text-[var(--surface-danger-text)]",
529
- neutral: "text-muted-foreground"
530
- };
531
- const trendStatus = trend ? trend.value > 0 ? "positive" : trend.value < 0 ? "negative" : "neutral" : null;
532
- return /* @__PURE__ */ jsx(Card, {
533
- ref,
534
- variant,
535
- className: cn("p-6", className),
536
- ...props,
537
- children: /* @__PURE__ */ jsxs("div", {
538
- className: "flex items-start justify-between",
539
- children: [/* @__PURE__ */ jsxs("div", {
540
- className: "space-y-1",
541
- children: [
542
- /* @__PURE__ */ jsx("p", {
543
- className: "text-muted-foreground text-sm",
544
- children: title
545
- }),
546
- /* @__PURE__ */ jsx("p", {
547
- className: "font-bold text-3xl tracking-tight",
548
- children: value
549
- }),
550
- subtitle && /* @__PURE__ */ jsx("p", {
551
- className: "text-[var(--text-dim)] text-xs",
552
- children: subtitle
553
- }),
554
- trend && trendStatus && /* @__PURE__ */ jsxs("div", {
555
- className: cn("flex items-center gap-1 text-sm", trendColors[trendStatus]),
556
- children: [
557
- trend.value > 0 ? "↑" : trend.value < 0 ? "↓" : "→",
558
- /* @__PURE__ */ jsxs("span", { children: [Math.abs(trend.value), "%"] }),
559
- trend.label && /* @__PURE__ */ jsx("span", {
560
- className: "text-muted-foreground",
561
- children: trend.label
562
- })
563
- ]
564
- })
565
- ]
566
- }), icon && /* @__PURE__ */ jsx("div", {
567
- className: cn("rounded-lg bg-muted/50 p-2", variant === "sandbox" && "bg-[var(--accent-surface-soft)]", iconColors[variant]),
568
- children: icon
569
- })]
570
- })
571
- });
572
- });
573
- StatCard.displayName = "StatCard";
574
- //#endregion
575
- //#region src/primitives/terminal-display.tsx
576
- const TerminalDisplay = React.forwardRef(({ className, variant = "default", title = "Terminal", showHeader = true, autoScroll = true, maxHeight = "400px", children, ...props }, ref) => {
577
- const containerRef = useRef(null);
578
- useEffect(() => {
579
- if (autoScroll && containerRef.current) containerRef.current.scrollTop = containerRef.current.scrollHeight;
580
- }, [autoScroll]);
581
- return /* @__PURE__ */ jsxs("div", {
582
- ref,
583
- className: cn("overflow-hidden rounded-xl border bg-background font-mono text-sm", {
584
- default: "border-border",
585
- sandbox: "border-border shadow-[var(--shadow-accent)]"
586
- }[variant], className),
587
- ...props,
588
- children: [showHeader && /* @__PURE__ */ jsx("div", {
589
- className: "flex items-center border-b border-border bg-card px-4 py-3",
590
- children: /* @__PURE__ */ jsx("span", {
591
- className: "text-muted-foreground text-xs",
592
- children: title
593
- })
594
- }), /* @__PURE__ */ jsx("div", {
595
- ref: containerRef,
596
- className: "overflow-auto p-4",
597
- style: { maxHeight },
598
- children
599
- })]
600
- });
601
- });
602
- TerminalDisplay.displayName = "TerminalDisplay";
603
- const TerminalLine = React.forwardRef(({ className, type = "output", prompt = "$", timestamp, children, ...props }, ref) => {
604
- return /* @__PURE__ */ jsxs("div", {
605
- ref,
606
- className: cn("flex items-start gap-2 py-0.5 leading-relaxed", {
607
- input: "text-foreground",
608
- output: "text-foreground",
609
- error: "text-[var(--surface-danger-text)]",
610
- success: "text-[var(--surface-success-text)]",
611
- info: "text-[var(--surface-info-text)]",
612
- thinking: "text-[var(--surface-warning-text)] animate-pulse",
613
- command: "text-foreground",
614
- warning: "text-[var(--surface-warning-text)]"
615
- }[type], className),
616
- ...props,
617
- children: [
618
- (type === "input" || type === "command") && /* @__PURE__ */ jsx("span", {
619
- className: "shrink-0 select-none text-[var(--surface-success-text)]",
620
- children: prompt
621
- }),
622
- type === "thinking" && /* @__PURE__ */ jsx("span", {
623
- className: "shrink-0 select-none",
624
- children: "..."
625
- }),
626
- timestamp && /* @__PURE__ */ jsxs("span", {
627
- className: "shrink-0 select-none text-[var(--text-dim)]",
628
- children: [
629
- "[",
630
- timestamp,
631
- "]"
632
- ]
633
- }),
634
- /* @__PURE__ */ jsx("span", {
635
- className: "whitespace-pre-wrap break-all",
636
- children
637
- })
638
- ]
639
- });
640
- });
641
- TerminalLine.displayName = "TerminalLine";
642
- const TerminalCursor = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("span", {
643
- ref,
644
- className: cn("ml-0.5 inline-block h-4 w-2 animate-pulse bg-foreground", className),
645
- ...props
646
- }));
647
- TerminalCursor.displayName = "TerminalCursor";
648
- const TerminalInput = React.forwardRef(({ className, onSubmit, variant: _variant, ...props }, ref) => {
649
- const [value, setValue] = React.useState("");
650
- const handleKeyDown = (e) => {
651
- if (e.key === "Enter" && value.trim() && onSubmit) {
652
- onSubmit(value.trim());
653
- setValue("");
654
- }
655
- };
656
- return /* @__PURE__ */ jsxs("div", {
657
- className: cn("flex items-center rounded-lg border bg-background px-4 py-2.5 font-mono text-sm", focusFieldWithin, className),
658
- children: [
659
- /* @__PURE__ */ jsx("span", {
660
- className: "mr-2 select-none text-[var(--surface-success-text)]",
661
- children: "$"
662
- }),
663
- /* @__PURE__ */ jsx("input", {
664
- ref,
665
- type: "text",
666
- value,
667
- onChange: (e) => setValue(e.target.value),
668
- onKeyDown: handleKeyDown,
669
- className: "flex-1 bg-transparent text-foreground outline-none placeholder:text-muted-foreground",
670
- ...props
671
- }),
672
- /* @__PURE__ */ jsx(TerminalCursor, {})
673
- ]
674
- });
675
- });
676
- TerminalInput.displayName = "TerminalInput";
677
- //#endregion
678
- //#region src/primitives/drop-zone.tsx
679
- /**
680
- * DropZone — full-window drag-and-drop file upload overlay.
681
- *
682
- * Detects when files are dragged over the browser window and shows a
683
- * customizable overlay. Products provide the onDrop handler and optional
684
- * custom overlay content.
685
- *
686
- * Usage:
687
- * <DropZone onDrop={files => uploadToR2(files)} accept=".pdf,.csv">
688
- * <YourApp />
689
- * </DropZone>
690
- */
691
- 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 }) {
692
- const [dragOver, setDragOver] = useState(false);
693
- const counter = useRef(0);
694
- const isAccepted = useCallback((file) => {
695
- if (!accept) return true;
696
- const extensions = accept.split(",").map((ext) => ext.trim().toLowerCase());
697
- const fileName = file.name.toLowerCase();
698
- return extensions.some((ext) => fileName.endsWith(ext));
699
- }, [accept]);
700
- const handleDragEnter = useCallback((e) => {
701
- e.preventDefault();
702
- if (disabled) return;
703
- counter.current++;
704
- if (e.dataTransfer?.types.includes("Files")) setDragOver(true);
705
- }, [disabled]);
706
- const handleDragLeave = useCallback((e) => {
707
- e.preventDefault();
708
- counter.current--;
709
- if (counter.current === 0) setDragOver(false);
710
- }, []);
711
- const handleDragOver = useCallback((e) => {
712
- e.preventDefault();
713
- if (!disabled) e.dataTransfer.dropEffect = "copy";
714
- }, [disabled]);
715
- const handleDrop = useCallback((e) => {
716
- e.preventDefault();
717
- counter.current = 0;
718
- setDragOver(false);
719
- if (disabled) return;
720
- const allFiles = Array.from(e.dataTransfer?.files || []);
721
- const accepted = accept ? allFiles.filter(isAccepted) : allFiles;
722
- if (accepted.length > 0) onDrop(accepted);
723
- }, [
724
- disabled,
725
- accept,
726
- isAccepted,
727
- onDrop
728
- ]);
729
- return /* @__PURE__ */ jsxs("div", {
730
- onDragEnter: handleDragEnter,
731
- onDragLeave: handleDragLeave,
732
- onDragOver: handleDragOver,
733
- onDrop: handleDrop,
734
- className: cn("relative", className),
735
- children: [dragOver && (overlay || /* @__PURE__ */ jsx("div", {
736
- className: "fixed inset-0 z-[100] flex items-center justify-center pointer-events-none bg-background",
737
- children: /* @__PURE__ */ jsxs("div", {
738
- className: "rounded-2xl border-2 border-dashed border-border bg-card p-16 text-center shadow-[var(--shadow-dropdown)] max-w-lg mx-auto",
739
- children: [
740
- /* @__PURE__ */ jsx("div", {
741
- className: "mx-auto mb-6 flex h-20 w-20 items-center justify-center rounded-2xl border border-border bg-[var(--accent-surface-soft)]",
742
- children: typeof icon === "string" ? /* @__PURE__ */ jsxs("svg", {
743
- xmlns: "http://www.w3.org/2000/svg",
744
- viewBox: "0 0 24 24",
745
- fill: "none",
746
- stroke: "currentColor",
747
- strokeWidth: "1.5",
748
- strokeLinecap: "round",
749
- strokeLinejoin: "round",
750
- className: "h-10 w-10 text-[var(--accent-text)]",
751
- children: [
752
- /* @__PURE__ */ jsx("title", { children: "Upload" }),
753
- /* @__PURE__ */ jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
754
- /* @__PURE__ */ jsx("polyline", { points: "17 8 12 3 7 8" }),
755
- /* @__PURE__ */ jsx("line", {
756
- x1: "12",
757
- x2: "12",
758
- y1: "3",
759
- y2: "15"
760
- })
761
- ]
762
- }) : icon
763
- }),
764
- /* @__PURE__ */ jsx("h2", {
765
- className: "text-2xl font-bold text-foreground",
766
- children: title
767
- }),
768
- /* @__PURE__ */ jsx("p", {
769
- className: "mt-2 text-sm text-muted-foreground",
770
- children: description
771
- })
772
- ]
773
- })
774
- })), children]
775
- });
776
- }
777
- //#endregion
778
- //#region src/primitives/upload-progress.tsx
779
- /**
780
- * UploadProgress — file upload status indicators.
781
- *
782
- * Shows a list of files being uploaded with progress bars,
783
- * completion checkmarks, and error states.
784
- */
785
- function formatSize(bytes) {
786
- if (bytes < 1024) return `${bytes}B`;
787
- if (bytes < 1048576) return `${(bytes / 1024).toFixed(0)}KB`;
788
- return `${(bytes / 1048576).toFixed(1)}MB`;
789
- }
790
- function UploadProgress({ files, onRemove, onRetry, className }) {
791
- if (files.length === 0) return null;
792
- return /* @__PURE__ */ jsx("div", {
793
- className: cn("space-y-2", className),
794
- children: files.map((file) => /* @__PURE__ */ jsxs("div", {
795
- className: cn("flex items-center gap-3 rounded-lg border px-3 py-2 text-sm", file.status === "error" ? "border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)]" : file.status === "complete" ? "border-[var(--surface-success-border)] bg-[var(--surface-success-bg)]" : "border-border bg-card"),
796
- children: [
797
- file.status === "complete" && /* @__PURE__ */ jsx(CheckCircle2, { className: "h-4 w-4 shrink-0 text-[var(--surface-success-text)]" }),
798
- file.status === "error" && /* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4 shrink-0 text-[var(--surface-danger-text)]" }),
799
- file.status === "uploading" && /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 shrink-0 animate-spin text-primary" }),
800
- file.status === "pending" && /* @__PURE__ */ jsx(FileText, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
801
- /* @__PURE__ */ jsxs("div", {
802
- className: "min-w-0 flex-1",
803
- children: [
804
- /* @__PURE__ */ jsxs("div", {
805
- className: "flex items-center gap-2",
806
- children: [/* @__PURE__ */ jsx("span", {
807
- className: "truncate font-medium text-foreground",
808
- children: file.name
809
- }), /* @__PURE__ */ jsx("span", {
810
- className: "shrink-0 text-xs text-muted-foreground",
811
- children: formatSize(file.size)
812
- })]
813
- }),
814
- file.status === "uploading" && file.progress !== void 0 && /* @__PURE__ */ jsx("div", {
815
- className: "mt-1 h-1 w-full overflow-hidden rounded-full bg-muted/50",
816
- children: /* @__PURE__ */ jsx("div", {
817
- className: "h-full rounded-full bg-primary transition-all",
818
- style: { width: `${file.progress}%` }
819
- })
820
- }),
821
- file.status === "error" && file.error && /* @__PURE__ */ jsx("p", {
822
- className: "mt-0.5 text-xs text-[var(--surface-danger-text)]",
823
- children: file.error
824
- })
825
- ]
826
- }),
827
- /* @__PURE__ */ jsxs("div", {
828
- className: "flex shrink-0 items-center gap-1",
829
- children: [file.status === "error" && onRetry && /* @__PURE__ */ jsx("button", {
830
- type: "button",
831
- onClick: () => onRetry(file.id),
832
- className: "rounded p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
833
- children: /* @__PURE__ */ jsx(RefreshCw, { className: "h-3.5 w-3.5" })
834
- }), onRemove && /* @__PURE__ */ jsx("button", {
835
- type: "button",
836
- onClick: () => onRemove(file.id),
837
- className: "rounded p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
838
- children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5" })
839
- })]
840
- })
841
- ]
842
- }, file.id))
843
- });
844
- }
845
- //#endregion
846
- //#region src/primitives/sidebar-drop-zone.tsx
847
- /**
848
- * SidebarDropZone — compact scoped drop zone for sidebar panels and narrow containers.
849
- *
850
- * Unlike the full-window DropZone, this renders as an inline element
851
- * that can be placed inside sidebar panels, file trees, or any container.
852
- * Shows a subtle drop target when files are dragged over it.
853
- *
854
- * Usage:
855
- * <SidebarPanelContent>
856
- * <FileTree ... />
857
- * <SidebarDropZone onDrop={uploadToWorkspace} title="Upload to workspace" />
858
- * </SidebarPanelContent>
859
- */
860
- function SidebarDropZone({ onDrop, accept, disabled, title = "Drop files here", description, icon, persistent = false, className }) {
861
- const [dragOver, setDragOver] = useState(false);
862
- const counter = useRef(0);
863
- const isAccepted = useCallback((file) => {
864
- if (!accept) return true;
865
- const extensions = accept.split(",").map((ext) => ext.trim().toLowerCase());
866
- const fileName = file.name.toLowerCase();
867
- return extensions.some((ext) => fileName.endsWith(ext));
868
- }, [accept]);
869
- const handleDragEnter = useCallback((e) => {
870
- e.preventDefault();
871
- e.stopPropagation();
872
- if (disabled) return;
873
- counter.current++;
874
- if (e.dataTransfer?.types.includes("Files")) setDragOver(true);
875
- }, [disabled]);
876
- const handleDragLeave = useCallback((e) => {
877
- e.preventDefault();
878
- e.stopPropagation();
879
- counter.current--;
880
- if (counter.current === 0) setDragOver(false);
881
- }, []);
882
- const handleDragOver = useCallback((e) => {
883
- e.preventDefault();
884
- e.stopPropagation();
885
- if (!disabled) e.dataTransfer.dropEffect = "copy";
886
- }, [disabled]);
887
- const handleDrop = useCallback((e) => {
888
- e.preventDefault();
889
- e.stopPropagation();
890
- counter.current = 0;
891
- setDragOver(false);
892
- if (disabled) return;
893
- const allFiles = Array.from(e.dataTransfer?.files || []);
894
- const accepted = accept ? allFiles.filter(isAccepted) : allFiles;
895
- if (accepted.length > 0) onDrop(accepted);
896
- }, [
897
- disabled,
898
- accept,
899
- isAccepted,
900
- onDrop
901
- ]);
902
- const isVisible = persistent || dragOver;
903
- return /* @__PURE__ */ jsx("div", {
904
- onDragEnter: handleDragEnter,
905
- onDragLeave: handleDragLeave,
906
- onDragOver: handleDragOver,
907
- onDrop: handleDrop,
908
- className: cn("rounded-lg border-2 border-dashed transition-all duration-150", isVisible ? "p-4" : "p-0 border-transparent", dragOver ? "border-[var(--brand-cool,hsl(var(--ring)))] bg-[var(--accent-surface-soft)]" : persistent ? "border-[var(--border-subtle,hsl(var(--border)))] bg-transparent hover:border-[var(--border-default,hsl(var(--border)))] hover:bg-[var(--bg-hover,hsl(var(--accent)))]" : "", disabled && "opacity-50 pointer-events-none", className),
909
- children: isVisible && /* @__PURE__ */ jsxs("div", {
910
- className: "flex flex-col items-center gap-2 text-center",
911
- children: [
912
- /* @__PURE__ */ jsx("div", {
913
- className: cn("flex h-8 w-8 items-center justify-center rounded-lg transition-colors", dragOver ? "bg-[var(--brand-cool,hsl(var(--primary)))]/15 text-[var(--brand-cool,hsl(var(--primary)))]" : "text-[var(--text-muted,hsl(var(--muted-foreground)))]"),
914
- children: icon ?? /* @__PURE__ */ jsx(Upload, { className: "h-4 w-4" })
915
- }),
916
- /* @__PURE__ */ jsx("p", {
917
- className: cn("text-xs font-medium", dragOver ? "text-[var(--text-primary,hsl(var(--foreground)))]" : "text-[var(--text-muted,hsl(var(--muted-foreground)))]"),
918
- children: title
919
- }),
920
- description && /* @__PURE__ */ jsx("p", {
921
- className: "text-[10px] text-[var(--text-muted,hsl(var(--muted-foreground)))]",
922
- children: description
923
- })
924
- ]
925
- })
926
- });
927
- }
928
- //#endregion
929
- //#region src/primitives/code-block.tsx
930
- function InlineCode({ className, children, ...props }) {
931
- return /* @__PURE__ */ jsx("code", {
932
- className: cn("rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-[0.85em] text-foreground", className),
933
- ...props,
934
- children
935
- });
936
- }
937
- //#endregion
938
- //#region src/primitives/theme-toggle.tsx
939
- function getSystemTheme() {
940
- return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
941
- }
942
- function applyTheme(theme) {
943
- const resolved = theme === "system" ? getSystemTheme() : theme;
944
- document.documentElement.classList.toggle("dark", resolved === "dark");
945
- }
946
- function useTheme() {
947
- const [theme, setThemeState] = useState(() => {
948
- if (typeof window === "undefined") return "system";
949
- return localStorage.getItem("theme") ?? "system";
950
- });
951
- const setTheme = useCallback((next) => {
952
- setThemeState(next);
953
- if (next === "system") localStorage.removeItem("theme");
954
- else localStorage.setItem("theme", next);
955
- applyTheme(next);
956
- }, []);
957
- useEffect(() => {
958
- applyTheme(theme);
959
- if (theme !== "system") return;
960
- const mq = window.matchMedia("(prefers-color-scheme: dark)");
961
- const handler = () => applyTheme("system");
962
- mq.addEventListener("change", handler);
963
- return () => mq.removeEventListener("change", handler);
964
- }, [theme]);
965
- return {
966
- theme,
967
- setTheme
968
- };
969
- }
970
- const iconClass = "h-4 w-4";
971
- function SunIcon() {
972
- return /* @__PURE__ */ jsxs("svg", {
973
- xmlns: "http://www.w3.org/2000/svg",
974
- viewBox: "0 0 24 24",
975
- fill: "none",
976
- stroke: "currentColor",
977
- strokeWidth: 2,
978
- strokeLinecap: "round",
979
- strokeLinejoin: "round",
980
- className: iconClass,
981
- children: [/* @__PURE__ */ jsx("circle", {
982
- cx: 12,
983
- cy: 12,
984
- r: 5
985
- }), /* @__PURE__ */ jsx("path", { d: "M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" })]
986
- });
987
- }
988
- function MoonIcon() {
989
- return /* @__PURE__ */ jsx("svg", {
990
- xmlns: "http://www.w3.org/2000/svg",
991
- viewBox: "0 0 24 24",
992
- fill: "none",
993
- stroke: "currentColor",
994
- strokeWidth: 2,
995
- strokeLinecap: "round",
996
- strokeLinejoin: "round",
997
- className: iconClass,
998
- children: /* @__PURE__ */ jsx("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" })
999
- });
1000
- }
1001
- function ThemeToggle() {
1002
- const { theme, setTheme } = useTheme();
1003
- const resolved = theme === "system" ? getSystemTheme() : theme;
1004
- return /* @__PURE__ */ jsx("button", {
1005
- type: "button",
1006
- onClick: () => setTheme(resolved === "dark" ? "light" : "dark"),
1007
- className: "inline-flex items-center justify-center rounded-md p-2 text-muted-foreground hover:bg-accent hover:text-accent-foreground transition-colors",
1008
- "aria-label": `Switch to ${resolved === "dark" ? "light" : "dark"} mode`,
1009
- children: resolved === "dark" ? /* @__PURE__ */ jsx(SunIcon, {}) : /* @__PURE__ */ jsx(MoonIcon, {})
1010
- });
1011
- }
1012
- //#endregion
1013
- //#region src/primitives/page-header.tsx
1014
- const PageHeader = React.forwardRef(({ className, title, description, actions, meta, titleId, level = 1, ...props }, ref) => {
1015
- const Heading = level === 1 ? "h1" : "h2";
1016
- return /* @__PURE__ */ jsxs("header", {
1017
- ref,
1018
- className: cn("mb-6", className),
1019
- ...props,
1020
- children: [/* @__PURE__ */ jsxs("div", {
1021
- className: "flex flex-wrap items-start justify-between gap-x-6 gap-y-3",
1022
- children: [/* @__PURE__ */ jsxs("div", {
1023
- className: "min-w-0",
1024
- children: [/* @__PURE__ */ jsx(Heading, {
1025
- id: titleId,
1026
- className: cn("text-balance font-semibold tracking-tight", level === 1 ? "text-2xl" : "text-lg"),
1027
- children: title
1028
- }), description && /* @__PURE__ */ jsx("p", {
1029
- className: "mt-1 max-w-prose text-muted-foreground text-sm",
1030
- children: description
1031
- })]
1032
- }), actions && /* @__PURE__ */ jsx("div", {
1033
- className: "flex flex-wrap items-center gap-2",
1034
- children: actions
1035
- })]
1036
- }), meta && /* @__PURE__ */ jsx("div", {
1037
- className: "mt-3 flex flex-wrap items-center gap-x-4 gap-y-2 text-[var(--text-dim)] text-xs",
1038
- children: meta
1039
- })]
1040
- });
1041
- });
1042
- PageHeader.displayName = "PageHeader";
1043
- //#endregion
1044
- //#region src/primitives/status-pill.tsx
1045
- const TONE_SURFACE = {
1046
- success: "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)] border-[var(--surface-success-border)]",
1047
- warning: "bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)] border-[var(--surface-warning-border)]",
1048
- danger: "bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)] border-[var(--surface-danger-border)]",
1049
- info: "bg-[var(--surface-info-bg)] text-[var(--surface-info-text)] border-[var(--surface-info-border)]",
1050
- running: "bg-[var(--surface-info-bg)] text-[var(--surface-info-text)] border-[var(--surface-info-border)]",
1051
- neutral: "bg-[var(--surface-neutral-bg)] text-[var(--surface-neutral-text)] border-[var(--surface-neutral-border)]"
1052
- };
1053
- /**
1054
- * The text tier alone, for `bare`. Declared rather than recovered from
1055
- * `TONE_SURFACE` by string search: picking the `text-` class out of that string
1056
- * silently yields `undefined` the moment the triple gains a second `text-`
1057
- * utility, and an undefined class removes the tone from the one channel `bare`
1058
- * has left — the glyph — with nothing to signal that it happened.
1059
- */
1060
- const TONE_TEXT = {
1061
- success: "text-[var(--surface-success-text)]",
1062
- warning: "text-[var(--surface-warning-text)]",
1063
- danger: "text-[var(--surface-danger-text)]",
1064
- info: "text-[var(--surface-info-text)]",
1065
- running: "text-[var(--surface-info-text)]",
1066
- neutral: "text-[var(--surface-neutral-text)]"
1067
- };
1068
- /**
1069
- * One glyph per silhouette. `currentColor` throughout so the mark inherits the
1070
- * tone's text colour and can never drift from the label beside it.
1071
- */
1072
- function ToneGlyph({ tone }) {
1073
- const common = {
1074
- viewBox: "0 0 8 8",
1075
- className: "size-2 shrink-0"
1076
- };
1077
- switch (tone) {
1078
- case "success": return /* @__PURE__ */ jsx("svg", {
1079
- ...common,
1080
- "aria-hidden": "true",
1081
- fill: "currentColor",
1082
- children: /* @__PURE__ */ jsx("circle", {
1083
- cx: "4",
1084
- cy: "4",
1085
- r: "3.25"
1086
- })
1087
- });
1088
- case "danger": return /* @__PURE__ */ jsxs("svg", {
1089
- ...common,
1090
- "aria-hidden": "true",
1091
- fill: "none",
1092
- stroke: "currentColor",
1093
- strokeWidth: "1.5",
1094
- children: [/* @__PURE__ */ jsx("circle", {
1095
- cx: "4",
1096
- cy: "4",
1097
- r: "3.1",
1098
- fill: "currentColor",
1099
- opacity: "0.35"
1100
- }), /* @__PURE__ */ jsx("path", {
1101
- d: "M1.9 6.1 6.1 1.9",
1102
- strokeLinecap: "round"
1103
- })]
1104
- });
1105
- case "warning": return /* @__PURE__ */ jsx("svg", {
1106
- ...common,
1107
- "aria-hidden": "true",
1108
- fill: "currentColor",
1109
- children: /* @__PURE__ */ jsx("path", { d: "M4 0.6 7.7 7.1H0.3z" })
1110
- });
1111
- case "running": return /* @__PURE__ */ jsx("svg", {
1112
- ...common,
1113
- "aria-hidden": "true",
1114
- fill: "none",
1115
- stroke: "currentColor",
1116
- strokeWidth: "1.75",
1117
- children: /* @__PURE__ */ jsx("circle", {
1118
- cx: "4",
1119
- cy: "4",
1120
- r: "2.9"
1121
- })
1122
- });
1123
- case "info": return /* @__PURE__ */ jsx("svg", {
1124
- ...common,
1125
- "aria-hidden": "true",
1126
- fill: "currentColor",
1127
- children: /* @__PURE__ */ jsx("rect", {
1128
- x: "0.9",
1129
- y: "0.9",
1130
- width: "6.2",
1131
- height: "6.2",
1132
- rx: "1.2"
1133
- })
1134
- });
1135
- default: return /* @__PURE__ */ jsx("svg", {
1136
- ...common,
1137
- "aria-hidden": "true",
1138
- fill: "none",
1139
- stroke: "currentColor",
1140
- strokeWidth: "1.75",
1141
- children: /* @__PURE__ */ jsx("path", {
1142
- d: "M1 4h6",
1143
- strokeLinecap: "round"
1144
- })
1145
- });
1146
- }
1147
- }
1148
- const StatusPill = React.forwardRef(({ className, tone, children, bare = false, size = "sm", ...props }, ref) => /* @__PURE__ */ jsxs("span", {
1149
- ref,
1150
- className: cn("inline-flex items-center gap-1.5 whitespace-nowrap rounded-full font-medium", size === "sm" ? "px-2 py-0.5 text-xs" : "px-2.5 py-1 text-sm", bare ? "border border-transparent bg-transparent px-0" : cn("border", TONE_SURFACE[tone]), className),
1151
- ...props,
1152
- children: [/* @__PURE__ */ jsx("span", {
1153
- className: cn("inline-flex", bare && TONE_TEXT[tone]),
1154
- children: /* @__PURE__ */ jsx(ToneGlyph, { tone })
1155
- }), children]
1156
- }));
1157
- StatusPill.displayName = "StatusPill";
1158
- //#endregion
1159
- //#region src/primitives/metric-strip.tsx
1160
- const MetricStrip = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx("dl", {
1161
- ref,
1162
- className: cn("grid grid-cols-2 rounded-[var(--radius-lg)] border border-border bg-card shadow-[var(--shadow-card)] sm:grid-cols-4", className),
1163
- ...props,
1164
- children
1165
- }));
1166
- MetricStrip.displayName = "MetricStrip";
1167
- /**
1168
- * One reading inside a `MetricStrip`.
1169
- *
1170
- * `<dt>` carries the label and `<dd>` the value, so the pair is announced as a
1171
- * described term rather than as two loose strings — the semantic that makes a
1172
- * figure legible without the visual grouping.
1173
- *
1174
- * The value is `tabular-nums`: these sit in a row and change on a timer, and
1175
- * proportional digits make the column jitter every time a 1 becomes an 8.
1176
- */
1177
- const Metric = React.forwardRef(({ className, label, value, hint, attention, ...props }, ref) => /* @__PURE__ */ jsxs("div", {
1178
- ref,
1179
- 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),
1180
- ...props,
1181
- children: [
1182
- /* @__PURE__ */ jsxs("dt", {
1183
- className: "flex items-center gap-2 text-muted-foreground text-sm",
1184
- children: [/* @__PURE__ */ jsx("span", {
1185
- className: "truncate",
1186
- children: label
1187
- }), attention && /* @__PURE__ */ jsx(StatusPill, {
1188
- tone: attention.tone,
1189
- children: attention.label
1190
- })]
1191
- }),
1192
- /* @__PURE__ */ jsx("dd", {
1193
- className: cn("mt-1 truncate font-semibold text-xl tabular-nums tracking-tight lg:text-2xl", attention?.tone === "danger" && "text-[var(--surface-danger-text)]"),
1194
- title: typeof value === "string" ? value : void 0,
1195
- children: value
1196
- }),
1197
- hint && /* @__PURE__ */ jsx("dd", {
1198
- className: "mt-0.5 truncate text-[var(--text-dim)] text-xs",
1199
- title: typeof hint === "string" ? hint : void 0,
1200
- children: hint
1201
- })
1202
- ]
1203
- }));
1204
- Metric.displayName = "Metric";
1205
- //#endregion
1206
- //#region src/primitives/toolbar.tsx
1207
- const Toolbar = React.forwardRef(({ className, search, filters, actions, ...props }, ref) => /* @__PURE__ */ jsxs("div", {
1208
- ref,
1209
- className: cn("mb-4 flex flex-col gap-3 lg:flex-row lg:items-center", className),
1210
- ...props,
1211
- children: [
1212
- search && /* @__PURE__ */ jsx("div", {
1213
- className: "min-w-0 lg:max-w-sm lg:flex-1",
1214
- children: search
1215
- }),
1216
- filters && /* @__PURE__ */ jsx("div", {
1217
- className: "flex min-w-0 items-center gap-2 overflow-x-auto py-1 lg:flex-1",
1218
- children: filters
1219
- }),
1220
- actions && /* @__PURE__ */ jsx("div", {
1221
- className: "flex shrink-0 items-center gap-2 lg:ml-auto",
1222
- children: actions
1223
- })
1224
- ]
1225
- }));
1226
- Toolbar.displayName = "Toolbar";
1227
- const FilterField = React.forwardRef(({ className, label, htmlFor, children, ...props }, ref) => /* @__PURE__ */ jsxs("div", {
1228
- ref,
1229
- className: cn("flex shrink-0 items-center gap-2", className),
1230
- ...props,
1231
- children: [/* @__PURE__ */ jsx("label", {
1232
- htmlFor,
1233
- className: "whitespace-nowrap text-muted-foreground text-xs",
1234
- children: label
1235
- }), children]
1236
- }));
1237
- FilterField.displayName = "FilterField";
1238
- //#endregion
1239
- export { SegmentedControl as A, SelectValue as B, ToastProvider as C, SkeletonTable as D, SkeletonCard as E, SelectLabel as F, DialogContent as G, Textarea as H, SelectScrollDownButton as I, DialogHeader as J, DialogDescription as K, SelectScrollUpButton as L, SelectContent as M, SelectGroup as N, Switch as O, SelectItem as P, DialogTrigger as Q, SelectSeparator as R, ToastContainer as S, Skeleton as T, Dialog as U, Input as V, DialogClose as W, DialogPortal as X, DialogOverlay as Y, DialogTitle as Z, TerminalInput as _, Metric as a, EmptyState as b, PageHeader as c, InlineCode as d, SidebarDropZone as f, TerminalDisplay as g, TerminalCursor as h, Toolbar as i, Select as j, Progress as k, ThemeToggle as l, DropZone as m, TangleKnot as n, MetricStrip as o, UploadProgress as p, DialogFooter as q, FilterField as r, StatusPill as s, Logo as t, useTheme as u, TerminalLine as v, useToast as w, Label as x, StatCard as y, SelectTrigger as z };