@hachej/boring-workspace 0.1.16 → 0.1.17

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.
@@ -1,533 +0,0 @@
1
- import { jsxs as R, jsx as e } from "react/jsx-runtime";
2
- import { useState as D, useCallback as V, useRef as L, useEffect as B, useMemo as X } from "react";
3
- import { ReactNodeViewRenderer as K, NodeViewWrapper as Q, useEditor as Z, EditorContent as G, useEditorState as J } from "@tiptap/react";
4
- import Y from "@tiptap/starter-kit";
5
- import tt from "@tiptap/extension-underline";
6
- import et from "@tiptap/extension-link";
7
- import P from "@tiptap/extension-placeholder";
8
- import rt from "@tiptap/extension-task-list";
9
- import it from "@tiptap/extension-task-item";
10
- import nt from "@tiptap/extension-text-align";
11
- import at from "@tiptap/extension-highlight";
12
- import { Table as ot } from "@tiptap/extension-table";
13
- import { TableRow as lt } from "@tiptap/extension-table-row";
14
- import { TableHeader as st } from "@tiptap/extension-table-header";
15
- import { TableCell as ct } from "@tiptap/extension-table-cell";
16
- import ut from "@tiptap/extension-image";
17
- import { c as H } from "./utils-B6yFEsav.js";
18
- import { ao as j, ap as gt } from "./CommandPalette-NOEOVkN2.js";
19
- import { uploadFile as dt } from "@hachej/boring-agent/front";
20
- import ft from "@tiptap/extension-code-block-lowlight";
21
- import { createLowlight as mt, common as pt } from "lowlight";
22
- import { Markdown as ht } from "@tiptap/markdown";
23
- import { BoldIcon as wt, ItalicIcon as kt, UnderlineIcon as vt, StrikethroughIcon as bt, Heading1Icon as It, Heading2Icon as At, Heading3Icon as yt, ListIcon as Lt, ListOrderedIcon as xt, ListChecksIcon as Nt, QuoteIcon as Ct, CodeIcon as Tt, LinkIcon as Mt, ImageIcon as Rt, HighlighterIcon as Ht, AlignLeftIcon as Ut, AlignCenterIcon as $t, AlignRightIcon as St, MinusIcon as Bt, Loader2Icon as Dt } from "lucide-react";
24
- import { Toolbar as Et, Input as Ft, ToolbarButton as zt, ToolbarSeparator as Wt } from "@hachej/boring-ui-kit";
25
- function Pt(t) {
26
- const i = j(), n = gt(), [a, c] = D(0);
27
- return { upload: V(
28
- async (f, o) => {
29
- c((p) => p + 1);
30
- try {
31
- return await dt(f, {
32
- apiBaseUrl: i,
33
- workspaceRequestId: n,
34
- directory: (o == null ? void 0 : o.directory) ?? (t == null ? void 0 : t.directory),
35
- sourcePath: o == null ? void 0 : o.sourcePath
36
- });
37
- } finally {
38
- c((p) => p - 1);
39
- }
40
- },
41
- [i, n, t == null ? void 0 : t.directory]
42
- ), uploading: a > 0 };
43
- }
44
- const E = 64, F = 2e3;
45
- function jt(t) {
46
- return t.replace(/\\/g, "\\\\").replace(/]/g, "\\]");
47
- }
48
- function S(t) {
49
- return t.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
50
- }
51
- function z(t) {
52
- if (typeof t == "number" && Number.isFinite(t) && t > 0) return t;
53
- if (typeof t == "string" && t.trim()) {
54
- const i = Number(t);
55
- if (Number.isFinite(i) && i > 0) return i;
56
- }
57
- return null;
58
- }
59
- const q = ut.extend({
60
- name: "image",
61
- draggable: !0,
62
- addOptions() {
63
- var t;
64
- return {
65
- ...(t = this.parent) == null ? void 0 : t.call(this),
66
- resolveSrc: (i) => i
67
- };
68
- },
69
- parseMarkdown: (t, i) => i.createNode("image", {
70
- src: t.href,
71
- title: t.title,
72
- alt: t.text
73
- }),
74
- renderMarkdown: (t) => {
75
- var b, I, A, r, m, w, y;
76
- const i = typeof ((b = t.attrs) == null ? void 0 : b.src) == "string" ? t.attrs.src : "", n = typeof ((I = t.attrs) == null ? void 0 : I.alt) == "string" ? t.attrs.alt : "", a = typeof ((A = t.attrs) == null ? void 0 : A.title) == "string" ? t.attrs.title : "", c = z((r = t.attrs) == null ? void 0 : r.width), l = z((m = t.attrs) == null ? void 0 : m.height), f = ((w = t.attrs) == null ? void 0 : w.align) === "center" || ((y = t.attrs) == null ? void 0 : y.align) === "right" ? t.attrs.align : "left";
77
- if (!c && !l && f === "left") {
78
- const k = jt(n);
79
- return a ? `![${k}](${i} "${a.replace(/"/g, '\\"')}")` : `![${k}](${i})`;
80
- }
81
- const p = `<img ${[
82
- `src="${S(i)}"`,
83
- n ? `alt="${S(n)}"` : null,
84
- a ? `title="${S(a)}"` : null,
85
- c ? `width="${c}"` : null,
86
- l ? `height="${l}"` : null
87
- ].filter(Boolean).join(" ")} />`;
88
- return f === "center" || f === "right" ? `<p align="${f}">${p}</p>` : p;
89
- },
90
- addAttributes() {
91
- var i;
92
- return {
93
- ...((i = this.parent) == null ? void 0 : i.call(this)) ?? {},
94
- width: {
95
- default: null,
96
- parseHTML: (n) => {
97
- const a = n.getAttribute("width");
98
- if (a) {
99
- const l = parseInt(a, 10);
100
- return Number.isFinite(l) ? l : null;
101
- }
102
- const c = n.style.width;
103
- if (c && c.endsWith("px")) {
104
- const l = parseInt(c, 10);
105
- return Number.isFinite(l) ? l : null;
106
- }
107
- return null;
108
- },
109
- renderHTML: (n) => n.width ? { width: String(n.width) } : {}
110
- },
111
- align: {
112
- default: "left",
113
- parseHTML: (n) => {
114
- const a = n.getAttribute("data-align");
115
- return a === "left" || a === "center" || a === "right" ? a : n.style.marginLeft === "auto" && n.style.marginRight === "auto" ? "center" : n.style.marginLeft === "auto" ? "right" : "left";
116
- },
117
- renderHTML: (n) => ({ "data-align": n.align ?? "left" })
118
- },
119
- // Transient marker used by MarkdownEditor.insertImageRef to find THIS
120
- // specific inserted image when its background upload completes, even
121
- // if the user pasted the same file twice (which produces two image
122
- // nodes with identical `src` data URLs). Never serialized to HTML or
123
- // markdown — purely in-memory state for the swap.
124
- pendingUploadId: {
125
- default: null,
126
- parseHTML: () => null,
127
- renderHTML: () => ({})
128
- }
129
- };
130
- },
131
- addNodeView() {
132
- return K(qt);
133
- }
134
- });
135
- function qt({ node: t, updateAttributes: i, selected: n, extension: a }) {
136
- const c = L(null), l = L(null), [f, o] = D(!1), p = t.attrs.src ?? "", I = (a.options.resolveSrc ?? ((k) => k))(p), A = t.attrs.alt ?? "", r = t.attrs.title ?? void 0, m = t.attrs.width, w = t.attrs.align ?? "left";
137
- B(() => {
138
- if (!f) return;
139
- const k = (g) => {
140
- const s = l.current;
141
- if (!s) return;
142
- const d = g.clientX - s.x, h = Math.max(E, Math.min(F, s.width + d));
143
- i({ width: Math.round(h) });
144
- }, v = () => {
145
- l.current = null, o(!1);
146
- };
147
- return window.addEventListener("pointermove", k), window.addEventListener("pointerup", v), window.addEventListener("pointercancel", v), () => {
148
- window.removeEventListener("pointermove", k), window.removeEventListener("pointerup", v), window.removeEventListener("pointercancel", v);
149
- };
150
- }, [f, i]);
151
- const y = (k) => {
152
- var s;
153
- k.preventDefault(), k.stopPropagation();
154
- const v = (s = c.current) == null ? void 0 : s.querySelector("img"), g = m ?? (v == null ? void 0 : v.getBoundingClientRect().width) ?? 320;
155
- l.current = { x: k.clientX, width: g }, o(!0);
156
- };
157
- return /* @__PURE__ */ R(
158
- Q,
159
- {
160
- ref: c,
161
- "data-resizable-image": "",
162
- "data-selected": n ? "true" : void 0,
163
- className: H(
164
- "relative block max-w-full align-baseline",
165
- "[&>img]:block [&>img]:max-w-full [&>img]:h-auto [&>img]:rounded-md",
166
- w === "left" && "mr-auto",
167
- w === "center" && "mx-auto",
168
- w === "right" && "ml-auto",
169
- n && "ring-2 ring-[color:var(--accent)] ring-offset-1 ring-offset-background"
170
- ),
171
- style: { width: m ? `${m}px` : void 0 },
172
- children: [
173
- /* @__PURE__ */ e("img", { src: I, alt: A, title: r, draggable: !1 }),
174
- /* @__PURE__ */ e(
175
- "span",
176
- {
177
- role: "slider",
178
- "aria-label": "Resize image",
179
- "aria-valuenow": m ?? 0,
180
- "aria-valuemin": E,
181
- "aria-valuemax": F,
182
- "data-testid": "resize-handle",
183
- onPointerDown: y,
184
- className: H(
185
- "absolute right-0 bottom-0 h-3 w-3 translate-x-1/2 translate-y-1/2 cursor-nwse-resize",
186
- "rounded-full border border-background bg-[color:var(--accent)] shadow",
187
- "opacity-0 transition-opacity duration-150 ease-out",
188
- (n || f) && "opacity-100"
189
- )
190
- }
191
- )
192
- ]
193
- }
194
- );
195
- }
196
- const _t = mt(pt), Ot = [
197
- /<script[\s>][\s\S]*?<\/script>/gi,
198
- /<iframe[\s>][\s\S]*?<\/iframe>/gi,
199
- /\s+on\w+\s*=\s*["'][^"']*["']/gi,
200
- /\s+on\w+\s*=\s*\S+/gi,
201
- /href\s*=\s*["']?\s*javascript:[^"'\s>]*/gi,
202
- /src\s*=\s*["']?\s*javascript:[^"'\s>]*/gi
203
- ];
204
- function Vt(t) {
205
- let i = t;
206
- for (const n of Ot)
207
- i = i.replace(n, "");
208
- return i;
209
- }
210
- function Xt(t) {
211
- return /^(?:[a-z][a-z0-9+.-]*:|\/|#)/i.test(t);
212
- }
213
- function Kt(t, i) {
214
- const n = t.match(/^([^?#]*)([?#].*)?$/), a = (n == null ? void 0 : n[1]) ?? t, c = (n == null ? void 0 : n[2]) ?? "", l = i != null && i.includes("/") ? i.slice(0, i.lastIndexOf("/")) : "", f = `${l ? `${l}/` : ""}${a}`.split("/"), o = [];
215
- for (const p of f)
216
- !p || p === "." || (p === ".." ? o.pop() : o.push(p));
217
- return `${o.join("/")}${c}`;
218
- }
219
- function Qt(t, i, n) {
220
- if (!t || Xt(t)) return t;
221
- const a = Kt(t, i);
222
- return `${n.replace(/\/$/, "")}/api/v1/files/raw?path=${encodeURIComponent(a)}`;
223
- }
224
- const Zt = [
225
- Y.configure({
226
- codeBlock: !1,
227
- link: !1,
228
- underline: !1
229
- }),
230
- tt,
231
- et.configure({
232
- openOnClick: !0,
233
- autolink: !0,
234
- linkOnPaste: !0,
235
- defaultProtocol: "https",
236
- HTMLAttributes: { rel: "noopener noreferrer nofollow", target: "_blank" }
237
- }),
238
- P.configure({
239
- placeholder: "Start writing..."
240
- }),
241
- rt,
242
- it.configure({ nested: !0 }),
243
- nt.configure({
244
- types: ["heading", "paragraph"]
245
- }),
246
- at,
247
- ot.configure({
248
- resizable: !0
249
- }),
250
- lt,
251
- st,
252
- ct,
253
- q.configure({
254
- inline: !1,
255
- allowBase64: !0
256
- }),
257
- ft.configure({ lowlight: _t }),
258
- ht.configure({
259
- markedOptions: {
260
- gfm: !0,
261
- breaks: !1,
262
- pedantic: !1
263
- }
264
- })
265
- ];
266
- function u({ onClick: t, active: i, disabled: n, title: a, children: c }) {
267
- return /* @__PURE__ */ e(
268
- zt,
269
- {
270
- type: "button",
271
- size: "icon-xs",
272
- onClick: t,
273
- disabled: n,
274
- title: a,
275
- "aria-pressed": i,
276
- className: H(
277
- "text-muted-foreground/70",
278
- i && "bg-[color:var(--accent-soft)] text-[color:var(--accent)]"
279
- ),
280
- children: c
281
- }
282
- );
283
- }
284
- function x() {
285
- return /* @__PURE__ */ e(Wt, { className: "mx-2 h-3.5" });
286
- }
287
- function W(t) {
288
- const i = t.trim().toLowerCase();
289
- return !i.startsWith("javascript:") && !i.startsWith("data:text/html");
290
- }
291
- function Gt(t) {
292
- return new Promise((i, n) => {
293
- const a = new FileReader();
294
- a.onload = () => i(a.result), a.onerror = () => n(a.error ?? new Error("Read failed")), a.readAsDataURL(t);
295
- });
296
- }
297
- function Jt(t) {
298
- if (!t) return null;
299
- for (const i of Array.from(t.files ?? []))
300
- if (i.type.startsWith("image/")) return i;
301
- for (const i of Array.from(t.items ?? [])) {
302
- if (i.kind !== "file" || !i.type.startsWith("image/")) continue;
303
- const n = i.getAsFile();
304
- if (n) return n;
305
- }
306
- return null;
307
- }
308
- function Yt({
309
- editor: t,
310
- onInsertImage: i,
311
- rawMode: n,
312
- onToggleRawMode: a,
313
- uploading: c
314
- }) {
315
- const l = (r) => {
316
- if (t) {
317
- if (t.isActive("image")) {
318
- t.chain().focus().updateAttributes("image", { align: r }).run();
319
- return;
320
- }
321
- t.chain().focus().setTextAlign(r).run();
322
- }
323
- }, f = L(null), o = J({
324
- editor: t,
325
- selector: ({ editor: r }) => r ? {
326
- bold: r.isActive("bold"),
327
- italic: r.isActive("italic"),
328
- underline: r.isActive("underline"),
329
- strike: r.isActive("strike"),
330
- h1: r.isActive("heading", { level: 1 }),
331
- h2: r.isActive("heading", { level: 2 }),
332
- h3: r.isActive("heading", { level: 3 }),
333
- bulletList: r.isActive("bulletList"),
334
- orderedList: r.isActive("orderedList"),
335
- taskList: r.isActive("taskList"),
336
- blockquote: r.isActive("blockquote"),
337
- codeBlock: r.isActive("codeBlock"),
338
- link: r.isActive("link"),
339
- highlight: r.isActive("highlight"),
340
- alignLeft: r.isActive("image") ? (r.getAttributes("image").align ?? "left") === "left" : r.isActive({ textAlign: "left" }),
341
- alignCenter: r.isActive("image") ? r.getAttributes("image").align === "center" : r.isActive({ textAlign: "center" }),
342
- alignRight: r.isActive("image") ? r.getAttributes("image").align === "right" : r.isActive({ textAlign: "right" })
343
- } : null
344
- });
345
- if (!t || !o) return null;
346
- const p = () => {
347
- const r = window.prompt("URL:");
348
- r && W(r) && t.chain().focus().extendMarkRange("link").setLink({ href: r }).run();
349
- }, b = () => {
350
- const r = window.prompt("Image URL:");
351
- r && W(r) && t.chain().focus().setImage({ src: r }).run();
352
- }, I = (r) => {
353
- var m;
354
- if (r != null && r.shiftKey) {
355
- b();
356
- return;
357
- }
358
- (m = f.current) == null || m.click();
359
- }, A = async (r) => {
360
- var w;
361
- const m = (w = r.target.files) == null ? void 0 : w[0];
362
- r.target.value = "", !(!m || !m.type.startsWith("image/")) && await i(m);
363
- };
364
- return /* @__PURE__ */ R(Et, { className: "border-b border-border/60 bg-background px-3 py-1.5", "aria-label": "Formatting toolbar", children: [
365
- /* @__PURE__ */ e(u, { onClick: () => t.chain().focus().toggleBold().run(), active: o.bold, title: "Bold", children: /* @__PURE__ */ e(wt, { className: "h-4 w-4" }) }),
366
- /* @__PURE__ */ e(u, { onClick: () => t.chain().focus().toggleItalic().run(), active: o.italic, title: "Italic", children: /* @__PURE__ */ e(kt, { className: "h-4 w-4" }) }),
367
- /* @__PURE__ */ e(u, { onClick: () => t.chain().focus().toggleUnderline().run(), active: o.underline, title: "Underline", children: /* @__PURE__ */ e(vt, { className: "h-4 w-4" }) }),
368
- /* @__PURE__ */ e(u, { onClick: () => t.chain().focus().toggleStrike().run(), active: o.strike, title: "Strikethrough", children: /* @__PURE__ */ e(bt, { className: "h-4 w-4" }) }),
369
- /* @__PURE__ */ e(x, {}),
370
- /* @__PURE__ */ e(u, { onClick: () => t.chain().focus().toggleHeading({ level: 1 }).run(), active: o.h1, title: "Heading 1", children: /* @__PURE__ */ e(It, { className: "h-4 w-4" }) }),
371
- /* @__PURE__ */ e(u, { onClick: () => t.chain().focus().toggleHeading({ level: 2 }).run(), active: o.h2, title: "Heading 2", children: /* @__PURE__ */ e(At, { className: "h-4 w-4" }) }),
372
- /* @__PURE__ */ e(u, { onClick: () => t.chain().focus().toggleHeading({ level: 3 }).run(), active: o.h3, title: "Heading 3", children: /* @__PURE__ */ e(yt, { className: "h-4 w-4" }) }),
373
- /* @__PURE__ */ e(x, {}),
374
- /* @__PURE__ */ e(u, { onClick: () => t.chain().focus().toggleBulletList().run(), active: o.bulletList, title: "Bullet list", children: /* @__PURE__ */ e(Lt, { className: "h-4 w-4" }) }),
375
- /* @__PURE__ */ e(u, { onClick: () => t.chain().focus().toggleOrderedList().run(), active: o.orderedList, title: "Ordered list", children: /* @__PURE__ */ e(xt, { className: "h-4 w-4" }) }),
376
- /* @__PURE__ */ e(u, { onClick: () => t.chain().focus().toggleTaskList().run(), active: o.taskList, title: "Task list", children: /* @__PURE__ */ e(Nt, { className: "h-4 w-4" }) }),
377
- /* @__PURE__ */ e(x, {}),
378
- /* @__PURE__ */ e(u, { onClick: () => t.chain().focus().toggleBlockquote().run(), active: o.blockquote, title: "Quote", children: /* @__PURE__ */ e(Ct, { className: "h-4 w-4" }) }),
379
- /* @__PURE__ */ e(u, { onClick: () => t.chain().focus().toggleCodeBlock().run(), active: o.codeBlock, title: "Code block", children: /* @__PURE__ */ e(Tt, { className: "h-4 w-4" }) }),
380
- /* @__PURE__ */ e(u, { onClick: p, active: o.link, title: "Link", children: /* @__PURE__ */ e(Mt, { className: "h-4 w-4" }) }),
381
- /* @__PURE__ */ e(
382
- u,
383
- {
384
- onClick: I,
385
- title: "Image (click to upload, Shift+click for URL)",
386
- children: /* @__PURE__ */ e(Rt, { className: "h-4 w-4" })
387
- }
388
- ),
389
- /* @__PURE__ */ e(
390
- Ft,
391
- {
392
- ref: f,
393
- "data-testid": "image-file-input",
394
- type: "file",
395
- accept: "image/*",
396
- className: "hidden",
397
- onChange: A
398
- }
399
- ),
400
- /* @__PURE__ */ e(u, { onClick: () => t.chain().focus().toggleHighlight().run(), active: o.highlight, title: "Highlight", children: /* @__PURE__ */ e(Ht, { className: "h-4 w-4" }) }),
401
- /* @__PURE__ */ e(x, {}),
402
- /* @__PURE__ */ e(u, { onClick: () => l("left"), active: o.alignLeft, title: "Align left", children: /* @__PURE__ */ e(Ut, { className: "h-4 w-4" }) }),
403
- /* @__PURE__ */ e(u, { onClick: () => l("center"), active: o.alignCenter, title: "Center align", children: /* @__PURE__ */ e($t, { className: "h-4 w-4" }) }),
404
- /* @__PURE__ */ e(u, { onClick: () => l("right"), active: o.alignRight, title: "Align right", children: /* @__PURE__ */ e(St, { className: "h-4 w-4" }) }),
405
- /* @__PURE__ */ e(x, {}),
406
- /* @__PURE__ */ e(u, { onClick: () => t.chain().focus().setHorizontalRule().run(), title: "Horizontal rule", children: /* @__PURE__ */ e(Bt, { className: "h-4 w-4" }) }),
407
- /* @__PURE__ */ e(x, {}),
408
- c && /* @__PURE__ */ R(
409
- "span",
410
- {
411
- role: "status",
412
- "aria-live": "polite",
413
- className: "ml-auto flex items-center gap-1.5 text-[11px] text-muted-foreground/80",
414
- children: [
415
- /* @__PURE__ */ e(Dt, { className: "h-3 w-3 animate-spin", "aria-hidden": !0 }),
416
- "Uploading…"
417
- ]
418
- }
419
- ),
420
- /* @__PURE__ */ e(
421
- u,
422
- {
423
- onClick: a,
424
- active: n,
425
- title: n ? "Rich text" : "Raw markdown",
426
- children: /* @__PURE__ */ e("span", { className: "font-mono text-[10px] font-semibold leading-none tracking-[-0.02em]", children: "MD" })
427
- }
428
- )
429
- ] });
430
- }
431
- function Le({
432
- content: t,
433
- onChange: i,
434
- readOnly: n = !1,
435
- placeholder: a,
436
- className: c,
437
- documentPath: l
438
- }) {
439
- const f = j(), { upload: o, uploading: p } = Pt(), [b, I] = D(!1), A = X(() => {
440
- const s = q.configure({
441
- inline: !1,
442
- allowBase64: !0,
443
- resolveSrc: (h) => Qt(h, l, f)
444
- }), d = Zt.map((h) => h.name === "image" ? s : h);
445
- return a ? [
446
- ...d.filter((h) => h.name !== "placeholder"),
447
- P.configure({ placeholder: a })
448
- ] : d;
449
- }, [f, l, a]), r = L(i);
450
- r.current = i;
451
- const m = L(!1), w = L(null), y = L(async () => {
452
- });
453
- y.current = async (s) => {
454
- const d = w.current;
455
- if (!d) return;
456
- let h;
457
- try {
458
- h = await Gt(s);
459
- } catch {
460
- return;
461
- }
462
- const U = typeof crypto < "u" && typeof crypto.randomUUID == "function" ? crypto.randomUUID() : `pending-${Date.now()}-${Math.random().toString(36).slice(2)}`, _ = { src: h, alt: s.name, pendingUploadId: U };
463
- d.chain().focus().setImage(_).run();
464
- try {
465
- const { url: N } = await o(s, { sourcePath: l }), C = w.current;
466
- if (!C || C.isDestroyed) return;
467
- C.commands.command(({ tr: $, state: T }) => (T.doc.descendants((M, O) => (M.type.name === "image" && M.attrs.pendingUploadId === U && $.setNodeMarkup(O, void 0, { ...M.attrs, src: N, pendingUploadId: null }), !0)), !0));
468
- } catch {
469
- const N = w.current;
470
- if (!N || N.isDestroyed) return;
471
- N.commands.command(({ tr: C, state: $ }) => ($.doc.descendants((T, M) => (T.type.name === "image" && T.attrs.pendingUploadId === U && C.setNodeMarkup(M, void 0, { ...T.attrs, pendingUploadId: null }), !0)), !0));
472
- }
473
- };
474
- const k = t || { type: "doc", content: [{ type: "paragraph" }] }, v = t ? "markdown" : "json", g = Z({
475
- extensions: A,
476
- content: k,
477
- contentType: v,
478
- editable: !n,
479
- editorProps: {
480
- attributes: {
481
- class: "tiptap-prose max-w-[68ch] px-8 py-6 focus:outline-none min-h-[200px]"
482
- },
483
- transformPastedHTML: Vt,
484
- handlePaste: (s, d) => {
485
- if (n) return !1;
486
- const h = Jt(d.clipboardData);
487
- return h ? (d.preventDefault(), y.current(h), !0) : !1;
488
- }
489
- },
490
- onUpdate: ({ editor: s }) => {
491
- var d, h;
492
- m.current || (h = r.current) == null || h.call(r, ((d = s.getMarkdown) == null ? void 0 : d.call(s)) ?? s.getHTML());
493
- }
494
- });
495
- return w.current = g, B(() => {
496
- !g || g.isDestroyed || g.setEditable(!n);
497
- }, [g, n]), B(() => {
498
- var d;
499
- !g || g.isDestroyed || (((d = g.getMarkdown) == null ? void 0 : d.call(g)) ?? g.getHTML()) === t || (m.current = !0, g.commands.setContent(k, { contentType: v }), m.current = !1);
500
- }, [g, t]), /* @__PURE__ */ R("div", { className: H("flex h-full flex-col overflow-hidden", c), children: [
501
- !n && /* @__PURE__ */ e(
502
- Yt,
503
- {
504
- editor: g,
505
- onInsertImage: (s) => y.current(s),
506
- rawMode: b,
507
- onToggleRawMode: () => I((s) => !s),
508
- uploading: p
509
- }
510
- ),
511
- /* @__PURE__ */ e("div", { className: "flex-1 overflow-auto", children: b && !n ? /* @__PURE__ */ e(
512
- "textarea",
513
- {
514
- "aria-label": "Raw markdown",
515
- "data-testid": "markdown-raw-editor",
516
- className: "h-full min-h-[200px] w-full resize-none bg-background px-8 py-6 font-mono text-[13px] leading-6 text-foreground outline-none placeholder:text-muted-foreground/70",
517
- value: t,
518
- placeholder: a,
519
- spellCheck: !1,
520
- onChange: (s) => {
521
- var d;
522
- return (d = r.current) == null ? void 0 : d.call(r, s.target.value);
523
- }
524
- }
525
- ) : /* @__PURE__ */ e(G, { editor: g }) })
526
- ] });
527
- }
528
- export {
529
- Le as MarkdownEditor,
530
- W as isSafeUrl,
531
- Gt as readFileAsDataUrl,
532
- Vt as sanitizeHtml
533
- };