@tangle-network/ui 11.11.8 → 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.
Files changed (279) 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/{document-editor-pane-DHM8DDhb.d.ts → editor/editor-provider.d.ts} +10 -47
  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} +22 -47
  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/editor/document-editor-pane.tsx +4 -1
  230. package/src/files/file-artifact-pane.test.tsx +23 -0
  231. package/src/files/file-artifact-pane.tsx +3 -0
  232. package/src/files/rich-file-tree.stories.tsx +1 -1
  233. package/src/files/rich-file-tree.tsx +12 -9
  234. package/src/markdown/code-block.test.tsx +46 -2
  235. package/src/markdown/code-block.tsx +23 -60
  236. package/src/markdown/markdown.test.tsx +3 -2
  237. package/src/primitives/button.stories.tsx +37 -1
  238. package/src/primitives/button.test.tsx +230 -0
  239. package/src/primitives/button.tsx +62 -14
  240. package/src/primitives/card-anatomy.stories.tsx +51 -0
  241. package/src/primitives/card.test.tsx +71 -0
  242. package/src/primitives/card.tsx +25 -13
  243. package/src/primitives/heading.stories.tsx +35 -0
  244. package/src/primitives/heading.test.tsx +56 -0
  245. package/src/primitives/heading.tsx +76 -0
  246. package/src/primitives/index.ts +8 -0
  247. package/src/primitives/input.stories.tsx +28 -0
  248. package/src/primitives/input.test.tsx +161 -0
  249. package/src/primitives/input.tsx +34 -28
  250. package/src/primitives/page-header.stories.tsx +51 -0
  251. package/src/primitives/page-header.test.tsx +48 -0
  252. package/src/primitives/page-header.tsx +35 -35
  253. package/src/primitives/page-shell.stories.tsx +89 -0
  254. package/src/primitives/page-shell.test.tsx +24 -0
  255. package/src/primitives/page-shell.tsx +26 -0
  256. package/src/primitives/table-wrapper.stories.tsx +54 -0
  257. package/src/primitives/table.test.tsx +72 -0
  258. package/src/primitives/table.tsx +33 -12
  259. package/src/primitives/theme-toggle.test.tsx +167 -0
  260. package/src/primitives/theme-toggle.tsx +111 -39
  261. package/dist/active-sessions-store-nl70ZnMC.d.ts +0 -84
  262. package/dist/button-C87nEe2R.js +0 -78
  263. package/dist/chat-DDvF2oGQ.js +0 -672
  264. package/dist/diff-preview-BcK3nRXb.js +0 -533
  265. package/dist/document-editor-pane-CsFbH2qo.js +0 -1279
  266. package/dist/files--Unn___t.js +0 -752
  267. package/dist/index-2UntyjBb.d.ts +0 -52
  268. package/dist/index-BgUHilZm.d.ts +0 -108
  269. package/dist/index-CPDET_s1.d.ts +0 -549
  270. package/dist/index-Cg6gYAqh.d.ts +0 -73
  271. package/dist/index-Cs7j8V7l.d.ts +0 -203
  272. package/dist/index-CyGSLGVF.d.ts +0 -234
  273. package/dist/index-DjKxO357.d.ts +0 -128
  274. package/dist/primitives-Bx59fT-U.js +0 -1239
  275. package/dist/table-Bss73DhB.js +0 -146
  276. package/dist/tool-call-step-DNebqhmX.js +0 -434
  277. package/dist/use-auto-scroll-C5Pjeqon.js +0 -153
  278. package/dist/use-sse-stream-DjqRuDft.js +0 -884
  279. package/dist/use-sse-stream-Dm6R5YWz.d.ts +0 -282
@@ -1,752 +0,0 @@
1
- import { a as focusRingInset, i as focusRing } from "./focus-BcE_SHqz.js";
2
- import { t as cn } from "./utils-C_uf36nf.js";
3
- import { t as Button } from "./button-C87nEe2R.js";
4
- import { t as ArtifactPane } from "./artifact-pane-DMXT9a8U.js";
5
- import { n as CopyButton, t as CodeBlock } from "./code-block-B36KVUSN.js";
6
- import { t as formatBytes } from "./format-DfcLWqMa.js";
7
- import { i as getFormatLabel, n as fileExtension, o as resolveFilePreviewKind, r as getCodeLanguage, t as detectFileFormat } from "./file-format-BgXbr-Ib.js";
8
- import { t as Markdown } from "./markdown-Db08KAYF.js";
9
- import { Suspense, lazy, useEffect, useMemo, useState } from "react";
10
- import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
11
- import { ChevronRight, Download, File, FileCode, FileImage, FileJson, FileSpreadsheet, FileText, Folder, FolderOpen, Music, X } from "lucide-react";
12
- import { FileTree, useFileTree } from "@pierre/trees/react";
13
- //#region src/files/file-tree.tsx
14
- /**
15
- * FileTree — directory browser with file type icons.
16
- *
17
- * Renders a hierarchical file system view. Clicking a file
18
- * triggers onSelect with the full path.
19
- */
20
- function isNodeVisible(node, visibility) {
21
- if (!visibility) return true;
22
- if (visibility.hiddenPaths?.includes(node.path)) return false;
23
- if (visibility.hiddenPathPrefixes?.some((prefix) => node.path === prefix || node.path.startsWith(`${prefix}/`))) return false;
24
- return visibility.isVisible ? visibility.isVisible(node) : true;
25
- }
26
- function filterFileTree(root, visibility) {
27
- if (!isNodeVisible(root, visibility)) return null;
28
- if (root.type === "file") return root;
29
- const children = (root.children ?? []).map((child) => filterFileTree(child, visibility)).filter((child) => child !== null);
30
- if (root.children && root.children.length > 0 && children.length === 0) return null;
31
- return {
32
- ...root,
33
- children
34
- };
35
- }
36
- const FILE_ICONS = {
37
- pdf: FileText,
38
- csv: FileSpreadsheet,
39
- xlsx: FileSpreadsheet,
40
- xls: FileSpreadsheet,
41
- py: FileCode,
42
- ts: FileCode,
43
- js: FileCode,
44
- json: FileJson,
45
- yaml: FileCode,
46
- yml: FileCode,
47
- md: FileText,
48
- txt: FileText,
49
- png: FileImage,
50
- jpg: FileImage,
51
- jpeg: FileImage,
52
- gif: FileImage,
53
- svg: FileImage
54
- };
55
- function getFileIcon(name) {
56
- const ext = name.split(".").pop()?.toLowerCase() || "";
57
- return FILE_ICONS[ext] || File;
58
- }
59
- function getFileColor(name) {
60
- switch (name.split(".").pop()?.toLowerCase() || "") {
61
- case "pdf": return "text-red-400";
62
- case "py": return "text-yellow-400";
63
- case "ts":
64
- case "js": return "text-blue-400";
65
- case "json": return "text-green-400";
66
- case "yaml":
67
- case "yml": return "text-[var(--accent-text)]";
68
- case "csv":
69
- case "xlsx": return "text-emerald-400";
70
- case "md": return "text-foreground";
71
- default: return "text-muted-foreground";
72
- }
73
- }
74
- function TreeNode({ node, depth, selectedPath, onSelect, defaultExpanded }) {
75
- const [expanded, setExpanded] = useState(defaultExpanded);
76
- const isSelected = node.path === selectedPath;
77
- const isDir = node.type === "directory";
78
- const handleClick = () => {
79
- if (isDir) setExpanded(!expanded);
80
- onSelect?.(node.path, node);
81
- };
82
- const Icon = isDir ? expanded ? FolderOpen : Folder : getFileIcon(node.name);
83
- const iconColor = isDir ? "text-primary" : getFileColor(node.name);
84
- return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("button", {
85
- type: "button",
86
- className: cn("flex items-center gap-1.5 w-full text-left px-2 py-[2px] cursor-pointer text-[13px] transition-colors", "appearance-none bg-transparent border-none", "hover:bg-accent", isSelected ? "bg-primary/15 text-foreground" : "text-foreground"),
87
- style: { paddingLeft: `${depth * 16 + 8}px` },
88
- onClick: handleClick,
89
- "aria-expanded": isDir ? expanded : void 0,
90
- children: [
91
- isDir && /* @__PURE__ */ jsx(ChevronRight, { className: cn("h-3 w-3 shrink-0 text-muted-foreground transition-transform", expanded && "rotate-90") }),
92
- !isDir && /* @__PURE__ */ jsx("span", { className: "w-3" }),
93
- /* @__PURE__ */ jsx(Icon, { className: cn("h-4 w-4 shrink-0", iconColor) }),
94
- /* @__PURE__ */ jsx("span", {
95
- className: "truncate",
96
- children: node.name
97
- }),
98
- node.size !== void 0 && !isDir && /* @__PURE__ */ jsx("span", {
99
- className: "text-muted-foreground text-xs ml-auto tabular-nums",
100
- children: formatSize(node.size)
101
- })
102
- ]
103
- }), isDir && expanded && node.children && /* @__PURE__ */ jsx("div", { children: node.children.sort((a, b) => {
104
- if (a.type !== b.type) return a.type === "directory" ? -1 : 1;
105
- return a.name.localeCompare(b.name);
106
- }).map((child) => /* @__PURE__ */ jsx(TreeNode, {
107
- node: child,
108
- depth: depth + 1,
109
- selectedPath,
110
- onSelect,
111
- defaultExpanded
112
- }, child.path)) })] });
113
- }
114
- function formatSize(bytes) {
115
- if (bytes < 1024) return `${bytes}B`;
116
- if (bytes < 1048576) return `${(bytes / 1024).toFixed(0)}K`;
117
- return `${(bytes / 1048576).toFixed(1)}M`;
118
- }
119
- function FileTree$1({ root, selectedPath, onSelect, className, defaultExpanded = true, visibility }) {
120
- const visibleRoot = filterFileTree(root, visibility);
121
- if (!visibleRoot) return null;
122
- return /* @__PURE__ */ jsx("div", {
123
- className: cn("text-sm font-sans", className),
124
- children: visibleRoot.children ? visibleRoot.children.sort((a, b) => {
125
- if (a.type !== b.type) return a.type === "directory" ? -1 : 1;
126
- return a.name.localeCompare(b.name);
127
- }).map((child) => /* @__PURE__ */ jsx(TreeNode, {
128
- node: child,
129
- depth: 0,
130
- selectedPath,
131
- onSelect,
132
- defaultExpanded
133
- }, child.path)) : /* @__PURE__ */ jsx(TreeNode, {
134
- node: visibleRoot,
135
- depth: 0,
136
- selectedPath,
137
- onSelect,
138
- defaultExpanded
139
- })
140
- });
141
- }
142
- //#endregion
143
- //#region src/files/rich-file-tree.tsx
144
- /**
145
- * RichFileTree — feature-rich file browser built on @pierre/trees.
146
- *
147
- * Why this exists alongside the existing FileTree:
148
- * - Built-in search (cmd-K-style fuzzy filter)
149
- * - Virtualized rendering for vaults with thousands of files
150
- * - Git-status overlays per row (modified / added / staged)
151
- * - Right-click + button-lane context menus with custom item rendering
152
- * - VS Code-style icons via @pierre/vscode-icons (optional)
153
- *
154
- * The existing FileTree stays as-is for simple cases. RichFileTree is the
155
- * upgrade path when a consumer's vault grows past a few hundred files or
156
- * needs richer affordances.
157
- *
158
- * Pierre renders inside a shadow DOM to keep its CSS isolated. We bridge
159
- * the host theme via CSS variables on the host element below — the tree
160
- * picks them up through `--trees-*-override` overrides.
161
- */
162
- /**
163
- * Map a sandbox-ui design token (e.g. `--accent-surface-soft`) to a CSS
164
- * `var(--token)` reference. Pierre's CSS-variable surface accepts any
165
- * valid CSS color expression, so passing `var(--token)` lets the host
166
- * theme propagate through without us having to read computed styles.
167
- */
168
- function cssVarFromToken(name) {
169
- return `var(${name})`;
170
- }
171
- const DEFAULT_THEME = {
172
- selectedBg: cssVarFromToken("--accent-surface-soft"),
173
- selectedFg: cssVarFromToken("--accent-text"),
174
- fg: cssVarFromToken("--foreground"),
175
- hoverBg: cssVarFromToken("--muted"),
176
- border: cssVarFromToken("--border"),
177
- mutedFg: cssVarFromToken("--muted-foreground")
178
- };
179
- /**
180
- * Walk a recursive FileNode and return a flat list of canonical paths.
181
- *
182
- * Pierre infers directory structure from path segments — passing both
183
- * `dir` and `dir/file.md` collides because `dir` looks like a file.
184
- * We emit only files; pure-directory leaves get a trailing slash so
185
- * Pierre keeps them as folders even when they have no children.
186
- */
187
- function flattenFileNode(node, out = []) {
188
- if (node.type === "file" && node.path) {
189
- out.push(node.path);
190
- return out;
191
- }
192
- if (node.type === "directory") {
193
- if (node.children?.length) {
194
- for (const child of node.children) flattenFileNode(child, out);
195
- return out;
196
- }
197
- if (node.path) out.push(`${node.path}/`);
198
- }
199
- return out;
200
- }
201
- function RichFileTree({ root, paths, selectedPath, onSelect, search = true, initialExpansion = "open", gitStatus, renderContextMenu, header, themeOverrides, className, style, height }) {
202
- if (root && paths) throw new Error("RichFileTree: pass `root` or `paths`, not both");
203
- const flatPaths = useMemo(() => {
204
- if (paths) return Array.from(paths);
205
- if (root) return flattenFileNode(root);
206
- return [];
207
- }, [paths, root]);
208
- const { model } = useFileTree({
209
- paths: flatPaths,
210
- search,
211
- initialExpansion,
212
- onSelectionChange: (selected) => {
213
- const next = selected[0];
214
- if (next && next !== selectedPath) onSelect?.(next);
215
- }
216
- });
217
- useEffect(() => {
218
- if (!gitStatus) return;
219
- model.setGitStatus(gitStatus);
220
- }, [model, gitStatus]);
221
- useEffect(() => {
222
- model.resetPaths(flatPaths);
223
- }, [model, flatPaths]);
224
- useEffect(() => {
225
- if (!selectedPath) return;
226
- const current = model.getSelectedPaths();
227
- if (current.length === 1 && current[0] === selectedPath) return;
228
- model.setSelectedPaths?.([selectedPath]);
229
- }, [model, selectedPath]);
230
- const theme = {
231
- ...DEFAULT_THEME,
232
- ...themeOverrides
233
- };
234
- const themeStyle = useMemo(() => ({
235
- ["--trees-selected-bg-override"]: theme.selectedBg,
236
- ["--trees-selected-fg-override"]: theme.selectedFg,
237
- ["--trees-fg-override"]: theme.fg,
238
- ["--trees-hover-bg-override"]: theme.hoverBg,
239
- ["--trees-border-color-override"]: theme.border,
240
- ["--trees-muted-fg-override"]: theme.mutedFg,
241
- height: height ?? "100%",
242
- ...style
243
- }), [
244
- theme,
245
- height,
246
- style
247
- ]);
248
- return /* @__PURE__ */ jsx(FileTree, {
249
- model,
250
- header,
251
- renderContextMenu,
252
- className,
253
- style: themeStyle
254
- });
255
- }
256
- //#endregion
257
- //#region src/files/file-preview.tsx
258
- /**
259
- * FilePreview — universal file renderer.
260
- *
261
- * Renders any file type:
262
- * - PDF: embedded viewer at full pane height
263
- * - Images: fit to the pane on a checker ground; click toggles natural size
264
- * - Video / audio: native players
265
- * - CSV: sticky-header table, capped at CSV_PREVIEW_ROW_LIMIT rows
266
- * - XLSX / XLS: download card
267
- * - Code (py/json/yaml/ts/js): syntax-highlighted, line-numbered viewer
268
- * - Markdown: rendered prose
269
- * - Text: monospace preview
270
- * - Anything else: text when content is a string, otherwise a download card
271
- */
272
- /** Rows rendered by the CSV preview; the count line reports the total. */
273
- const CSV_PREVIEW_ROW_LIMIT = 500;
274
- const NEEDS_DOWNLOAD_LINK = "This file needs a download link to preview.";
275
- const NO_INLINE_PREVIEW = "This file type has no inline preview.";
276
- const NO_INLINE_CONTENT = "This file has no inline content to preview yet.";
277
- function CodePreview({ content, filename, kind }) {
278
- const lineCount = content.split("\n").length;
279
- const language = getCodeLanguage(filename, kind);
280
- const labelToken = fileExtension(filename) || language || "txt";
281
- return /* @__PURE__ */ jsx(CodeBlock, {
282
- code: content,
283
- language,
284
- label: `${labelToken} · ${lineCount} lines`,
285
- showLineNumbers: true,
286
- className: "max-h-[70vh] overflow-auto",
287
- children: /* @__PURE__ */ jsx(CopyButton, { text: content })
288
- });
289
- }
290
- /**
291
- * Split CSV text into rows of cells (RFC 4180): a quoted cell may hold commas,
292
- * line breaks, and doubled quotes. Unquoted cells are trimmed; blank lines and
293
- * a trailing line break add no row.
294
- */
295
- function parseCsv(content) {
296
- const rows = [];
297
- let row = [];
298
- let cell = "";
299
- let quoted = false;
300
- let inQuotes = false;
301
- const endCell = () => {
302
- row.push(quoted ? cell : cell.trim());
303
- cell = "";
304
- quoted = false;
305
- };
306
- const endRow = () => {
307
- endCell();
308
- if (row.length > 1 || row[0] !== "") rows.push(row);
309
- row = [];
310
- };
311
- for (let index = 0; index < content.length; index += 1) {
312
- const char = content[index];
313
- if (inQuotes) {
314
- if (char === "\"") {
315
- if (content[index + 1] === "\"") {
316
- cell += "\"";
317
- index += 1;
318
- } else inQuotes = false;
319
- } else cell += char;
320
- continue;
321
- }
322
- if (char === "\"") {
323
- inQuotes = true;
324
- quoted = true;
325
- continue;
326
- }
327
- if (char === ",") {
328
- endCell();
329
- continue;
330
- }
331
- if (char === "\r" || char === "\n") {
332
- if (char === "\r" && content[index + 1] === "\n") index += 1;
333
- endRow();
334
- continue;
335
- }
336
- cell += char;
337
- }
338
- if (cell.length > 0 || quoted || row.length > 0) endRow();
339
- return rows;
340
- }
341
- function CsvPreview({ content }) {
342
- const [headers = [], ...body] = parseCsv(content);
343
- if (headers.length === 0) return null;
344
- const visible = body.slice(0, 500);
345
- const columnCount = Math.max(headers.length, ...visible.map((cells) => cells.length));
346
- const capped = body.length > visible.length;
347
- return /* @__PURE__ */ jsxs("div", {
348
- className: "flex min-h-0 flex-1 flex-col gap-2",
349
- children: [/* @__PURE__ */ jsx("div", {
350
- className: "min-h-0 overflow-auto rounded-[var(--radius-md)] border border-border",
351
- children: /* @__PURE__ */ jsxs("table", {
352
- className: "w-full text-sm",
353
- children: [/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: Array.from({ length: columnCount }, (_, column) => /* @__PURE__ */ jsx("th", {
354
- className: "sticky top-0 whitespace-nowrap border-b border-border bg-card px-3 py-2 text-left text-xs font-semibold text-foreground",
355
- children: headers[column] ?? ""
356
- }, column)) }) }), /* @__PURE__ */ jsx("tbody", { children: visible.map((cells, rowIndex) => /* @__PURE__ */ jsx("tr", {
357
- className: "border-b border-border hover:bg-accent",
358
- children: Array.from({ length: columnCount }, (_, column) => /* @__PURE__ */ jsx("td", {
359
- className: "whitespace-nowrap px-3 py-1.5 font-mono text-xs text-foreground",
360
- children: cells[column] ?? ""
361
- }, column))
362
- }, rowIndex)) })]
363
- })
364
- }), /* @__PURE__ */ jsxs("p", {
365
- className: "shrink-0 text-xs text-muted-foreground",
366
- children: [capped ? `Showing ${visible.length} of ${body.length} rows` : `${body.length} ${body.length === 1 ? "row" : "rows"}`, ` · ${columnCount} ${columnCount === 1 ? "column" : "columns"}`]
367
- })]
368
- });
369
- }
370
- const CHECKER_STYLE = {
371
- backgroundColor: "var(--color-background)",
372
- backgroundImage: "repeating-conic-gradient(var(--color-muted) 0% 25%, transparent 0% 50%)",
373
- backgroundSize: "16px 16px"
374
- };
375
- function ImagePreview({ src, filename }) {
376
- const [naturalSize, setNaturalSize] = useState(false);
377
- return /* @__PURE__ */ jsx("div", {
378
- className: "flex min-h-[12rem] flex-1 overflow-auto rounded-[var(--radius-md)] border border-border",
379
- style: CHECKER_STYLE,
380
- children: /* @__PURE__ */ jsx("button", {
381
- type: "button",
382
- onClick: () => setNaturalSize((value) => !value),
383
- "aria-pressed": naturalSize,
384
- "aria-label": naturalSize ? "Fit image to pane" : "Show image at natural size",
385
- className: cn("flex items-center justify-center", focusRingInset, naturalSize ? "m-auto cursor-zoom-out" : "h-full w-full cursor-zoom-in p-4"),
386
- children: /* @__PURE__ */ jsx("img", {
387
- src,
388
- alt: filename,
389
- draggable: false,
390
- className: naturalSize ? "max-w-none" : "max-h-full max-w-full object-contain"
391
- })
392
- })
393
- });
394
- }
395
- function PdfPreview({ blobUrl, filename, size, onDownload }) {
396
- return /* @__PURE__ */ jsx("object", {
397
- data: blobUrl,
398
- type: "application/pdf",
399
- title: filename,
400
- className: "min-h-[24rem] w-full flex-1 rounded-[var(--radius-md)]",
401
- children: /* @__PURE__ */ jsx(DownloadCard, {
402
- filename,
403
- size,
404
- sentence: "This browser does not show PDFs inline.",
405
- onDownload,
406
- className: "h-full"
407
- })
408
- });
409
- }
410
- function VideoPreview({ src, filename }) {
411
- return /* @__PURE__ */ jsx("div", {
412
- className: "flex min-h-[12rem] flex-1 items-center justify-center overflow-hidden rounded-[var(--radius-md)] border border-border bg-background",
413
- children: /* @__PURE__ */ jsx("video", {
414
- controls: true,
415
- preload: "metadata",
416
- src,
417
- "aria-label": filename,
418
- className: "max-h-full max-w-full"
419
- })
420
- });
421
- }
422
- function AudioPreview({ src, filename }) {
423
- return /* @__PURE__ */ jsxs("div", {
424
- className: "flex flex-col items-center gap-4 rounded-[var(--radius-md)] border border-border bg-background px-6 py-10",
425
- children: [
426
- /* @__PURE__ */ jsx(Music, { className: "h-10 w-10 text-muted-foreground opacity-60" }),
427
- /* @__PURE__ */ jsx("p", {
428
- className: "max-w-full truncate text-sm font-medium text-foreground",
429
- children: filename
430
- }),
431
- /* @__PURE__ */ jsx("audio", {
432
- controls: true,
433
- preload: "metadata",
434
- src,
435
- "aria-label": filename,
436
- className: "w-full max-w-md"
437
- })
438
- ]
439
- });
440
- }
441
- function TextPreview({ content }) {
442
- return /* @__PURE__ */ jsx("pre", {
443
- className: "bg-card rounded-[var(--radius-md)] border border-border p-4 overflow-auto max-h-[70vh] text-sm text-foreground font-mono leading-[1.55]",
444
- children: content
445
- });
446
- }
447
- function MarkdownPreview({ content, urlTransform }) {
448
- return /* @__PURE__ */ jsx("div", {
449
- className: "rounded-[var(--radius-md)] border border-border bg-background p-5",
450
- children: /* @__PURE__ */ jsx(Markdown, {
451
- urlTransform,
452
- children: content
453
- })
454
- });
455
- }
456
- /**
457
- * One muted sentence plus the filename, its size when known, and a Download
458
- * button when the host wires `onDownload`. Serves spreadsheets, binaries, and
459
- * every kind whose source (blob or text) is missing.
460
- */
461
- function DownloadCard({ filename, size, sentence, icon: Icon = FileText, onDownload, className }) {
462
- return /* @__PURE__ */ jsxs("div", {
463
- className: cn("flex flex-col items-center justify-center rounded-[var(--radius-md)] border border-dashed border-border bg-background px-6 py-16 text-center", className),
464
- children: [
465
- /* @__PURE__ */ jsx(Icon, { className: "mb-3 h-12 w-12 text-muted-foreground opacity-40" }),
466
- /* @__PURE__ */ jsx("p", {
467
- className: "max-w-full truncate text-sm font-medium text-foreground",
468
- children: filename
469
- }),
470
- size !== void 0 && /* @__PURE__ */ jsx("p", {
471
- className: "mt-1 text-xs text-muted-foreground",
472
- children: formatBytes(size)
473
- }),
474
- /* @__PURE__ */ jsx("p", {
475
- className: "mt-3 max-w-md text-sm text-muted-foreground",
476
- children: sentence
477
- }),
478
- onDownload && /* @__PURE__ */ jsxs(Button, {
479
- type: "button",
480
- variant: "outline",
481
- size: "sm",
482
- className: "mt-5",
483
- onClick: onDownload,
484
- children: [/* @__PURE__ */ jsx(Download, {}), "Download"]
485
- })
486
- ]
487
- });
488
- }
489
- function PreviewBody({ kind, filename, content, blobUrl, size, urlTransform, onDownload }) {
490
- const hasText = typeof content === "string";
491
- const card = (sentence, icon) => /* @__PURE__ */ jsx(DownloadCard, {
492
- filename,
493
- size,
494
- sentence,
495
- icon,
496
- onDownload
497
- });
498
- switch (kind) {
499
- case "pdf":
500
- if (blobUrl) return /* @__PURE__ */ jsx(PdfPreview, {
501
- blobUrl,
502
- filename,
503
- size,
504
- onDownload
505
- });
506
- return card(NEEDS_DOWNLOAD_LINK);
507
- case "image":
508
- if (blobUrl) return /* @__PURE__ */ jsx(ImagePreview, {
509
- src: blobUrl,
510
- filename
511
- });
512
- if (hasText) return /* @__PURE__ */ jsx(CodePreview, {
513
- content,
514
- filename,
515
- kind: "code"
516
- });
517
- return card(NEEDS_DOWNLOAD_LINK);
518
- case "video":
519
- if (blobUrl) return /* @__PURE__ */ jsx(VideoPreview, {
520
- src: blobUrl,
521
- filename
522
- });
523
- return card(NEEDS_DOWNLOAD_LINK);
524
- case "audio":
525
- if (blobUrl) return /* @__PURE__ */ jsx(AudioPreview, {
526
- src: blobUrl,
527
- filename
528
- });
529
- return card(NEEDS_DOWNLOAD_LINK, Music);
530
- case "csv":
531
- if (hasText) return /* @__PURE__ */ jsx(CsvPreview, { content });
532
- return card(NO_INLINE_CONTENT, FileSpreadsheet);
533
- case "code":
534
- case "json":
535
- case "yaml":
536
- if (hasText) return /* @__PURE__ */ jsx(CodePreview, {
537
- content,
538
- filename,
539
- kind
540
- });
541
- return card(NO_INLINE_CONTENT);
542
- case "markdown":
543
- if (hasText) return /* @__PURE__ */ jsx(MarkdownPreview, {
544
- content,
545
- urlTransform
546
- });
547
- return card(NO_INLINE_CONTENT);
548
- case "text":
549
- if (hasText) return /* @__PURE__ */ jsx(TextPreview, { content });
550
- return card(NO_INLINE_CONTENT);
551
- case "spreadsheet": return card("Download to open this workbook in a spreadsheet app.", FileSpreadsheet);
552
- case "binary":
553
- if (hasText) return /* @__PURE__ */ jsx(TextPreview, { content });
554
- return card(blobUrl ? NO_INLINE_PREVIEW : NEEDS_DOWNLOAD_LINK);
555
- }
556
- }
557
- function FilePreview({ filename, content, blobUrl, mimeType, size, urlTransform, onClose, onDownload, hideHeader = false, className }) {
558
- const kind = resolveFilePreviewKind(filename, mimeType);
559
- const previewLabel = getFormatLabel(kind);
560
- return /* @__PURE__ */ jsxs("div", {
561
- className: cn("flex flex-col h-full", className),
562
- children: [!hideHeader && /* @__PURE__ */ jsxs("div", {
563
- className: "flex items-center gap-2 px-3 py-2 border-b border-border shrink-0",
564
- children: [
565
- /* @__PURE__ */ jsxs("div", {
566
- className: "min-w-0 flex-1",
567
- children: [/* @__PURE__ */ jsx("div", {
568
- className: "truncate text-sm font-medium text-foreground",
569
- children: filename
570
- }), /* @__PURE__ */ jsx("div", {
571
- className: "mt-0.5 text-[11px] uppercase tracking-[0.12em] text-muted-foreground",
572
- children: previewLabel
573
- })]
574
- }),
575
- onDownload && /* @__PURE__ */ jsx("button", {
576
- type: "button",
577
- onClick: onDownload,
578
- "aria-label": `Download ${filename}`,
579
- className: "p-1.5 rounded-[var(--radius-sm)] hover:bg-accent text-muted-foreground hover:text-foreground transition-colors",
580
- children: /* @__PURE__ */ jsx(Download, { className: "h-4 w-4" })
581
- }),
582
- onClose && /* @__PURE__ */ jsx("button", {
583
- type: "button",
584
- onClick: onClose,
585
- "aria-label": `Close ${filename}`,
586
- className: "p-1.5 rounded-[var(--radius-sm)] hover:bg-accent text-muted-foreground hover:text-foreground transition-colors",
587
- children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
588
- })
589
- ]
590
- }), /* @__PURE__ */ jsx("div", {
591
- className: "flex min-h-0 flex-1 flex-col overflow-auto p-3",
592
- children: /* @__PURE__ */ jsx(PreviewBody, {
593
- kind,
594
- filename,
595
- content,
596
- blobUrl,
597
- size,
598
- urlTransform,
599
- onDownload
600
- })
601
- })]
602
- });
603
- }
604
- //#endregion
605
- //#region src/files/file-tabs.tsx
606
- /**
607
- * FileTabs — tab bar for open files in the preview panel.
608
- */
609
- function getTabIcon(name) {
610
- const ext = name.split(".").pop()?.toLowerCase() || "";
611
- if (["pdf"].includes(ext)) return FileText;
612
- if (["csv", "xlsx"].includes(ext)) return FileSpreadsheet;
613
- return FileCode;
614
- }
615
- function FileTabs({ tabs, activeId, onSelect, onClose, className }) {
616
- if (tabs.length === 0) return null;
617
- return /* @__PURE__ */ jsx("div", {
618
- className: cn("flex items-center border-b border-border bg-background overflow-x-auto", className),
619
- children: tabs.map((tab) => {
620
- const isActive = tab.id === activeId;
621
- const Icon = getTabIcon(tab.name);
622
- return /* @__PURE__ */ jsxs("div", {
623
- className: cn("group flex items-center border-r border-border shrink-0", isActive ? "bg-card text-foreground border-b-2 border-b-primary" : "text-muted-foreground hover:bg-muted/50"),
624
- children: [/* @__PURE__ */ jsxs("button", {
625
- type: "button",
626
- onClick: () => onSelect(tab.id),
627
- className: cn("flex min-w-0 items-center gap-1.5 px-3 py-1.5 text-xs transition-colors hover:text-foreground", focusRingInset),
628
- children: [
629
- /* @__PURE__ */ jsx(Icon, { className: "h-3 w-3 shrink-0" }),
630
- /* @__PURE__ */ jsx("span", {
631
- className: "max-w-[120px] truncate",
632
- children: tab.name
633
- }),
634
- tab.dirty && /* @__PURE__ */ jsx("span", { className: "h-1.5 w-1.5 rounded-full bg-primary" })
635
- ]
636
- }), /* @__PURE__ */ jsx("button", {
637
- type: "button",
638
- "aria-label": `Close ${tab.name}`,
639
- onClick: () => onClose(tab.id),
640
- className: cn("mr-1 rounded p-0.5 opacity-0 transition-opacity hover:bg-accent focus-visible:opacity-100 group-hover:opacity-100", focusRing),
641
- children: /* @__PURE__ */ jsx(X, { className: "h-2.5 w-2.5" })
642
- })]
643
- }, tab.id);
644
- })
645
- });
646
- }
647
- //#endregion
648
- //#region src/files/file-artifact-pane.tsx
649
- const LazyDocumentEditorPane = lazy(async () => {
650
- return { default: (await import("./document-editor-pane-CsFbH2qo.js").then((n) => n.n)).DocumentEditorPane };
651
- });
652
- /**
653
- * FileArtifactPane — opinionated artifact frame for file previews with tabs and
654
- * header actions. The body is `FilePreview`, so every kind it renders (image,
655
- * PDF, video, audio, CSV, spreadsheet, markdown, code, text) renders here too;
656
- * `onDownload` drives both the header button and the body's download cards.
657
- */
658
- function FileArtifactPane({ filename, content, blobUrl, mimeType, size, onClose, onDownload, urlTransform, path, tabs = [], activeTabId, onTabSelect, onTabClose, eyebrow = "Artifact", meta, toolbar, footer, className, headerClassName, hideTitleBlock, editor }) {
659
- const paneTabs = tabs.length > 0 && onTabSelect && onTabClose ? /* @__PURE__ */ jsx(FileTabs, {
660
- tabs,
661
- activeId: activeTabId,
662
- onSelect: onTabSelect,
663
- onClose: onTabClose
664
- }) : void 0;
665
- const isEditableMarkdown = (detectFileFormat(filename, mimeType) === "markdown" || (path ? detectFileFormat(path, mimeType) === "markdown" : false)) && editor?.enabled;
666
- const headerActions = onDownload || onClose ? /* @__PURE__ */ jsxs(Fragment$1, { children: [onDownload && /* @__PURE__ */ jsx("button", {
667
- type: "button",
668
- "aria-label": `Download ${filename}`,
669
- onClick: onDownload,
670
- className: `rounded-[var(--radius-sm)] p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing}`,
671
- children: /* @__PURE__ */ jsx(Download, { className: "h-4 w-4" })
672
- }), onClose && /* @__PURE__ */ jsx("button", {
673
- type: "button",
674
- "aria-label": `Close ${filename}`,
675
- onClick: onClose,
676
- className: `rounded-[var(--radius-sm)] p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing}`,
677
- children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
678
- })] }) : void 0;
679
- if (isEditableMarkdown) return /* @__PURE__ */ jsx(Suspense, {
680
- fallback: /* @__PURE__ */ jsx(ArtifactPane, {
681
- eyebrow,
682
- title: filename,
683
- subtitle: path,
684
- meta,
685
- toolbar,
686
- footer,
687
- className,
688
- tabs: paneTabs,
689
- headerActions,
690
- headerClassName,
691
- hideTitleBlock,
692
- children: /* @__PURE__ */ jsx("div", {
693
- className: "flex min-h-[12rem] items-center justify-center rounded-[var(--radius-lg)] border border-dashed border-border bg-muted text-sm text-muted-foreground",
694
- children: "Loading editor…"
695
- })
696
- }),
697
- children: /* @__PURE__ */ jsx(LazyDocumentEditorPane, {
698
- eyebrow,
699
- title: filename,
700
- subtitle: path,
701
- meta,
702
- toolbar,
703
- footer,
704
- className,
705
- tabs: paneTabs,
706
- headerActions,
707
- headerClassName,
708
- hideTitleBlock,
709
- markdown: content ?? "",
710
- urlTransform,
711
- mode: editor.mode,
712
- defaultMode: editor.defaultMode,
713
- onModeChange: editor.onModeChange,
714
- backend: editor.backend,
715
- collaboration: editor.collaboration,
716
- placeholder: editor.placeholder,
717
- autoFocus: editor.autoFocus,
718
- readOnly: editor.readOnly,
719
- saving: editor.saving,
720
- saveLabel: editor.saveLabel,
721
- onChange: editor.onChange,
722
- onSave: editor.onSave,
723
- previewClassName: editor.previewClassName,
724
- editorClassName: editor.editorClassName
725
- })
726
- });
727
- return /* @__PURE__ */ jsx(ArtifactPane, {
728
- eyebrow,
729
- title: filename,
730
- subtitle: path,
731
- meta,
732
- toolbar,
733
- footer,
734
- className,
735
- tabs: paneTabs,
736
- headerActions,
737
- headerClassName,
738
- hideTitleBlock,
739
- children: /* @__PURE__ */ jsx(FilePreview, {
740
- filename,
741
- content,
742
- blobUrl,
743
- mimeType,
744
- size,
745
- urlTransform,
746
- onDownload,
747
- hideHeader: true
748
- })
749
- });
750
- }
751
- //#endregion
752
- export { parseCsv as a, filterFileTree as c, FilePreview as i, FileTabs as n, RichFileTree as o, CSV_PREVIEW_ROW_LIMIT as r, FileTree$1 as s, FileArtifactPane as t };