@tangle-network/ui 1.0.1 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -0
- package/dist/chat.js +8 -7
- package/dist/{chunk-TMFOPHHN.js → chunk-52Y3FMFI.js} +2 -2
- package/dist/{chunk-7UO2ZMRQ.js → chunk-5VPTNXX7.js} +2 -2
- package/dist/{chunk-XIHMJ7ZQ.js → chunk-AAUNOHVL.js} +5 -30
- package/dist/{chunk-YJ2G3XO5.js → chunk-CMX2I43A.js} +1 -1
- package/dist/{chunk-2VH6PUXD.js → chunk-DGW77LD7.js} +1 -1
- package/dist/{chunk-CD53GZOM.js → chunk-FJBTCTZM.js} +1 -1
- package/dist/{chunk-YNN4O57I.js → chunk-JBPWIYTQ.js} +4 -4
- package/dist/{chunk-2NFQRQOD.js → chunk-KT5RNO7N.js} +4 -4
- package/dist/{chunk-HJKCSXCH.js → chunk-LELGOLFV.js} +44 -78
- package/dist/{chunk-EEE55AVS.js → chunk-SZ44QDA6.js} +1 -1
- package/dist/{chunk-66BNMOVT.js → chunk-WUQDUBJG.js} +5 -4
- package/dist/chunk-ZRVH3WCA.js +107 -0
- package/dist/{code-block-DjXf8eOG.d.ts → code-block-0kSpWMnf.d.ts} +7 -1
- package/dist/{document-editor-pane-A5LT5H4N.js → document-editor-pane-WCTA3ZOE.js} +3 -3
- package/dist/editor.js +3 -4
- package/dist/files.d.ts +39 -2
- package/dist/files.js +16 -4
- package/dist/hooks.js +5 -5
- package/dist/index.d.ts +46 -7
- package/dist/index.js +120 -37
- package/dist/markdown.d.ts +1 -1
- package/dist/markdown.js +2 -2
- package/dist/nav.d.ts +25 -0
- package/dist/nav.js +16 -0
- package/dist/openui.js +3 -3
- package/dist/primitives.d.ts +1 -1
- package/dist/primitives.js +1 -1
- package/dist/run.js +8 -7
- package/dist/sdk-hooks.js +5 -5
- package/dist/tool-previews.js +3 -2
- package/package.json +13 -3
- package/src/files/file-artifact-pane.tsx +3 -3
- package/src/files/file-format.test.ts +176 -0
- package/src/files/file-format.ts +167 -0
- package/src/files/file-preview.stories.tsx +87 -0
- package/src/files/file-preview.test.tsx +52 -0
- package/src/files/file-preview.tsx +48 -94
- package/src/files/index.ts +8 -0
- package/src/index.ts +1 -2
- package/src/markdown/code-block.test.tsx +62 -0
- package/src/markdown/code-block.tsx +11 -4
- package/src/nav/index.tsx +34 -0
- package/src/redaction/index.ts +7 -0
- package/src/redaction/redacted-document.tsx +150 -0
- package/src/tool-previews/write-file-preview.tsx +2 -30
- package/dist/chunk-Q7EIIWTC.js +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,66 @@
|
|
|
1
1
|
# @tangle-network/ui
|
|
2
2
|
|
|
3
|
+
## 4.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- d7a442d: Share theme-aware file-format rendering across the preview and artifact surfaces. `FilePreview` now routes `code`/`json`/`yaml` through the same theme-aware `CodeBlock` the chat markdown renderer uses, so code is syntax-highlighted and theme-consistent in the artifact pane instead of monochrome. A new `files/file-format` module (`detectFileFormat`, `getFormatLabel`, `getSyntaxLanguage`, `fileExtension`) is the single source of truth for extension/MIME detection, consumed by `FilePreview`, `FileArtifactPane`, and `WriteFilePreview`. `CodeBlock` gains an optional `label` prop to display a header name independent of the highlight language.
|
|
8
|
+
|
|
9
|
+
## 4.0.0
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [184c8bb]
|
|
14
|
+
- @tangle-network/brand@0.5.0
|
|
15
|
+
|
|
16
|
+
## 3.0.0
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- Updated dependencies [8152d92]
|
|
21
|
+
- @tangle-network/brand@0.4.0
|
|
22
|
+
|
|
23
|
+
## 2.1.0
|
|
24
|
+
|
|
25
|
+
### Minor Changes
|
|
26
|
+
|
|
27
|
+
- 12f5565: Add `<RedactedDocument>` viewer (`@tangle-network/ui/redaction`): renders a server-produced redacted document with masked, click-to-reveal spans. The client holds only `{ id, kind }` per span; revealing one round-trips through an `onReveal` callback so authorization and the audit trail stay server-side (pairs with `@tangle-network/agent-app/redact`'s `buildRedactedDocument` / `revealSpan`).
|
|
28
|
+
|
|
29
|
+
## 2.0.0
|
|
30
|
+
|
|
31
|
+
### Major Changes
|
|
32
|
+
|
|
33
|
+
- 4d7cc77: Drop `editor` re-exports from `@tangle-network/ui` root barrel. The `@tangle-network/ui/editor` subpath is unchanged.
|
|
34
|
+
|
|
35
|
+
**Rationale:** the editor surface drags `@tiptap/*`, `yjs`, and `@hocuspocus/provider` type chains into the package root's `.d.ts`. These are specialized collaboration tooling, not generic UI primitives — they should not appear in a consumer's default import.
|
|
36
|
+
|
|
37
|
+
**Migration:**
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
// before
|
|
41
|
+
import {
|
|
42
|
+
TiptapEditor,
|
|
43
|
+
EditorToolbar,
|
|
44
|
+
DocumentEditorPane,
|
|
45
|
+
} from "@tangle-network/ui";
|
|
46
|
+
|
|
47
|
+
// after
|
|
48
|
+
import {
|
|
49
|
+
TiptapEditor,
|
|
50
|
+
EditorToolbar,
|
|
51
|
+
DocumentEditorPane,
|
|
52
|
+
} from "@tangle-network/ui/editor";
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`sed` recipe:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
grep -rl '"@tangle-network/ui"' src/ \
|
|
59
|
+
| xargs sed -i '' -E '/Tiptap|Editor|Collaborat|useYjs|useAwareness|DocumentEditor|ConnectionState/s|"@tangle-network/ui"|"@tangle-network/ui/editor"|g'
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Known residual:** `dist/index.d.ts` still emits type-only side-effect imports for `@hocuspocus/provider` and `yjs`. These come from `FileArtifactPaneEditorOptions` in `files/file-artifact-pane.tsx`, which types its optional collaboration config against `DocumentEditorMode`/`DocumentEditorBackend`/`DocumentEditorPaneCollaborationConfig` from `editor/`. The actual editor symbols (`TiptapEditor`, `EditorProvider`, etc.) and `@tiptap/*` types are no longer at the root. A follow-up PR can either extract the editor option types out of `editor/` or drop `./files` from the root barrel; both exceed this PR's scope.
|
|
63
|
+
|
|
3
64
|
## 1.0.1
|
|
4
65
|
|
|
5
66
|
### Patch Changes
|
package/dist/chat.js
CHANGED
|
@@ -6,18 +6,19 @@ import {
|
|
|
6
6
|
MessageList,
|
|
7
7
|
ThinkingIndicator,
|
|
8
8
|
UserMessage
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-KT5RNO7N.js";
|
|
10
10
|
import "./chunk-54SQQMMM.js";
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-JBPWIYTQ.js";
|
|
12
|
+
import "./chunk-DGW77LD7.js";
|
|
13
13
|
import "./chunk-4CLN43XT.js";
|
|
14
14
|
import "./chunk-BX6AQMUS.js";
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-AAUNOHVL.js";
|
|
16
|
+
import "./chunk-52Y3FMFI.js";
|
|
17
17
|
import "./chunk-GYPQXTJU.js";
|
|
18
18
|
import "./chunk-MKTSMWVD.js";
|
|
19
|
-
import "./chunk-
|
|
20
|
-
import "./chunk-
|
|
19
|
+
import "./chunk-ZRVH3WCA.js";
|
|
20
|
+
import "./chunk-FJBTCTZM.js";
|
|
21
|
+
import "./chunk-WUQDUBJG.js";
|
|
21
22
|
import "./chunk-RQHJBTEU.js";
|
|
22
23
|
export {
|
|
23
24
|
AgentTimeline,
|
|
@@ -17,10 +17,10 @@ import {
|
|
|
17
17
|
} from "./chunk-MKTSMWVD.js";
|
|
18
18
|
import {
|
|
19
19
|
Markdown
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-FJBTCTZM.js";
|
|
21
21
|
import {
|
|
22
22
|
CodeBlock
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-WUQDUBJG.js";
|
|
24
24
|
import {
|
|
25
25
|
cn
|
|
26
26
|
} from "./chunk-RQHJBTEU.js";
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getSyntaxLanguage
|
|
3
|
+
} from "./chunk-ZRVH3WCA.js";
|
|
1
4
|
import {
|
|
2
5
|
CodeBlock,
|
|
3
6
|
CopyButton
|
|
4
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-WUQDUBJG.js";
|
|
5
8
|
import {
|
|
6
9
|
cn
|
|
7
10
|
} from "./chunk-RQHJBTEU.js";
|
|
@@ -153,39 +156,11 @@ function extractWriteContent(input) {
|
|
|
153
156
|
const content = String(obj.content ?? obj.contents ?? obj.data ?? "");
|
|
154
157
|
return { path, content };
|
|
155
158
|
}
|
|
156
|
-
function getLanguageFromPath(path) {
|
|
157
|
-
const ext = path.split(".").pop()?.toLowerCase();
|
|
158
|
-
const map = {
|
|
159
|
-
ts: "typescript",
|
|
160
|
-
tsx: "tsx",
|
|
161
|
-
js: "javascript",
|
|
162
|
-
jsx: "jsx",
|
|
163
|
-
rs: "rust",
|
|
164
|
-
py: "python",
|
|
165
|
-
go: "go",
|
|
166
|
-
rb: "ruby",
|
|
167
|
-
json: "json",
|
|
168
|
-
yaml: "yaml",
|
|
169
|
-
yml: "yaml",
|
|
170
|
-
toml: "toml",
|
|
171
|
-
md: "markdown",
|
|
172
|
-
css: "css",
|
|
173
|
-
scss: "scss",
|
|
174
|
-
html: "html",
|
|
175
|
-
sh: "bash",
|
|
176
|
-
bash: "bash",
|
|
177
|
-
zsh: "bash",
|
|
178
|
-
sql: "sql",
|
|
179
|
-
sol: "solidity",
|
|
180
|
-
proto: "protobuf"
|
|
181
|
-
};
|
|
182
|
-
return ext ? map[ext] : void 0;
|
|
183
|
-
}
|
|
184
159
|
var WriteFilePreview = memo2(({ part }) => {
|
|
185
160
|
const write = extractWriteContent(part.state.input);
|
|
186
161
|
if (!write) return null;
|
|
187
162
|
const lineCount = write.content.split("\n").length;
|
|
188
|
-
const language =
|
|
163
|
+
const language = getSyntaxLanguage(write.path);
|
|
189
164
|
return /* @__PURE__ */ jsxs3(
|
|
190
165
|
PreviewCard,
|
|
191
166
|
{
|
|
@@ -15,16 +15,16 @@ import {
|
|
|
15
15
|
QuestionPreview,
|
|
16
16
|
WebSearchPreview,
|
|
17
17
|
WriteFilePreview
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-AAUNOHVL.js";
|
|
19
19
|
import {
|
|
20
20
|
OpenUIArtifactRenderer
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-52Y3FMFI.js";
|
|
22
22
|
import {
|
|
23
23
|
Markdown
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-FJBTCTZM.js";
|
|
25
25
|
import {
|
|
26
26
|
CodeBlock
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-WUQDUBJG.js";
|
|
28
28
|
import {
|
|
29
29
|
cn
|
|
30
30
|
} from "./chunk-RQHJBTEU.js";
|
|
@@ -6,20 +6,20 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
InlineThinkingItem,
|
|
8
8
|
RunGroup
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-JBPWIYTQ.js";
|
|
10
10
|
import {
|
|
11
11
|
ToolCallGroup,
|
|
12
12
|
ToolCallStep
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-DGW77LD7.js";
|
|
14
14
|
import {
|
|
15
15
|
getToolDisplayMetadata
|
|
16
16
|
} from "./chunk-BX6AQMUS.js";
|
|
17
17
|
import {
|
|
18
18
|
OpenUIArtifactRenderer
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-52Y3FMFI.js";
|
|
20
20
|
import {
|
|
21
21
|
Markdown
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-FJBTCTZM.js";
|
|
23
23
|
import {
|
|
24
24
|
cn
|
|
25
25
|
} from "./chunk-RQHJBTEU.js";
|
|
@@ -1,9 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
detectFileFormat,
|
|
3
|
+
fileExtension,
|
|
4
|
+
getCodeLanguage,
|
|
5
|
+
getFormatLabel
|
|
6
|
+
} from "./chunk-ZRVH3WCA.js";
|
|
1
7
|
import {
|
|
2
8
|
ArtifactPane
|
|
3
9
|
} from "./chunk-CSAIKY36.js";
|
|
4
10
|
import {
|
|
5
11
|
Markdown
|
|
6
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-FJBTCTZM.js";
|
|
13
|
+
import {
|
|
14
|
+
CodeBlock,
|
|
15
|
+
CopyButton
|
|
16
|
+
} from "./chunk-WUQDUBJG.js";
|
|
7
17
|
import {
|
|
8
18
|
cn
|
|
9
19
|
} from "./chunk-RQHJBTEU.js";
|
|
@@ -311,69 +321,25 @@ import {
|
|
|
311
321
|
FileText as FileText2
|
|
312
322
|
} from "lucide-react";
|
|
313
323
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
314
|
-
function
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
return "Image";
|
|
334
|
-
case "csv":
|
|
335
|
-
return "CSV";
|
|
336
|
-
case "spreadsheet":
|
|
337
|
-
return "Spreadsheet";
|
|
338
|
-
case "code":
|
|
339
|
-
return "Code";
|
|
340
|
-
case "json":
|
|
341
|
-
return "JSON";
|
|
342
|
-
case "yaml":
|
|
343
|
-
return "YAML";
|
|
344
|
-
case "markdown":
|
|
345
|
-
return "Markdown";
|
|
346
|
-
case "text":
|
|
347
|
-
return "Text";
|
|
348
|
-
default:
|
|
349
|
-
return "File";
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
function CodePreview({ content, filename }) {
|
|
353
|
-
const lines = content.split("\n");
|
|
354
|
-
const language = filename.split(".").pop()?.toUpperCase() || "TXT";
|
|
355
|
-
return /* @__PURE__ */ jsxs2("div", { className: "relative bg-background rounded-[var(--radius-md)] border border-border overflow-hidden", children: [
|
|
356
|
-
/* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between gap-3 border-b border-border px-4 py-2.5", children: [
|
|
357
|
-
/* @__PURE__ */ jsxs2("div", { className: "flex gap-1.5", children: [
|
|
358
|
-
/* @__PURE__ */ jsx3("div", { className: "w-3 h-3 rounded-full bg-[#FF5F57]" }),
|
|
359
|
-
/* @__PURE__ */ jsx3("div", { className: "w-3 h-3 rounded-full bg-[#FEBC2E]" }),
|
|
360
|
-
/* @__PURE__ */ jsx3("div", { className: "w-3 h-3 rounded-full bg-[#8E59FF]" })
|
|
361
|
-
] }),
|
|
362
|
-
/* @__PURE__ */ jsx3("div", { className: "ml-2 min-w-0 flex-1 truncate text-xs font-mono text-muted-foreground", children: filename }),
|
|
363
|
-
/* @__PURE__ */ jsxs2("div", { className: "inline-flex items-center gap-2 rounded-[var(--radius-full)] border border-border bg-card px-2.5 py-1 text-[10px] font-semibold uppercase tracking-[0.12em] text-muted-foreground", children: [
|
|
364
|
-
/* @__PURE__ */ jsx3("span", { children: language }),
|
|
365
|
-
/* @__PURE__ */ jsx3("span", { className: "h-1 w-1 rounded-full bg-[var(--border-hover)]" }),
|
|
366
|
-
/* @__PURE__ */ jsxs2("span", { children: [
|
|
367
|
-
lines.length,
|
|
368
|
-
" lines"
|
|
369
|
-
] })
|
|
370
|
-
] })
|
|
371
|
-
] }),
|
|
372
|
-
/* @__PURE__ */ jsx3("div", { className: "overflow-auto max-h-[70vh]", children: /* @__PURE__ */ jsx3("table", { className: "w-full", children: /* @__PURE__ */ jsx3("tbody", { children: lines.map((line, i) => /* @__PURE__ */ jsxs2("tr", { className: "hover:bg-accent", children: [
|
|
373
|
-
/* @__PURE__ */ jsx3("td", { className: "text-right pr-4 pl-4 py-0 select-none text-muted-foreground text-xs font-mono w-10 align-top leading-[1.55]", children: i + 1 }),
|
|
374
|
-
/* @__PURE__ */ jsx3("td", { className: "pr-4 py-0 font-mono text-[13px] text-foreground leading-[1.55] whitespace-pre", children: line || " " })
|
|
375
|
-
] }, i)) }) }) })
|
|
376
|
-
] });
|
|
324
|
+
function CodePreview({
|
|
325
|
+
content,
|
|
326
|
+
filename,
|
|
327
|
+
format
|
|
328
|
+
}) {
|
|
329
|
+
const lineCount = content.split("\n").length;
|
|
330
|
+
const language = getCodeLanguage(filename, format);
|
|
331
|
+
const labelToken = fileExtension(filename) || language || "txt";
|
|
332
|
+
return /* @__PURE__ */ jsx3(
|
|
333
|
+
CodeBlock,
|
|
334
|
+
{
|
|
335
|
+
code: content,
|
|
336
|
+
language,
|
|
337
|
+
label: `${labelToken} \xB7 ${lineCount} lines`,
|
|
338
|
+
showLineNumbers: true,
|
|
339
|
+
className: "max-h-[70vh] overflow-auto",
|
|
340
|
+
children: /* @__PURE__ */ jsx3(CopyButton, { text: content })
|
|
341
|
+
}
|
|
342
|
+
);
|
|
377
343
|
}
|
|
378
344
|
function parseCsvRow(line) {
|
|
379
345
|
const cells = [];
|
|
@@ -478,9 +444,9 @@ function FilePreview({
|
|
|
478
444
|
hideHeader = false,
|
|
479
445
|
className
|
|
480
446
|
}) {
|
|
481
|
-
const
|
|
482
|
-
const previewLabel =
|
|
483
|
-
const hasRenderableSource = Boolean(content) || Boolean(blobUrl) ||
|
|
447
|
+
const format = detectFileFormat(filename, mimeType);
|
|
448
|
+
const previewLabel = getFormatLabel(format);
|
|
449
|
+
const hasRenderableSource = Boolean(content) || Boolean(blobUrl) || format === "unknown" || format === "spreadsheet";
|
|
484
450
|
return /* @__PURE__ */ jsxs2("div", { className: cn("flex flex-col h-full", className), children: [
|
|
485
451
|
!hideHeader && /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-border shrink-0", children: [
|
|
486
452
|
/* @__PURE__ */ jsxs2("div", { className: "min-w-0 flex-1", children: [
|
|
@@ -509,13 +475,13 @@ function FilePreview({
|
|
|
509
475
|
)
|
|
510
476
|
] }),
|
|
511
477
|
/* @__PURE__ */ jsxs2("div", { className: "flex-1 overflow-auto p-3", children: [
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
(
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
478
|
+
format === "pdf" && blobUrl && /* @__PURE__ */ jsx3(PdfPreview, { blobUrl, filename }),
|
|
479
|
+
format === "image" && blobUrl && /* @__PURE__ */ jsx3(ImagePreview, { src: blobUrl, filename }),
|
|
480
|
+
format === "csv" && typeof content === "string" && /* @__PURE__ */ jsx3(CsvPreview, { content }),
|
|
481
|
+
(format === "code" || format === "json" || format === "yaml") && typeof content === "string" && /* @__PURE__ */ jsx3(CodePreview, { content, filename, format }),
|
|
482
|
+
format === "text" && typeof content === "string" && /* @__PURE__ */ jsx3(TextPreview, { content }),
|
|
483
|
+
format === "markdown" && typeof content === "string" && /* @__PURE__ */ jsx3(MarkdownPreview, { content }),
|
|
484
|
+
format === "spreadsheet" && /* @__PURE__ */ jsx3(
|
|
519
485
|
UnsupportedPreview,
|
|
520
486
|
{
|
|
521
487
|
filename,
|
|
@@ -523,8 +489,8 @@ function FilePreview({
|
|
|
523
489
|
description: "Download the workbook or convert it to CSV when you need an inline preview."
|
|
524
490
|
}
|
|
525
491
|
),
|
|
526
|
-
|
|
527
|
-
|
|
492
|
+
format === "unknown" && typeof content !== "string" && /* @__PURE__ */ jsx3(EmptyPreview, { filename }),
|
|
493
|
+
format === "unknown" && typeof content === "string" && /* @__PURE__ */ jsx3(TextPreview, { content }),
|
|
528
494
|
!hasRenderableSource && typeof content !== "string" && /* @__PURE__ */ jsx3(
|
|
529
495
|
UnsupportedPreview,
|
|
530
496
|
{
|
|
@@ -594,7 +560,7 @@ import { lazy, Suspense } from "react";
|
|
|
594
560
|
import { Download as Download2, X as X3 } from "lucide-react";
|
|
595
561
|
import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
596
562
|
var LazyDocumentEditorPane = lazy(async () => {
|
|
597
|
-
const module = await import("./document-editor-pane-
|
|
563
|
+
const module = await import("./document-editor-pane-WCTA3ZOE.js");
|
|
598
564
|
return { default: module.DocumentEditorPane };
|
|
599
565
|
});
|
|
600
566
|
function FileArtifactPane({
|
|
@@ -626,7 +592,7 @@ function FileArtifactPane({
|
|
|
626
592
|
onClose: onTabClose
|
|
627
593
|
}
|
|
628
594
|
) : void 0;
|
|
629
|
-
const isMarkdown = mimeType === "
|
|
595
|
+
const isMarkdown = detectFileFormat(filename, mimeType) === "markdown" || (path ? detectFileFormat(path, mimeType) === "markdown" : false);
|
|
630
596
|
const isEditableMarkdown = isMarkdown && editor?.enabled;
|
|
631
597
|
const headerActions = /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
632
598
|
onDownload && /* @__PURE__ */ jsx5(
|
|
@@ -83,24 +83,25 @@ function useIsLightTheme() {
|
|
|
83
83
|
return isLight;
|
|
84
84
|
}
|
|
85
85
|
var CodeBlock = memo(
|
|
86
|
-
({ code, language, showLineNumbers = false, light: lightProp, className, children, ...props }) => {
|
|
86
|
+
({ code, language, label, showLineNumbers = false, light: lightProp, className, children, ...props }) => {
|
|
87
87
|
const isLight = useIsLightTheme();
|
|
88
88
|
const light = lightProp ?? isLight;
|
|
89
89
|
const theme = getSyntaxTheme();
|
|
90
90
|
const bg = "bg-card border-border";
|
|
91
91
|
const headerBg = light ? "bg-muted/50 border-border" : "bg-background border-border";
|
|
92
92
|
const langColor = "text-muted-foreground";
|
|
93
|
+
const headerLabel = label ?? language;
|
|
93
94
|
return /* @__PURE__ */ jsxs(
|
|
94
95
|
"div",
|
|
95
96
|
{
|
|
96
97
|
className: cn("group relative overflow-hidden rounded-lg border font-mono", bg, className),
|
|
97
98
|
...props,
|
|
98
99
|
children: [
|
|
99
|
-
|
|
100
|
-
/* @__PURE__ */ jsx("span", { className: cn("text-[calc(var(--font-size-xs)-1px)] font-mono font-medium uppercase tracking-widest", langColor), children:
|
|
100
|
+
headerLabel && /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between border-b px-3 py-1", headerBg), children: [
|
|
101
|
+
/* @__PURE__ */ jsx("span", { className: cn("text-[calc(var(--font-size-xs)-1px)] font-mono font-medium uppercase tracking-widest", langColor), children: headerLabel }),
|
|
101
102
|
children
|
|
102
103
|
] }),
|
|
103
|
-
!
|
|
104
|
+
!headerLabel && children && /* @__PURE__ */ jsx("div", { className: "absolute right-2 top-2 z-10 flex items-center gap-2 opacity-0 transition-opacity group-hover:opacity-100", children }),
|
|
104
105
|
/* @__PURE__ */ jsx(
|
|
105
106
|
SyntaxHighlighter,
|
|
106
107
|
{
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// src/files/file-format.ts
|
|
2
|
+
var IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "gif", "svg", "webp"];
|
|
3
|
+
var EXTENSION_TO_SYNTAX_LANGUAGE = {
|
|
4
|
+
ts: "typescript",
|
|
5
|
+
tsx: "tsx",
|
|
6
|
+
js: "javascript",
|
|
7
|
+
jsx: "jsx",
|
|
8
|
+
mjs: "javascript",
|
|
9
|
+
cjs: "javascript",
|
|
10
|
+
rs: "rust",
|
|
11
|
+
py: "python",
|
|
12
|
+
go: "go",
|
|
13
|
+
rb: "ruby",
|
|
14
|
+
json: "json",
|
|
15
|
+
yaml: "yaml",
|
|
16
|
+
yml: "yaml",
|
|
17
|
+
toml: "toml",
|
|
18
|
+
md: "markdown",
|
|
19
|
+
markdown: "markdown",
|
|
20
|
+
css: "css",
|
|
21
|
+
scss: "scss",
|
|
22
|
+
html: "html",
|
|
23
|
+
sh: "bash",
|
|
24
|
+
bash: "bash",
|
|
25
|
+
zsh: "bash",
|
|
26
|
+
bashrc: "bash",
|
|
27
|
+
bash_logout: "bash",
|
|
28
|
+
profile: "bash",
|
|
29
|
+
sql: "sql",
|
|
30
|
+
sol: "solidity",
|
|
31
|
+
proto: "protobuf"
|
|
32
|
+
};
|
|
33
|
+
var NON_CODE_SYNTAX_EXTENSIONS = /* @__PURE__ */ new Set(["json", "yaml", "yml", "md", "markdown"]);
|
|
34
|
+
var PLAIN_CODE_EXTENSIONS = ["env", "gitignore"];
|
|
35
|
+
var CODE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
36
|
+
...Object.keys(EXTENSION_TO_SYNTAX_LANGUAGE).filter((ext) => !NON_CODE_SYNTAX_EXTENSIONS.has(ext)),
|
|
37
|
+
...PLAIN_CODE_EXTENSIONS
|
|
38
|
+
]);
|
|
39
|
+
function fileExtension(filename) {
|
|
40
|
+
const base = filename.slice(filename.lastIndexOf("/") + 1);
|
|
41
|
+
const dot = base.lastIndexOf(".");
|
|
42
|
+
if (dot < 0) return "";
|
|
43
|
+
return base.slice(dot + 1).toLowerCase();
|
|
44
|
+
}
|
|
45
|
+
function mimeEssence(mimeType) {
|
|
46
|
+
return mimeType?.split(";")[0]?.trim().toLowerCase() ?? "";
|
|
47
|
+
}
|
|
48
|
+
function detectFileFormat(filename, mimeType) {
|
|
49
|
+
const ext = fileExtension(filename);
|
|
50
|
+
const mime = mimeEssence(mimeType);
|
|
51
|
+
if (mime === "application/pdf") return "pdf";
|
|
52
|
+
if (mime.startsWith("image/")) return "image";
|
|
53
|
+
if (mime === "text/markdown") return "markdown";
|
|
54
|
+
if (mime === "application/json") return "json";
|
|
55
|
+
if (mime === "text/csv" || mime === "application/csv") return "csv";
|
|
56
|
+
if (mime === "application/yaml" || mime === "application/x-yaml" || mime === "text/yaml") return "yaml";
|
|
57
|
+
if (ext === "pdf") return "pdf";
|
|
58
|
+
if (IMAGE_EXTENSIONS.includes(ext)) return "image";
|
|
59
|
+
if (ext === "csv") return "csv";
|
|
60
|
+
if (ext === "xlsx" || ext === "xls") return "spreadsheet";
|
|
61
|
+
if (CODE_EXTENSIONS.has(ext)) return "code";
|
|
62
|
+
if (ext === "json") return "json";
|
|
63
|
+
if (ext === "yaml" || ext === "yml") return "yaml";
|
|
64
|
+
if (ext === "md" || ext === "markdown") return "markdown";
|
|
65
|
+
if (["txt", "log", "text"].includes(ext)) return "text";
|
|
66
|
+
if (mime === "text/plain") return "text";
|
|
67
|
+
return "unknown";
|
|
68
|
+
}
|
|
69
|
+
function getFormatLabel(format) {
|
|
70
|
+
switch (format) {
|
|
71
|
+
case "pdf":
|
|
72
|
+
return "PDF";
|
|
73
|
+
case "image":
|
|
74
|
+
return "Image";
|
|
75
|
+
case "csv":
|
|
76
|
+
return "CSV";
|
|
77
|
+
case "spreadsheet":
|
|
78
|
+
return "Spreadsheet";
|
|
79
|
+
case "code":
|
|
80
|
+
return "Code";
|
|
81
|
+
case "json":
|
|
82
|
+
return "JSON";
|
|
83
|
+
case "yaml":
|
|
84
|
+
return "YAML";
|
|
85
|
+
case "markdown":
|
|
86
|
+
return "Markdown";
|
|
87
|
+
case "text":
|
|
88
|
+
return "Text";
|
|
89
|
+
default:
|
|
90
|
+
return "File";
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function getSyntaxLanguage(filename) {
|
|
94
|
+
return EXTENSION_TO_SYNTAX_LANGUAGE[fileExtension(filename)];
|
|
95
|
+
}
|
|
96
|
+
function getCodeLanguage(filename, format) {
|
|
97
|
+
if (format === "json" || format === "yaml") return format;
|
|
98
|
+
return getSyntaxLanguage(filename);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export {
|
|
102
|
+
fileExtension,
|
|
103
|
+
detectFileFormat,
|
|
104
|
+
getFormatLabel,
|
|
105
|
+
getSyntaxLanguage,
|
|
106
|
+
getCodeLanguage
|
|
107
|
+
};
|
|
@@ -5,12 +5,18 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
5
5
|
interface CodeBlockProps extends HTMLAttributes<HTMLDivElement> {
|
|
6
6
|
code: string;
|
|
7
7
|
language?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Header text. Defaults to `language`. Set this when the display name differs
|
|
10
|
+
* from the highlight.js language id — e.g. a file extension ("BASHRC") whose
|
|
11
|
+
* content highlights as a known language, or none.
|
|
12
|
+
*/
|
|
13
|
+
label?: string;
|
|
8
14
|
showLineNumbers?: boolean;
|
|
9
15
|
/** Force light theme; defaults to dark */
|
|
10
16
|
light?: boolean;
|
|
11
17
|
children?: ReactNode;
|
|
12
18
|
}
|
|
13
|
-
declare const CodeBlock: React.MemoExoticComponent<({ code, language, showLineNumbers, light: lightProp, className, children, ...props }: CodeBlockProps) => react_jsx_runtime.JSX.Element>;
|
|
19
|
+
declare const CodeBlock: React.MemoExoticComponent<({ code, language, label, showLineNumbers, light: lightProp, className, children, ...props }: CodeBlockProps) => react_jsx_runtime.JSX.Element>;
|
|
14
20
|
/** Copy-to-clipboard button for use inside CodeBlock. */
|
|
15
21
|
declare const CopyButton: React.MemoExoticComponent<({ text }: {
|
|
16
22
|
text: string;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
DocumentEditorPane
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-SZ44QDA6.js";
|
|
5
5
|
import "./chunk-Q56BYXQF.js";
|
|
6
6
|
import "./chunk-CSAIKY36.js";
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-FJBTCTZM.js";
|
|
8
|
+
import "./chunk-WUQDUBJG.js";
|
|
9
9
|
import "./chunk-RQHJBTEU.js";
|
|
10
10
|
export {
|
|
11
11
|
DocumentEditorPane
|
package/dist/editor.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import "./chunk-Q7EIIWTC.js";
|
|
2
1
|
import {
|
|
3
2
|
CollaboratorsList,
|
|
4
3
|
DocumentEditorPane,
|
|
@@ -12,11 +11,11 @@ import {
|
|
|
12
11
|
useEditorConnection,
|
|
13
12
|
useEditorContext,
|
|
14
13
|
useYjsState
|
|
15
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-SZ44QDA6.js";
|
|
16
15
|
import "./chunk-Q56BYXQF.js";
|
|
17
16
|
import "./chunk-CSAIKY36.js";
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-FJBTCTZM.js";
|
|
18
|
+
import "./chunk-WUQDUBJG.js";
|
|
20
19
|
import "./chunk-RQHJBTEU.js";
|
|
21
20
|
export {
|
|
22
21
|
CollaboratorsList,
|