@tangle-network/ui 11.10.0 → 11.11.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 (132) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +4 -1
  3. package/dist/active-sessions-store-Gt1R0rFG.js +262 -0
  4. package/dist/{active-sessions-store-CeOmXgv5.d.ts → active-sessions-store-nl70ZnMC.d.ts} +40 -41
  5. package/dist/artifact-pane-BL_DFWNl.d.ts +32 -0
  6. package/dist/artifact-pane-DMXT9a8U.js +70 -0
  7. package/dist/auth-DOETfnd9.js +154 -0
  8. package/dist/auth.d.ts +2 -74
  9. package/dist/auth.js +2 -16
  10. package/dist/branding-26d5ARIr.d.ts +14 -0
  11. package/dist/button-C87nEe2R.js +78 -0
  12. package/dist/button-yoIv77e2.d.ts +16 -0
  13. package/dist/chat-D4jAfEmj.js +667 -0
  14. package/dist/chat.d.ts +2 -201
  15. package/dist/chat.js +2 -31
  16. package/dist/code-block-B36KVUSN.js +165 -0
  17. package/dist/code-block-B9miUPht.d.ts +23 -0
  18. package/dist/diff-preview-BcK3nRXb.js +533 -0
  19. package/dist/document-editor-pane-BcoABlhn.d.ts +131 -0
  20. package/dist/document-editor-pane-BxlPjaTP.js +1287 -0
  21. package/dist/dropdown-menu-BpcLa5vF.js +101 -0
  22. package/dist/editor.d.ts +76 -78
  23. package/dist/editor.js +2 -34
  24. package/dist/file-format-BgXbr-Ib.js +160 -0
  25. package/dist/files-Bug33qCl.js +743 -0
  26. package/dist/files.d.ts +2 -243
  27. package/dist/files.js +3 -41
  28. package/dist/focus-BcE_SHqz.js +57 -0
  29. package/dist/format-DfcLWqMa.js +54 -0
  30. package/dist/hooks.d.ts +30 -37
  31. package/dist/hooks.js +111 -46
  32. package/dist/index-2UntyjBb.d.ts +52 -0
  33. package/dist/index-BgUHilZm.d.ts +108 -0
  34. package/dist/index-COgqsFAQ.d.ts +42 -0
  35. package/dist/index-CPDET_s1.d.ts +549 -0
  36. package/dist/index-CUhfHT_V.d.ts +204 -0
  37. package/dist/index-Cg6gYAqh.d.ts +73 -0
  38. package/dist/index-Cq-EJzqW.d.ts +16 -0
  39. package/dist/index-DhYmSaLF.d.ts +245 -0
  40. package/dist/index-DjKxO357.d.ts +128 -0
  41. package/dist/index.d.ts +26 -43
  42. package/dist/index.js +35 -472
  43. package/dist/markdown-BGqicV82.js +45 -0
  44. package/dist/markdown.d.ts +3 -18
  45. package/dist/markdown.js +3 -15
  46. package/dist/message-vhUI0c5G.d.ts +16 -0
  47. package/dist/nav.d.ts +6 -8
  48. package/dist/nav.js +29 -11
  49. package/dist/openui-artifact-renderer-D3E5bIAI.d.ts +114 -0
  50. package/dist/openui-artifact-renderer-DrU1AdVk.js +266 -0
  51. package/dist/openui.d.ts +2 -115
  52. package/dist/openui.js +2 -13
  53. package/dist/parts-5mhy9yJ3.d.ts +37 -0
  54. package/dist/primitives-Cb8GGVKr.js +1239 -0
  55. package/dist/primitives.d.ts +5 -525
  56. package/dist/primitives.js +9 -212
  57. package/dist/redaction-CGGB2ENG.js +74 -0
  58. package/dist/redaction.d.ts +2 -42
  59. package/dist/redaction.js +2 -7
  60. package/dist/run-OyWmIDqu.d.ts +41 -0
  61. package/dist/run-ZsIKPA6J.js +17 -0
  62. package/dist/run-group-BACLbCFl.js +410 -0
  63. package/dist/run.d.ts +3 -126
  64. package/dist/run.js +5 -40
  65. package/dist/sdk-hooks.d.ts +2 -285
  66. package/dist/sdk-hooks.js +3 -36
  67. package/dist/stores.d.ts +13 -14
  68. package/dist/stores.js +34 -76
  69. package/dist/table-Bss73DhB.js +146 -0
  70. package/dist/tabs-BVHR6NkO.js +40 -0
  71. package/dist/text-shimmer-BUUo6I-g.js +64 -0
  72. package/dist/tool-call-feed-BeB1_4pX.d.ts +47 -0
  73. package/dist/tool-call-feed-Djt2q11V.js +109 -0
  74. package/dist/tool-call-step-DNebqhmX.js +434 -0
  75. package/dist/tool-display-BAuAVa43.js +158 -0
  76. package/dist/{tool-display-z4JcDmMQ.d.ts → tool-display-DgmL5rIU.d.ts} +16 -16
  77. package/dist/tool-previews.d.ts +2 -48
  78. package/dist/tool-previews.js +2 -23
  79. package/dist/types.d.ts +6 -19
  80. package/dist/types.js +0 -1
  81. package/dist/use-auto-scroll-C5Pjeqon.js +153 -0
  82. package/dist/use-sse-stream-BVgO1QBN.js +884 -0
  83. package/dist/use-sse-stream-Dm6R5YWz.d.ts +282 -0
  84. package/dist/utils-Bl_CZ0Qp.js +37 -0
  85. package/dist/{chunk-RQHJBTEU.js → utils-C_uf36nf.js} +4 -6
  86. package/dist/utils.d.ts +2 -104
  87. package/dist/utils.js +6 -44
  88. package/package.json +39 -41
  89. package/src/lib/focus.ts +2 -1
  90. package/dist/artifact-pane-DpuWcAiF.d.ts +0 -33
  91. package/dist/button-CMQuQEW_.d.ts +0 -17
  92. package/dist/chunk-34A66VBG.js +0 -214
  93. package/dist/chunk-3OI2QKFD.js +0 -0
  94. package/dist/chunk-3XXBZL53.js +0 -174
  95. package/dist/chunk-42PAH5D2.js +0 -112
  96. package/dist/chunk-4CLN43XT.js +0 -45
  97. package/dist/chunk-55WHV7SS.js +0 -1604
  98. package/dist/chunk-565EATZZ.js +0 -156
  99. package/dist/chunk-5Z5ZYMOJ.js +0 -0
  100. package/dist/chunk-6BGQA4BQ.js +0 -0
  101. package/dist/chunk-BEBXZPHW.js +0 -299
  102. package/dist/chunk-C5WF4WMV.js +0 -734
  103. package/dist/chunk-HFL6R6IF.js +0 -37
  104. package/dist/chunk-HGML45QH.js +0 -104
  105. package/dist/chunk-HMAPIH7L.js +0 -595
  106. package/dist/chunk-K5XFRUS4.js +0 -1401
  107. package/dist/chunk-KFQGHD73.js +0 -198
  108. package/dist/chunk-L57WRIND.js +0 -59
  109. package/dist/chunk-LTEKI7YJ.js +0 -59
  110. package/dist/chunk-M3QZK62R.js +0 -233
  111. package/dist/chunk-ND3ZFXQK.js +0 -179
  112. package/dist/chunk-OEX7NZE3.js +0 -321
  113. package/dist/chunk-OL5GYLHV.js +0 -60
  114. package/dist/chunk-QGFYBNSO.js +0 -133
  115. package/dist/chunk-R7B3UWPF.js +0 -550
  116. package/dist/chunk-R7SUY4E3.js +0 -65
  117. package/dist/chunk-REJESC5U.js +0 -117
  118. package/dist/chunk-RQGKSCEZ.js +0 -0
  119. package/dist/chunk-SNLR2AEA.js +0 -40
  120. package/dist/chunk-WKWBTL2V.js +0 -15
  121. package/dist/chunk-X7CU776B.js +0 -1048
  122. package/dist/chunk-XU3HB5QL.js +0 -127
  123. package/dist/chunk-YTO5V6QS.js +0 -19
  124. package/dist/chunk-YU4E5J2N.js +0 -437
  125. package/dist/chunk-YZ6AK25N.js +0 -886
  126. package/dist/code-block-0kSpWMnf.d.ts +0 -25
  127. package/dist/document-editor-pane-IAEQn_Dl.d.ts +0 -128
  128. package/dist/document-editor-pane-QHDOBA43.js +0 -13
  129. package/dist/message-BHWbxBtT.d.ts +0 -15
  130. package/dist/parts-dj7AcUg0.d.ts +0 -36
  131. package/dist/run-PfLmDAox.d.ts +0 -41
  132. package/dist/tool-call-feed-D9iofJgW.d.ts +0 -46
@@ -1,886 +0,0 @@
1
- import {
2
- formatBytes
3
- } from "./chunk-4CLN43XT.js";
4
- import {
5
- detectFileFormat,
6
- fileExtension,
7
- getCodeLanguage,
8
- getFormatLabel,
9
- resolveFilePreviewKind
10
- } from "./chunk-XU3HB5QL.js";
11
- import {
12
- Button
13
- } from "./chunk-42PAH5D2.js";
14
- import {
15
- ArtifactPane
16
- } from "./chunk-LTEKI7YJ.js";
17
- import {
18
- Markdown
19
- } from "./chunk-OL5GYLHV.js";
20
- import {
21
- CodeBlock,
22
- CopyButton
23
- } from "./chunk-3XXBZL53.js";
24
- import {
25
- focusRing,
26
- focusRingInset
27
- } from "./chunk-WKWBTL2V.js";
28
- import {
29
- cn
30
- } from "./chunk-RQHJBTEU.js";
31
-
32
- // src/files/file-tree.tsx
33
- import { useState } from "react";
34
- import {
35
- File,
36
- FileText,
37
- FileCode,
38
- FileSpreadsheet,
39
- FileImage,
40
- Folder,
41
- FolderOpen,
42
- ChevronRight,
43
- FileJson
44
- } from "lucide-react";
45
- import { jsx, jsxs } from "react/jsx-runtime";
46
- function isNodeVisible(node, visibility) {
47
- if (!visibility) return true;
48
- if (visibility.hiddenPaths?.includes(node.path)) {
49
- return false;
50
- }
51
- if (visibility.hiddenPathPrefixes?.some(
52
- (prefix) => node.path === prefix || node.path.startsWith(`${prefix}/`)
53
- )) {
54
- return false;
55
- }
56
- return visibility.isVisible ? visibility.isVisible(node) : true;
57
- }
58
- function filterFileTree(root, visibility) {
59
- if (!isNodeVisible(root, visibility)) {
60
- return null;
61
- }
62
- if (root.type === "file") {
63
- return root;
64
- }
65
- const children = (root.children ?? []).map((child) => filterFileTree(child, visibility)).filter((child) => child !== null);
66
- if (root.children && root.children.length > 0 && children.length === 0) {
67
- return null;
68
- }
69
- return {
70
- ...root,
71
- children
72
- };
73
- }
74
- var FILE_ICONS = {
75
- pdf: FileText,
76
- csv: FileSpreadsheet,
77
- xlsx: FileSpreadsheet,
78
- xls: FileSpreadsheet,
79
- py: FileCode,
80
- ts: FileCode,
81
- js: FileCode,
82
- json: FileJson,
83
- yaml: FileCode,
84
- yml: FileCode,
85
- md: FileText,
86
- txt: FileText,
87
- png: FileImage,
88
- jpg: FileImage,
89
- jpeg: FileImage,
90
- gif: FileImage,
91
- svg: FileImage
92
- };
93
- function getFileIcon(name) {
94
- const ext = name.split(".").pop()?.toLowerCase() || "";
95
- return FILE_ICONS[ext] || File;
96
- }
97
- function getFileColor(name) {
98
- const ext = name.split(".").pop()?.toLowerCase() || "";
99
- switch (ext) {
100
- case "pdf":
101
- return "text-red-400";
102
- case "py":
103
- return "text-yellow-400";
104
- case "ts":
105
- case "js":
106
- return "text-blue-400";
107
- case "json":
108
- return "text-green-400";
109
- case "yaml":
110
- case "yml":
111
- return "text-[var(--accent-text)]";
112
- case "csv":
113
- case "xlsx":
114
- return "text-emerald-400";
115
- case "md":
116
- return "text-foreground";
117
- default:
118
- return "text-muted-foreground";
119
- }
120
- }
121
- function TreeNode({ node, depth, selectedPath, onSelect, defaultExpanded }) {
122
- const [expanded, setExpanded] = useState(defaultExpanded);
123
- const isSelected = node.path === selectedPath;
124
- const isDir = node.type === "directory";
125
- const handleClick = () => {
126
- if (isDir) {
127
- setExpanded(!expanded);
128
- }
129
- onSelect?.(node.path, node);
130
- };
131
- const Icon = isDir ? expanded ? FolderOpen : Folder : getFileIcon(node.name);
132
- const iconColor = isDir ? "text-primary" : getFileColor(node.name);
133
- return /* @__PURE__ */ jsxs("div", { children: [
134
- /* @__PURE__ */ jsxs(
135
- "button",
136
- {
137
- type: "button",
138
- className: cn(
139
- "flex items-center gap-1.5 w-full text-left px-2 py-[2px] cursor-pointer text-[13px] transition-colors",
140
- "appearance-none bg-transparent border-none",
141
- "hover:bg-accent",
142
- isSelected ? "bg-primary/15 text-foreground" : "text-foreground"
143
- ),
144
- style: { paddingLeft: `${depth * 16 + 8}px` },
145
- onClick: handleClick,
146
- "aria-expanded": isDir ? expanded : void 0,
147
- children: [
148
- isDir && /* @__PURE__ */ jsx(
149
- ChevronRight,
150
- {
151
- className: cn(
152
- "h-3 w-3 shrink-0 text-muted-foreground transition-transform",
153
- expanded && "rotate-90"
154
- )
155
- }
156
- ),
157
- !isDir && /* @__PURE__ */ jsx("span", { className: "w-3" }),
158
- /* @__PURE__ */ jsx(Icon, { className: cn("h-4 w-4 shrink-0", iconColor) }),
159
- /* @__PURE__ */ jsx("span", { className: "truncate", children: node.name }),
160
- node.size !== void 0 && !isDir && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-xs ml-auto tabular-nums", children: formatSize(node.size) })
161
- ]
162
- }
163
- ),
164
- isDir && expanded && node.children && /* @__PURE__ */ jsx("div", { children: node.children.sort((a, b) => {
165
- if (a.type !== b.type) return a.type === "directory" ? -1 : 1;
166
- return a.name.localeCompare(b.name);
167
- }).map((child) => /* @__PURE__ */ jsx(
168
- TreeNode,
169
- {
170
- node: child,
171
- depth: depth + 1,
172
- selectedPath,
173
- onSelect,
174
- defaultExpanded
175
- },
176
- child.path
177
- )) })
178
- ] });
179
- }
180
- function formatSize(bytes) {
181
- if (bytes < 1024) return `${bytes}B`;
182
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)}K`;
183
- return `${(bytes / (1024 * 1024)).toFixed(1)}M`;
184
- }
185
- function FileTree({
186
- root,
187
- selectedPath,
188
- onSelect,
189
- className,
190
- defaultExpanded = true,
191
- visibility
192
- }) {
193
- const visibleRoot = filterFileTree(root, visibility);
194
- if (!visibleRoot) {
195
- return null;
196
- }
197
- return /* @__PURE__ */ jsx("div", { className: cn("text-sm font-sans", className), children: visibleRoot.children ? visibleRoot.children.sort((a, b) => {
198
- if (a.type !== b.type) return a.type === "directory" ? -1 : 1;
199
- return a.name.localeCompare(b.name);
200
- }).map((child) => /* @__PURE__ */ jsx(
201
- TreeNode,
202
- {
203
- node: child,
204
- depth: 0,
205
- selectedPath,
206
- onSelect,
207
- defaultExpanded
208
- },
209
- child.path
210
- )) : /* @__PURE__ */ jsx(
211
- TreeNode,
212
- {
213
- node: visibleRoot,
214
- depth: 0,
215
- selectedPath,
216
- onSelect,
217
- defaultExpanded
218
- }
219
- ) });
220
- }
221
-
222
- // src/files/rich-file-tree.tsx
223
- import {
224
- FileTree as PierreFileTree,
225
- useFileTree as usePierreFileTree
226
- } from "@pierre/trees/react";
227
- import { useEffect, useMemo } from "react";
228
- import { jsx as jsx2 } from "react/jsx-runtime";
229
- function cssVarFromToken(name) {
230
- return `var(${name})`;
231
- }
232
- var DEFAULT_THEME = {
233
- selectedBg: cssVarFromToken("--accent-surface-soft"),
234
- selectedFg: cssVarFromToken("--accent-text"),
235
- fg: cssVarFromToken("--foreground"),
236
- hoverBg: cssVarFromToken("--muted"),
237
- border: cssVarFromToken("--border"),
238
- mutedFg: cssVarFromToken("--muted-foreground")
239
- };
240
- function flattenFileNode(node, out = []) {
241
- if (node.type === "file" && node.path) {
242
- out.push(node.path);
243
- return out;
244
- }
245
- if (node.type === "directory") {
246
- if (node.children?.length) {
247
- for (const child of node.children) {
248
- flattenFileNode(child, out);
249
- }
250
- return out;
251
- }
252
- if (node.path) out.push(`${node.path}/`);
253
- }
254
- return out;
255
- }
256
- function RichFileTree({
257
- root,
258
- paths,
259
- selectedPath,
260
- onSelect,
261
- search = true,
262
- initialExpansion = "open",
263
- gitStatus,
264
- renderContextMenu,
265
- header,
266
- themeOverrides,
267
- className,
268
- style,
269
- height
270
- }) {
271
- if (root && paths) {
272
- throw new Error("RichFileTree: pass `root` or `paths`, not both");
273
- }
274
- const flatPaths = useMemo(() => {
275
- if (paths) return Array.from(paths);
276
- if (root) return flattenFileNode(root);
277
- return [];
278
- }, [paths, root]);
279
- const { model } = usePierreFileTree({
280
- paths: flatPaths,
281
- search,
282
- initialExpansion,
283
- onSelectionChange: (selected) => {
284
- const next = selected[0];
285
- if (next && next !== selectedPath) onSelect?.(next);
286
- }
287
- });
288
- useEffect(() => {
289
- if (!gitStatus) return;
290
- model.setGitStatus(gitStatus);
291
- }, [model, gitStatus]);
292
- useEffect(() => {
293
- model.resetPaths(flatPaths);
294
- }, [model, flatPaths]);
295
- useEffect(() => {
296
- if (!selectedPath) return;
297
- const current = model.getSelectedPaths();
298
- if (current.length === 1 && current[0] === selectedPath) return;
299
- const m = model;
300
- m.setSelectedPaths?.([selectedPath]);
301
- }, [model, selectedPath]);
302
- const theme = { ...DEFAULT_THEME, ...themeOverrides };
303
- const themeStyle = useMemo(
304
- () => ({
305
- ["--trees-selected-bg-override"]: theme.selectedBg,
306
- ["--trees-selected-fg-override"]: theme.selectedFg,
307
- ["--trees-fg-override"]: theme.fg,
308
- ["--trees-hover-bg-override"]: theme.hoverBg,
309
- ["--trees-border-color-override"]: theme.border,
310
- ["--trees-muted-fg-override"]: theme.mutedFg,
311
- height: height ?? "100%",
312
- ...style
313
- }),
314
- [theme, height, style]
315
- );
316
- return /* @__PURE__ */ jsx2(
317
- PierreFileTree,
318
- {
319
- model,
320
- header,
321
- renderContextMenu,
322
- className,
323
- style: themeStyle
324
- }
325
- );
326
- }
327
-
328
- // src/files/file-preview.tsx
329
- import { useState as useState2 } from "react";
330
- import {
331
- Download,
332
- FileSpreadsheet as FileSpreadsheet2,
333
- FileText as FileText2,
334
- Music,
335
- X
336
- } from "lucide-react";
337
- import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
338
- var CSV_PREVIEW_ROW_LIMIT = 500;
339
- var NEEDS_DOWNLOAD_LINK = "This file needs a download link to preview.";
340
- var NO_INLINE_PREVIEW = "This file type has no inline preview.";
341
- var NO_INLINE_CONTENT = "This file has no inline content to preview yet.";
342
- function CodePreview({
343
- content,
344
- filename,
345
- kind
346
- }) {
347
- const lineCount = content.split("\n").length;
348
- const language = getCodeLanguage(filename, kind);
349
- const labelToken = fileExtension(filename) || language || "txt";
350
- return /* @__PURE__ */ jsx3(
351
- CodeBlock,
352
- {
353
- code: content,
354
- language,
355
- label: `${labelToken} \xB7 ${lineCount} lines`,
356
- showLineNumbers: true,
357
- className: "max-h-[70vh] overflow-auto",
358
- children: /* @__PURE__ */ jsx3(CopyButton, { text: content })
359
- }
360
- );
361
- }
362
- function parseCsv(content) {
363
- const rows = [];
364
- let row = [];
365
- let cell = "";
366
- let quoted = false;
367
- let inQuotes = false;
368
- const endCell = () => {
369
- row.push(quoted ? cell : cell.trim());
370
- cell = "";
371
- quoted = false;
372
- };
373
- const endRow = () => {
374
- endCell();
375
- if (row.length > 1 || row[0] !== "") rows.push(row);
376
- row = [];
377
- };
378
- for (let index = 0; index < content.length; index += 1) {
379
- const char = content[index];
380
- if (inQuotes) {
381
- if (char === '"') {
382
- if (content[index + 1] === '"') {
383
- cell += '"';
384
- index += 1;
385
- } else {
386
- inQuotes = false;
387
- }
388
- } else {
389
- cell += char;
390
- }
391
- continue;
392
- }
393
- if (char === '"') {
394
- inQuotes = true;
395
- quoted = true;
396
- continue;
397
- }
398
- if (char === ",") {
399
- endCell();
400
- continue;
401
- }
402
- if (char === "\r" || char === "\n") {
403
- if (char === "\r" && content[index + 1] === "\n") index += 1;
404
- endRow();
405
- continue;
406
- }
407
- cell += char;
408
- }
409
- if (cell.length > 0 || quoted || row.length > 0) endRow();
410
- return rows;
411
- }
412
- function CsvPreview({ content }) {
413
- const [headers = [], ...body] = parseCsv(content);
414
- if (headers.length === 0) return null;
415
- const visible = body.slice(0, CSV_PREVIEW_ROW_LIMIT);
416
- const columnCount = Math.max(headers.length, ...visible.map((cells) => cells.length));
417
- const capped = body.length > visible.length;
418
- return /* @__PURE__ */ jsxs2("div", { className: "flex min-h-0 flex-1 flex-col gap-2", children: [
419
- /* @__PURE__ */ jsx3("div", { className: "min-h-0 overflow-auto rounded-[var(--radius-md)] border border-border", children: /* @__PURE__ */ jsxs2("table", { className: "w-full text-sm", children: [
420
- /* @__PURE__ */ jsx3("thead", { children: /* @__PURE__ */ jsx3("tr", { children: Array.from({ length: columnCount }, (_, column) => /* @__PURE__ */ jsx3(
421
- "th",
422
- {
423
- className: "sticky top-0 whitespace-nowrap border-b border-border bg-card px-3 py-2 text-left text-xs font-semibold text-foreground",
424
- children: headers[column] ?? ""
425
- },
426
- column
427
- )) }) }),
428
- /* @__PURE__ */ jsx3("tbody", { children: visible.map((cells, rowIndex) => /* @__PURE__ */ jsx3("tr", { className: "border-b border-border hover:bg-accent", children: Array.from({ length: columnCount }, (_, column) => /* @__PURE__ */ jsx3(
429
- "td",
430
- {
431
- className: "whitespace-nowrap px-3 py-1.5 font-mono text-xs text-foreground",
432
- children: cells[column] ?? ""
433
- },
434
- column
435
- )) }, rowIndex)) })
436
- ] }) }),
437
- /* @__PURE__ */ jsxs2("p", { className: "shrink-0 text-xs text-muted-foreground", children: [
438
- capped ? `Showing ${visible.length} of ${body.length} rows` : `${body.length} ${body.length === 1 ? "row" : "rows"}`,
439
- ` \xB7 ${columnCount} ${columnCount === 1 ? "column" : "columns"}`
440
- ] })
441
- ] });
442
- }
443
- var CHECKER_STYLE = {
444
- backgroundColor: "var(--color-background)",
445
- backgroundImage: "repeating-conic-gradient(var(--color-muted) 0% 25%, transparent 0% 50%)",
446
- backgroundSize: "16px 16px"
447
- };
448
- function ImagePreview({ src, filename }) {
449
- const [naturalSize, setNaturalSize] = useState2(false);
450
- return /* @__PURE__ */ jsx3(
451
- "div",
452
- {
453
- className: "flex min-h-[12rem] flex-1 overflow-auto rounded-[var(--radius-md)] border border-border",
454
- style: CHECKER_STYLE,
455
- children: /* @__PURE__ */ jsx3(
456
- "button",
457
- {
458
- type: "button",
459
- onClick: () => setNaturalSize((value) => !value),
460
- "aria-pressed": naturalSize,
461
- "aria-label": naturalSize ? "Fit image to pane" : "Show image at natural size",
462
- className: cn(
463
- "flex items-center justify-center",
464
- focusRingInset,
465
- naturalSize ? "m-auto cursor-zoom-out" : "h-full w-full cursor-zoom-in p-4"
466
- ),
467
- children: /* @__PURE__ */ jsx3(
468
- "img",
469
- {
470
- src,
471
- alt: filename,
472
- draggable: false,
473
- className: naturalSize ? "max-w-none" : "max-h-full max-w-full object-contain"
474
- }
475
- )
476
- }
477
- )
478
- }
479
- );
480
- }
481
- function PdfPreview({
482
- blobUrl,
483
- filename,
484
- size,
485
- onDownload
486
- }) {
487
- return /* @__PURE__ */ jsx3(
488
- "object",
489
- {
490
- data: blobUrl,
491
- type: "application/pdf",
492
- title: filename,
493
- className: "min-h-[24rem] w-full flex-1 rounded-[var(--radius-md)]",
494
- children: /* @__PURE__ */ jsx3(
495
- DownloadCard,
496
- {
497
- filename,
498
- size,
499
- sentence: "This browser does not show PDFs inline.",
500
- onDownload,
501
- className: "h-full"
502
- }
503
- )
504
- }
505
- );
506
- }
507
- function VideoPreview({ src, filename }) {
508
- return /* @__PURE__ */ jsx3("div", { className: "flex min-h-[12rem] flex-1 items-center justify-center overflow-hidden rounded-[var(--radius-md)] border border-border bg-background", children: /* @__PURE__ */ jsx3(
509
- "video",
510
- {
511
- controls: true,
512
- preload: "metadata",
513
- src,
514
- "aria-label": filename,
515
- className: "max-h-full max-w-full"
516
- }
517
- ) });
518
- }
519
- function AudioPreview({ src, filename }) {
520
- return /* @__PURE__ */ jsxs2("div", { className: "flex flex-col items-center gap-4 rounded-[var(--radius-md)] border border-border bg-background px-6 py-10", children: [
521
- /* @__PURE__ */ jsx3(Music, { className: "h-10 w-10 text-muted-foreground opacity-60" }),
522
- /* @__PURE__ */ jsx3("p", { className: "max-w-full truncate text-sm font-medium text-foreground", children: filename }),
523
- /* @__PURE__ */ jsx3("audio", { controls: true, preload: "metadata", src, "aria-label": filename, className: "w-full max-w-md" })
524
- ] });
525
- }
526
- function TextPreview({ content }) {
527
- return /* @__PURE__ */ jsx3("pre", { 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]", children: content });
528
- }
529
- function MarkdownPreview({ content }) {
530
- return /* @__PURE__ */ jsx3("div", { className: "rounded-[var(--radius-md)] border border-border bg-background p-5", children: /* @__PURE__ */ jsx3(Markdown, { children: content }) });
531
- }
532
- function DownloadCard({
533
- filename,
534
- size,
535
- sentence,
536
- icon: Icon = FileText2,
537
- onDownload,
538
- className
539
- }) {
540
- return /* @__PURE__ */ jsxs2(
541
- "div",
542
- {
543
- className: cn(
544
- "flex flex-col items-center justify-center rounded-[var(--radius-md)] border border-dashed border-border bg-background px-6 py-16 text-center",
545
- className
546
- ),
547
- children: [
548
- /* @__PURE__ */ jsx3(Icon, { className: "mb-3 h-12 w-12 text-muted-foreground opacity-40" }),
549
- /* @__PURE__ */ jsx3("p", { className: "max-w-full truncate text-sm font-medium text-foreground", children: filename }),
550
- size !== void 0 && /* @__PURE__ */ jsx3("p", { className: "mt-1 text-xs text-muted-foreground", children: formatBytes(size) }),
551
- /* @__PURE__ */ jsx3("p", { className: "mt-3 max-w-md text-sm text-muted-foreground", children: sentence }),
552
- onDownload && /* @__PURE__ */ jsxs2(Button, { type: "button", variant: "outline", size: "sm", className: "mt-5", onClick: onDownload, children: [
553
- /* @__PURE__ */ jsx3(Download, {}),
554
- "Download"
555
- ] })
556
- ]
557
- }
558
- );
559
- }
560
- function PreviewBody({
561
- kind,
562
- filename,
563
- content,
564
- blobUrl,
565
- size,
566
- onDownload
567
- }) {
568
- const hasText = typeof content === "string";
569
- const card = (sentence, icon) => /* @__PURE__ */ jsx3(
570
- DownloadCard,
571
- {
572
- filename,
573
- size,
574
- sentence,
575
- icon,
576
- onDownload
577
- }
578
- );
579
- switch (kind) {
580
- case "pdf":
581
- if (blobUrl) {
582
- return /* @__PURE__ */ jsx3(PdfPreview, { blobUrl, filename, size, onDownload });
583
- }
584
- return card(NEEDS_DOWNLOAD_LINK);
585
- case "image":
586
- if (blobUrl) return /* @__PURE__ */ jsx3(ImagePreview, { src: blobUrl, filename });
587
- if (hasText) return /* @__PURE__ */ jsx3(CodePreview, { content, filename, kind: "code" });
588
- return card(NEEDS_DOWNLOAD_LINK);
589
- case "video":
590
- if (blobUrl) return /* @__PURE__ */ jsx3(VideoPreview, { src: blobUrl, filename });
591
- return card(NEEDS_DOWNLOAD_LINK);
592
- case "audio":
593
- if (blobUrl) return /* @__PURE__ */ jsx3(AudioPreview, { src: blobUrl, filename });
594
- return card(NEEDS_DOWNLOAD_LINK, Music);
595
- case "csv":
596
- if (hasText) return /* @__PURE__ */ jsx3(CsvPreview, { content });
597
- return card(NO_INLINE_CONTENT, FileSpreadsheet2);
598
- case "code":
599
- case "json":
600
- case "yaml":
601
- if (hasText) return /* @__PURE__ */ jsx3(CodePreview, { content, filename, kind });
602
- return card(NO_INLINE_CONTENT);
603
- case "markdown":
604
- if (hasText) return /* @__PURE__ */ jsx3(MarkdownPreview, { content });
605
- return card(NO_INLINE_CONTENT);
606
- case "text":
607
- if (hasText) return /* @__PURE__ */ jsx3(TextPreview, { content });
608
- return card(NO_INLINE_CONTENT);
609
- case "spreadsheet":
610
- return card("Download to open this workbook in a spreadsheet app.", FileSpreadsheet2);
611
- case "binary":
612
- if (hasText) return /* @__PURE__ */ jsx3(TextPreview, { content });
613
- return card(blobUrl ? NO_INLINE_PREVIEW : NEEDS_DOWNLOAD_LINK);
614
- }
615
- }
616
- function FilePreview({
617
- filename,
618
- content,
619
- blobUrl,
620
- mimeType,
621
- size,
622
- onClose,
623
- onDownload,
624
- hideHeader = false,
625
- className
626
- }) {
627
- const kind = resolveFilePreviewKind(filename, mimeType);
628
- const previewLabel = getFormatLabel(kind);
629
- return /* @__PURE__ */ jsxs2("div", { className: cn("flex flex-col h-full", className), children: [
630
- !hideHeader && /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-border shrink-0", children: [
631
- /* @__PURE__ */ jsxs2("div", { className: "min-w-0 flex-1", children: [
632
- /* @__PURE__ */ jsx3("div", { className: "truncate text-sm font-medium text-foreground", children: filename }),
633
- /* @__PURE__ */ jsx3("div", { className: "mt-0.5 text-[11px] uppercase tracking-[0.12em] text-muted-foreground", children: previewLabel })
634
- ] }),
635
- onDownload && /* @__PURE__ */ jsx3(
636
- "button",
637
- {
638
- type: "button",
639
- onClick: onDownload,
640
- "aria-label": `Download ${filename}`,
641
- className: "p-1.5 rounded-[var(--radius-sm)] hover:bg-accent text-muted-foreground hover:text-foreground transition-colors",
642
- children: /* @__PURE__ */ jsx3(Download, { className: "h-4 w-4" })
643
- }
644
- ),
645
- onClose && /* @__PURE__ */ jsx3(
646
- "button",
647
- {
648
- type: "button",
649
- onClick: onClose,
650
- "aria-label": `Close ${filename}`,
651
- className: "p-1.5 rounded-[var(--radius-sm)] hover:bg-accent text-muted-foreground hover:text-foreground transition-colors",
652
- children: /* @__PURE__ */ jsx3(X, { className: "h-4 w-4" })
653
- }
654
- )
655
- ] }),
656
- /* @__PURE__ */ jsx3("div", { className: "flex min-h-0 flex-1 flex-col overflow-auto p-3", children: /* @__PURE__ */ jsx3(
657
- PreviewBody,
658
- {
659
- kind,
660
- filename,
661
- content,
662
- blobUrl,
663
- size,
664
- onDownload
665
- }
666
- ) })
667
- ] });
668
- }
669
-
670
- // src/files/file-tabs.tsx
671
- import { X as X2, FileText as FileText3, FileCode as FileCode2, FileSpreadsheet as FileSpreadsheet3 } from "lucide-react";
672
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
673
- function getTabIcon(name) {
674
- const ext = name.split(".").pop()?.toLowerCase() || "";
675
- if (["pdf"].includes(ext)) return FileText3;
676
- if (["csv", "xlsx"].includes(ext)) return FileSpreadsheet3;
677
- return FileCode2;
678
- }
679
- function FileTabs({ tabs, activeId, onSelect, onClose, className }) {
680
- if (tabs.length === 0) return null;
681
- return /* @__PURE__ */ jsx4("div", { className: cn("flex items-center border-b border-border bg-background overflow-x-auto", className), children: tabs.map((tab) => {
682
- const isActive = tab.id === activeId;
683
- const Icon = getTabIcon(tab.name);
684
- return /* @__PURE__ */ jsxs3(
685
- "div",
686
- {
687
- className: cn(
688
- "group flex items-center border-r border-border shrink-0",
689
- isActive ? "bg-card text-foreground border-b-2 border-b-primary" : "text-muted-foreground hover:bg-muted/50"
690
- ),
691
- children: [
692
- /* @__PURE__ */ jsxs3(
693
- "button",
694
- {
695
- type: "button",
696
- onClick: () => onSelect(tab.id),
697
- className: cn(
698
- "flex min-w-0 items-center gap-1.5 px-3 py-1.5 text-xs transition-colors hover:text-foreground",
699
- focusRingInset
700
- ),
701
- children: [
702
- /* @__PURE__ */ jsx4(Icon, { className: "h-3 w-3 shrink-0" }),
703
- /* @__PURE__ */ jsx4("span", { className: "max-w-[120px] truncate", children: tab.name }),
704
- tab.dirty && /* @__PURE__ */ jsx4("span", { className: "h-1.5 w-1.5 rounded-full bg-primary" })
705
- ]
706
- }
707
- ),
708
- /* @__PURE__ */ jsx4(
709
- "button",
710
- {
711
- type: "button",
712
- "aria-label": `Close ${tab.name}`,
713
- onClick: () => onClose(tab.id),
714
- className: cn(
715
- "mr-1 rounded p-0.5 opacity-0 transition-opacity hover:bg-accent focus-visible:opacity-100 group-hover:opacity-100",
716
- focusRing
717
- ),
718
- children: /* @__PURE__ */ jsx4(X2, { className: "h-2.5 w-2.5" })
719
- }
720
- )
721
- ]
722
- },
723
- tab.id
724
- );
725
- }) });
726
- }
727
-
728
- // src/files/file-artifact-pane.tsx
729
- import { lazy, Suspense } from "react";
730
- import { Download as Download2, X as X3 } from "lucide-react";
731
- import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
732
- var LazyDocumentEditorPane = lazy(async () => {
733
- const module = await import("./document-editor-pane-QHDOBA43.js");
734
- return { default: module.DocumentEditorPane };
735
- });
736
- function FileArtifactPane({
737
- filename,
738
- content,
739
- blobUrl,
740
- mimeType,
741
- size,
742
- onClose,
743
- onDownload,
744
- path,
745
- tabs = [],
746
- activeTabId,
747
- onTabSelect,
748
- onTabClose,
749
- eyebrow = "Artifact",
750
- meta,
751
- toolbar,
752
- footer,
753
- className,
754
- headerClassName,
755
- hideTitleBlock,
756
- editor
757
- }) {
758
- const showTabs = tabs.length > 0 && onTabSelect && onTabClose;
759
- const paneTabs = showTabs ? /* @__PURE__ */ jsx5(
760
- FileTabs,
761
- {
762
- tabs,
763
- activeId: activeTabId,
764
- onSelect: onTabSelect,
765
- onClose: onTabClose
766
- }
767
- ) : void 0;
768
- const isMarkdown = detectFileFormat(filename, mimeType) === "markdown" || (path ? detectFileFormat(path, mimeType) === "markdown" : false);
769
- const isEditableMarkdown = isMarkdown && editor?.enabled;
770
- const headerActions = onDownload || onClose ? /* @__PURE__ */ jsxs4(Fragment, { children: [
771
- onDownload && /* @__PURE__ */ jsx5(
772
- "button",
773
- {
774
- type: "button",
775
- "aria-label": `Download ${filename}`,
776
- onClick: onDownload,
777
- className: `rounded-[var(--radius-sm)] p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing}`,
778
- children: /* @__PURE__ */ jsx5(Download2, { className: "h-4 w-4" })
779
- }
780
- ),
781
- onClose && /* @__PURE__ */ jsx5(
782
- "button",
783
- {
784
- type: "button",
785
- "aria-label": `Close ${filename}`,
786
- onClick: onClose,
787
- className: `rounded-[var(--radius-sm)] p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing}`,
788
- children: /* @__PURE__ */ jsx5(X3, { className: "h-4 w-4" })
789
- }
790
- )
791
- ] }) : void 0;
792
- if (isEditableMarkdown) {
793
- return /* @__PURE__ */ jsx5(
794
- Suspense,
795
- {
796
- fallback: /* @__PURE__ */ jsx5(
797
- ArtifactPane,
798
- {
799
- eyebrow,
800
- title: filename,
801
- subtitle: path,
802
- meta,
803
- toolbar,
804
- footer,
805
- className,
806
- tabs: paneTabs,
807
- headerActions,
808
- headerClassName,
809
- hideTitleBlock,
810
- children: /* @__PURE__ */ jsx5("div", { 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", children: "Loading editor\u2026" })
811
- }
812
- ),
813
- children: /* @__PURE__ */ jsx5(
814
- LazyDocumentEditorPane,
815
- {
816
- eyebrow,
817
- title: filename,
818
- subtitle: path,
819
- meta,
820
- toolbar,
821
- footer,
822
- className,
823
- tabs: paneTabs,
824
- headerActions,
825
- headerClassName,
826
- hideTitleBlock,
827
- markdown: content ?? "",
828
- mode: editor.mode,
829
- defaultMode: editor.defaultMode,
830
- onModeChange: editor.onModeChange,
831
- backend: editor.backend,
832
- collaboration: editor.collaboration,
833
- placeholder: editor.placeholder,
834
- autoFocus: editor.autoFocus,
835
- readOnly: editor.readOnly,
836
- saving: editor.saving,
837
- saveLabel: editor.saveLabel,
838
- onChange: editor.onChange,
839
- onSave: editor.onSave,
840
- previewClassName: editor.previewClassName,
841
- editorClassName: editor.editorClassName
842
- }
843
- )
844
- }
845
- );
846
- }
847
- return /* @__PURE__ */ jsx5(
848
- ArtifactPane,
849
- {
850
- eyebrow,
851
- title: filename,
852
- subtitle: path,
853
- meta,
854
- toolbar,
855
- footer,
856
- className,
857
- tabs: paneTabs,
858
- headerActions,
859
- headerClassName,
860
- hideTitleBlock,
861
- children: /* @__PURE__ */ jsx5(
862
- FilePreview,
863
- {
864
- filename,
865
- content,
866
- blobUrl,
867
- mimeType,
868
- size,
869
- onDownload,
870
- hideHeader: true
871
- }
872
- )
873
- }
874
- );
875
- }
876
-
877
- export {
878
- filterFileTree,
879
- FileTree,
880
- RichFileTree,
881
- CSV_PREVIEW_ROW_LIMIT,
882
- parseCsv,
883
- FilePreview,
884
- FileTabs,
885
- FileArtifactPane
886
- };