neuphlo-editor 1.4.7 → 1.4.8

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 (97) hide show
  1. package/dist/chunk-BYYL4NTM.js +620 -0
  2. package/dist/chunk-BYYL4NTM.js.map +1 -0
  3. package/dist/chunk-FR2S7WLJ.js +619 -0
  4. package/dist/chunk-FR2S7WLJ.js.map +1 -0
  5. package/dist/chunk-LMAPK3FZ.js +602 -0
  6. package/dist/chunk-LMAPK3FZ.js.map +1 -0
  7. package/dist/chunk-NVDAKTK5.js +625 -0
  8. package/dist/chunk-NVDAKTK5.js.map +1 -0
  9. package/dist/chunk-OWNLX6MZ.js +619 -0
  10. package/dist/chunk-OWNLX6MZ.js.map +1 -0
  11. package/dist/chunk-PNWSC5HP.js +619 -0
  12. package/dist/chunk-PNWSC5HP.js.map +1 -0
  13. package/dist/chunk-PTPOSXWA.js +619 -0
  14. package/dist/chunk-PTPOSXWA.js.map +1 -0
  15. package/dist/chunk-RNN6NQQ7.js +616 -0
  16. package/dist/chunk-RNN6NQQ7.js.map +1 -0
  17. package/dist/chunk-SWG4LKYM.js +594 -0
  18. package/dist/chunk-SWG4LKYM.js.map +1 -0
  19. package/dist/chunk-V5D6DU4F.js +627 -0
  20. package/dist/chunk-V5D6DU4F.js.map +1 -0
  21. package/dist/chunk-Y4MYTPNW.js +619 -0
  22. package/dist/chunk-Y4MYTPNW.js.map +1 -0
  23. package/dist/headless/components/editor-bubble-item.d.ts +9 -0
  24. package/dist/headless/components/editor-bubble-item.js +29 -0
  25. package/dist/headless/components/editor-bubble.d.ts +9 -0
  26. package/dist/headless/components/editor-bubble.js +9 -0
  27. package/dist/headless/components/editor-command-item.d.ts +3 -0
  28. package/dist/headless/components/editor-command-item.js +18 -0
  29. package/dist/headless/components/editor-command.d.ts +10 -0
  30. package/dist/headless/components/editor-command.js +48 -0
  31. package/dist/headless/components/editor.d.ts +24 -0
  32. package/dist/headless/components/editor.js +13 -0
  33. package/dist/headless/extensions/CodeBlock/CodeBlock.d.ts +1 -0
  34. package/dist/headless/extensions/CodeBlock/CodeBlock.js +6 -0
  35. package/dist/headless/extensions/CodeBlock/index.d.ts +1 -0
  36. package/dist/headless/extensions/CodeBlock/index.js +1 -0
  37. package/dist/headless/extensions/Image/Image.d.ts +6 -0
  38. package/dist/headless/extensions/Image/Image.js +197 -0
  39. package/dist/headless/extensions/ImageBlock/ImageBlock.d.ts +22 -0
  40. package/dist/headless/extensions/ImageBlock/ImageBlock.js +243 -0
  41. package/dist/headless/extensions/ImageBlock/index.d.ts +2 -0
  42. package/dist/headless/extensions/ImageBlock/index.js +1 -0
  43. package/dist/headless/extensions/Link/Link.d.ts +2 -0
  44. package/dist/headless/extensions/Link/Link.js +44 -0
  45. package/dist/headless/extensions/Link/index.d.ts +1 -0
  46. package/dist/headless/extensions/Link/index.js +1 -0
  47. package/dist/headless/extensions/extension-kit.d.ts +12 -0
  48. package/dist/headless/extensions/extension-kit.js +44 -0
  49. package/dist/headless/extensions/index.d.ts +6 -0
  50. package/dist/headless/extensions/index.js +6 -0
  51. package/dist/headless/extensions/slash-command.d.ts +36 -0
  52. package/dist/headless/extensions/slash-command.js +114 -0
  53. package/dist/headless/index.cjs +7 -0
  54. package/dist/headless/index.cjs.map +1 -1
  55. package/dist/headless/index.js +1 -1
  56. package/dist/headless/utils/atoms.d.ts +7 -0
  57. package/dist/headless/utils/atoms.js +3 -0
  58. package/dist/headless/utils/store.d.ts +2 -0
  59. package/dist/headless/utils/store.js +4 -0
  60. package/dist/react/Editor.d.ts +32 -0
  61. package/dist/react/Editor.js +43 -0
  62. package/dist/react/index.cjs +368 -309
  63. package/dist/react/index.cjs.map +1 -1
  64. package/dist/react/index.css.map +1 -1
  65. package/dist/react/index.js +355 -303
  66. package/dist/react/index.js.map +1 -1
  67. package/dist/react/menus/ImageBlock/ImageBlockLoading.d.ts +2 -0
  68. package/dist/react/menus/ImageBlock/ImageBlockLoading.js +6 -0
  69. package/dist/react/menus/ImageBlock/ImageBlockMenu.d.ts +7 -0
  70. package/dist/react/menus/ImageBlock/ImageBlockMenu.js +100 -0
  71. package/dist/react/menus/ImageBlock/ImageBlockView.d.ts +10 -0
  72. package/dist/react/menus/ImageBlock/ImageBlockView.js +44 -0
  73. package/dist/react/menus/ImageBlock/ImageBlockWidth.d.ts +6 -0
  74. package/dist/react/menus/ImageBlock/ImageBlockWidth.js +29 -0
  75. package/dist/react/menus/ImageBlock/ImageUploader.d.ts +7 -0
  76. package/dist/react/menus/ImageBlock/ImageUploader.js +63 -0
  77. package/dist/react/menus/ImageBlock/index.d.ts +4 -0
  78. package/dist/react/menus/ImageBlock/index.js +4 -0
  79. package/dist/react/menus/ImageMenu.d.ts +10 -0
  80. package/dist/react/menus/ImageMenu.js +76 -0
  81. package/dist/react/menus/ImagePopover.d.ts +8 -0
  82. package/dist/react/menus/ImagePopover.js +146 -0
  83. package/dist/react/menus/LinkEditor.d.ts +8 -0
  84. package/dist/react/menus/LinkEditor.js +38 -0
  85. package/dist/react/menus/LinkMenu.d.ts +2 -0
  86. package/dist/react/menus/LinkMenu.js +69 -0
  87. package/dist/react/menus/LinkPopover.d.ts +9 -0
  88. package/dist/react/menus/LinkPopover.js +113 -0
  89. package/dist/react/menus/MenuList.d.ts +10 -0
  90. package/dist/react/menus/MenuList.js +94 -0
  91. package/dist/react/menus/SlashMenu.d.ts +5 -0
  92. package/dist/react/menus/SlashMenu.js +79 -0
  93. package/dist/react/menus/TextMenu.d.ts +10 -0
  94. package/dist/react/menus/TextMenu.js +131 -0
  95. package/dist/react/menus/index.d.ts +10 -0
  96. package/dist/react/menus/index.js +6 -0
  97. package/package.json +16 -16
@@ -0,0 +1,620 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all2) => {
6
+ for (var name in all2)
7
+ __defProp(target, name, { get: all2[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
18
+
19
+ // src/headless/index.ts
20
+ import { useCurrentEditor as useCurrentEditor4 } from "@tiptap/react";
21
+
22
+ // src/headless/components/editor.tsx
23
+ import { EditorProvider } from "@tiptap/react";
24
+ import { forwardRef } from "react";
25
+ import { Provider } from "jotai";
26
+
27
+ // src/headless/utils/store.ts
28
+ var store_exports = {};
29
+ __export(store_exports, {
30
+ novelStore: () => novelStore
31
+ });
32
+ __reExport(store_exports, jotai_star);
33
+ import { createStore } from "jotai";
34
+ import * as jotai_star from "jotai";
35
+ var novelStore = createStore();
36
+
37
+ // src/headless/components/editor.tsx
38
+ import { jsx } from "react/jsx-runtime";
39
+ var EditorRoot = ({ children }) => {
40
+ return /* @__PURE__ */ jsx(Provider, { store: novelStore, children });
41
+ };
42
+ var EditorContent = forwardRef(
43
+ ({ className, children, initialContent, content, ...rest }, ref) => {
44
+ const effectiveContent = content ?? initialContent;
45
+ return /* @__PURE__ */ jsx("div", { ref, className, children: /* @__PURE__ */ jsx(EditorProvider, { ...rest, content: effectiveContent, children }) });
46
+ }
47
+ );
48
+ EditorContent.displayName = "EditorContent";
49
+
50
+ // src/headless/components/editor-bubble.tsx
51
+ import { useCurrentEditor } from "@tiptap/react";
52
+ import { BubbleMenu as BubbleMenuReact } from "@tiptap/react/menus";
53
+ import { jsx as jsx2 } from "react/jsx-runtime";
54
+ function EditorBubble({ className, children, ...rest }) {
55
+ const { editor } = useCurrentEditor();
56
+ if (!editor) return null;
57
+ return /* @__PURE__ */ jsx2(BubbleMenuReact, { editor, ...rest, children: /* @__PURE__ */ jsx2("div", { className, children }) });
58
+ }
59
+
60
+ // src/headless/components/editor-bubble-item.tsx
61
+ import { forwardRef as forwardRef2, isValidElement, cloneElement } from "react";
62
+ import { useCurrentEditor as useCurrentEditor2 } from "@tiptap/react";
63
+ import { jsx as jsx3 } from "react/jsx-runtime";
64
+ var EditorBubbleItem = forwardRef2(({ children, asChild, onSelect, ...rest }, ref) => {
65
+ const { editor } = useCurrentEditor2();
66
+ if (!editor) return null;
67
+ const handleClick = (e) => {
68
+ e.preventDefault();
69
+ onSelect?.(editor);
70
+ };
71
+ if (asChild && isValidElement(children)) {
72
+ const child = children;
73
+ const childOnClick = child.props?.onClick;
74
+ const mergedOnClick = (e) => {
75
+ childOnClick?.(e);
76
+ if (!e?.defaultPrevented) onSelect?.(editor);
77
+ };
78
+ return cloneElement(child, {
79
+ ...rest,
80
+ ref: child.ref ?? ref,
81
+ onClick: mergedOnClick
82
+ });
83
+ }
84
+ return /* @__PURE__ */ jsx3("div", { ref, ...rest, onClick: handleClick, children });
85
+ });
86
+ EditorBubbleItem.displayName = "EditorBubbleItem";
87
+
88
+ // src/headless/components/editor-command.tsx
89
+ import { useAtom, useSetAtom } from "jotai";
90
+ import { useEffect, forwardRef as forwardRef3 } from "react";
91
+ import { Command } from "cmdk";
92
+
93
+ // src/headless/utils/atoms.ts
94
+ import { atom } from "jotai";
95
+ var queryAtom = atom("");
96
+ var rangeAtom = atom(null);
97
+
98
+ // src/headless/components/editor-command.tsx
99
+ import tunnel from "tunnel-rat";
100
+ import { jsx as jsx4, jsxs } from "react/jsx-runtime";
101
+ var commandTunnel = tunnel();
102
+ var EditorCommandOut = ({
103
+ query,
104
+ range
105
+ }) => {
106
+ const setQuery = useSetAtom(queryAtom, { store: novelStore });
107
+ const setRange = useSetAtom(rangeAtom, { store: novelStore });
108
+ useEffect(() => {
109
+ setQuery(query);
110
+ }, [query, setQuery]);
111
+ useEffect(() => {
112
+ setRange(range);
113
+ }, [range, setRange]);
114
+ useEffect(() => {
115
+ const navigationKeys = ["ArrowUp", "ArrowDown", "Enter"];
116
+ const onKeyDown = (e) => {
117
+ if (navigationKeys.includes(e.key)) {
118
+ e.preventDefault();
119
+ const commandRef = document.querySelector("#slash-command");
120
+ if (commandRef)
121
+ commandRef.dispatchEvent(
122
+ new KeyboardEvent("keydown", {
123
+ key: e.key,
124
+ cancelable: true,
125
+ bubbles: true
126
+ })
127
+ );
128
+ return false;
129
+ }
130
+ };
131
+ document.addEventListener("keydown", onKeyDown);
132
+ return () => {
133
+ document.removeEventListener("keydown", onKeyDown);
134
+ };
135
+ }, []);
136
+ return /* @__PURE__ */ jsx4(commandTunnel.Out, {});
137
+ };
138
+ var CommandAny = Command;
139
+ var EditorCommand = forwardRef3(
140
+ ({ children, className, ...rest }, ref) => {
141
+ const [query, setQuery] = useAtom(queryAtom);
142
+ return /* @__PURE__ */ jsx4(commandTunnel.In, { children: /* @__PURE__ */ jsxs(
143
+ CommandAny,
144
+ {
145
+ ref,
146
+ onKeyDown: (e) => {
147
+ e.stopPropagation();
148
+ },
149
+ id: "slash-command",
150
+ className,
151
+ ...rest,
152
+ children: [
153
+ /* @__PURE__ */ jsx4(
154
+ CommandAny.Input,
155
+ {
156
+ value: query,
157
+ onValueChange: setQuery,
158
+ style: { display: "none" }
159
+ }
160
+ ),
161
+ children
162
+ ]
163
+ }
164
+ ) });
165
+ }
166
+ );
167
+ var EditorCommandList = Command.List;
168
+ EditorCommand.displayName = "EditorCommand";
169
+
170
+ // src/headless/components/editor-command-item.tsx
171
+ import { forwardRef as forwardRef4 } from "react";
172
+ import { CommandEmpty, CommandItem } from "cmdk";
173
+ import { useCurrentEditor as useCurrentEditor3 } from "@tiptap/react";
174
+ import { useAtomValue } from "jotai";
175
+ import { jsx as jsx5 } from "react/jsx-runtime";
176
+ var CommandItemAny = CommandItem;
177
+ var CommandEmptyAny = CommandEmpty;
178
+ var EditorCommandItem = forwardRef4(({ children, onCommand, ...rest }, ref) => {
179
+ const { editor } = useCurrentEditor3();
180
+ const range = useAtomValue(rangeAtom);
181
+ if (!editor || !range) return null;
182
+ return /* @__PURE__ */ jsx5(
183
+ CommandItemAny,
184
+ {
185
+ ref,
186
+ ...rest,
187
+ onSelect: () => onCommand({ editor, range }),
188
+ children
189
+ }
190
+ );
191
+ });
192
+ EditorCommandItem.displayName = "EditorCommandItem";
193
+ var EditorCommandEmpty = CommandEmptyAny;
194
+
195
+ // src/headless/extensions/index.ts
196
+ import { StarterKit } from "@tiptap/starter-kit";
197
+ import { Placeholder } from "@tiptap/extension-placeholder";
198
+
199
+ // src/headless/extensions/CodeBlock/CodeBlock.ts
200
+ import { CodeBlockLowlight } from "@tiptap/extension-code-block-lowlight";
201
+ import { all, createLowlight } from "lowlight";
202
+ var lowlight = createLowlight(all);
203
+ var CodeBlock = CodeBlockLowlight.configure({
204
+ lowlight
205
+ });
206
+
207
+ // src/headless/extensions/Link/Link.ts
208
+ import { mergeAttributes } from "@tiptap/core";
209
+ import TiptapLink from "@tiptap/extension-link";
210
+ import { Plugin } from "@tiptap/pm/state";
211
+ var Link = TiptapLink.extend({
212
+ inclusive: false,
213
+ parseHTML() {
214
+ return [
215
+ {
216
+ tag: 'a[href]:not([data-type="button"]):not([href *= "javascript:" i])'
217
+ }
218
+ ];
219
+ },
220
+ renderHTML({ HTMLAttributes }) {
221
+ return [
222
+ "a",
223
+ mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
224
+ class: "link"
225
+ }),
226
+ 0
227
+ ];
228
+ },
229
+ addProseMirrorPlugins() {
230
+ const { editor } = this;
231
+ return [
232
+ ...this.parent?.() || [],
233
+ new Plugin({
234
+ props: {
235
+ handleKeyDown: (view, event) => {
236
+ const { selection } = editor.state;
237
+ if (event.key === "Escape" && selection.empty !== true) {
238
+ editor.commands.focus(selection.to, { scrollIntoView: false });
239
+ }
240
+ return false;
241
+ }
242
+ }
243
+ })
244
+ ];
245
+ }
246
+ }).configure({
247
+ openOnClick: false,
248
+ autolink: true,
249
+ enableClickSelection: true
250
+ });
251
+
252
+ // src/headless/extensions/ImageBlock/ImageBlock.ts
253
+ import { mergeAttributes as mergeAttributes2 } from "@tiptap/core";
254
+ import { Image as TiptapImage } from "@tiptap/extension-image";
255
+ import { ReactNodeViewRenderer } from "@tiptap/react";
256
+ import { Plugin as Plugin2, PluginKey } from "@tiptap/pm/state";
257
+ var ImageBlock = TiptapImage.extend({
258
+ name: "imageBlock",
259
+ group: "block",
260
+ defining: true,
261
+ isolating: true,
262
+ addOptions() {
263
+ return {
264
+ ...this.parent?.(),
265
+ uploadImage: void 0,
266
+ inline: false
267
+ };
268
+ },
269
+ addAttributes() {
270
+ return {
271
+ src: {
272
+ default: "",
273
+ parseHTML: (element) => element.getAttribute("src"),
274
+ renderHTML: (attributes) => ({
275
+ src: attributes.src
276
+ })
277
+ },
278
+ width: {
279
+ default: "100%",
280
+ parseHTML: (element) => element.getAttribute("data-width"),
281
+ renderHTML: (attributes) => ({
282
+ "data-width": attributes.width
283
+ })
284
+ },
285
+ align: {
286
+ default: "center",
287
+ parseHTML: (element) => element.getAttribute("data-align"),
288
+ renderHTML: (attributes) => ({
289
+ "data-align": attributes.align
290
+ })
291
+ },
292
+ alt: {
293
+ default: void 0,
294
+ parseHTML: (element) => element.getAttribute("alt"),
295
+ renderHTML: (attributes) => ({
296
+ alt: attributes.alt
297
+ })
298
+ },
299
+ loading: {
300
+ default: false,
301
+ parseHTML: () => false,
302
+ renderHTML: () => ({})
303
+ }
304
+ };
305
+ },
306
+ parseHTML() {
307
+ return [
308
+ {
309
+ tag: 'img[src]:not([src^="data:"])',
310
+ getAttrs: (element) => {
311
+ const el = element;
312
+ return {
313
+ src: el.getAttribute("src"),
314
+ alt: el.getAttribute("alt"),
315
+ width: el.getAttribute("data-width") || "100%",
316
+ align: el.getAttribute("data-align") || "center"
317
+ };
318
+ }
319
+ }
320
+ ];
321
+ },
322
+ renderHTML({ HTMLAttributes }) {
323
+ return ["img", mergeAttributes2(HTMLAttributes)];
324
+ },
325
+ addCommands() {
326
+ return {
327
+ setImageBlock: (attrs) => ({ commands }) => {
328
+ return commands.insertContent({
329
+ type: "imageBlock",
330
+ attrs: { src: attrs.src }
331
+ });
332
+ },
333
+ setImageBlockAt: (attrs) => ({ commands }) => {
334
+ return commands.insertContentAt(attrs.pos, {
335
+ type: "imageBlock",
336
+ attrs: { src: attrs.src }
337
+ });
338
+ },
339
+ setImageBlockAlign: (align) => ({ commands }) => commands.updateAttributes("imageBlock", { align }),
340
+ setImageBlockWidth: (width) => ({ commands }) => commands.updateAttributes("imageBlock", {
341
+ width: `${Math.max(0, Math.min(100, width))}%`
342
+ })
343
+ };
344
+ },
345
+ addNodeView() {
346
+ if (this.options.nodeView) {
347
+ return ReactNodeViewRenderer(this.options.nodeView);
348
+ }
349
+ return null;
350
+ },
351
+ addProseMirrorPlugins() {
352
+ return [
353
+ new Plugin2({
354
+ key: new PluginKey("imageBlockDrop"),
355
+ props: {
356
+ handleDOMEvents: {
357
+ drop: (view, event) => {
358
+ const hasFiles = event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files.length;
359
+ if (!hasFiles) {
360
+ return false;
361
+ }
362
+ const images = Array.from(event.dataTransfer.files).filter(
363
+ (file) => /image/i.test(file.type)
364
+ );
365
+ if (images.length === 0) {
366
+ return false;
367
+ }
368
+ event.preventDefault();
369
+ const { schema } = view.state;
370
+ const coordinates = view.posAtCoords({
371
+ left: event.clientX,
372
+ top: event.clientY
373
+ });
374
+ if (!coordinates) return false;
375
+ images.forEach(async (image) => {
376
+ if (this.options.uploadImage) {
377
+ try {
378
+ const placeholderNode = schema.nodes.imageBlock.create({
379
+ src: "",
380
+ loading: true
381
+ });
382
+ const placeholderTr = view.state.tr.insert(
383
+ coordinates.pos,
384
+ placeholderNode
385
+ );
386
+ view.dispatch(placeholderTr);
387
+ const url = await this.options.uploadImage(image);
388
+ const node = schema.nodes.imageBlock.create({ src: url });
389
+ const currentState = view.state;
390
+ let foundPos = -1;
391
+ currentState.doc.descendants((node2, pos) => {
392
+ if (node2.type.name === "imageBlock" && node2.attrs.loading) {
393
+ foundPos = pos;
394
+ return false;
395
+ }
396
+ });
397
+ if (foundPos !== -1) {
398
+ const transaction = view.state.tr.replaceWith(
399
+ foundPos,
400
+ foundPos + 1,
401
+ node
402
+ );
403
+ view.dispatch(transaction);
404
+ }
405
+ } catch (error) {
406
+ console.error("Failed to upload image:", error);
407
+ const currentState = view.state;
408
+ let foundPos = -1;
409
+ currentState.doc.descendants((node, pos) => {
410
+ if (node.type.name === "imageBlock" && node.attrs.loading) {
411
+ foundPos = pos;
412
+ return false;
413
+ }
414
+ });
415
+ if (foundPos !== -1) {
416
+ const transaction = view.state.tr.delete(
417
+ foundPos,
418
+ foundPos + 1
419
+ );
420
+ view.dispatch(transaction);
421
+ }
422
+ }
423
+ }
424
+ });
425
+ return true;
426
+ },
427
+ paste: (view, event) => {
428
+ const hasFiles = event.clipboardData && event.clipboardData.files && event.clipboardData.files.length;
429
+ if (!hasFiles) {
430
+ return false;
431
+ }
432
+ const images = Array.from(event.clipboardData.files).filter(
433
+ (file) => /image/i.test(file.type)
434
+ );
435
+ if (images.length === 0) {
436
+ return false;
437
+ }
438
+ event.preventDefault();
439
+ images.forEach(async (image) => {
440
+ if (this.options.uploadImage) {
441
+ try {
442
+ const placeholderNode = view.state.schema.nodes.imageBlock.create({
443
+ src: "",
444
+ loading: true
445
+ });
446
+ view.dispatch(
447
+ view.state.tr.replaceSelectionWith(placeholderNode)
448
+ );
449
+ const url = await this.options.uploadImage(image);
450
+ const node = view.state.schema.nodes.imageBlock.create({
451
+ src: url
452
+ });
453
+ const currentState = view.state;
454
+ let foundPos = -1;
455
+ currentState.doc.descendants((node2, pos) => {
456
+ if (node2.type.name === "imageBlock" && node2.attrs.loading) {
457
+ foundPos = pos;
458
+ return false;
459
+ }
460
+ });
461
+ if (foundPos !== -1) {
462
+ const transaction = view.state.tr.replaceWith(
463
+ foundPos,
464
+ foundPos + 1,
465
+ node
466
+ );
467
+ view.dispatch(transaction);
468
+ }
469
+ } catch (error) {
470
+ console.error("Failed to upload image:", error);
471
+ const currentState = view.state;
472
+ let foundPos = -1;
473
+ currentState.doc.descendants((node, pos) => {
474
+ if (node.type.name === "imageBlock" && node.attrs.loading) {
475
+ foundPos = pos;
476
+ return false;
477
+ }
478
+ });
479
+ if (foundPos !== -1) {
480
+ const transaction = view.state.tr.delete(
481
+ foundPos,
482
+ foundPos + 1
483
+ );
484
+ view.dispatch(transaction);
485
+ }
486
+ }
487
+ }
488
+ });
489
+ return true;
490
+ }
491
+ }
492
+ }
493
+ })
494
+ ];
495
+ }
496
+ });
497
+
498
+ // src/headless/extensions/slash-command.tsx
499
+ import { ReactRenderer } from "@tiptap/react";
500
+ import Suggestion from "@tiptap/suggestion";
501
+ import { Extension } from "@tiptap/core";
502
+ var Command2 = Extension.create({
503
+ name: "slash-command",
504
+ addOptions() {
505
+ return {
506
+ suggestion: {
507
+ char: "/",
508
+ command: (ctx) => {
509
+ ctx.props.command({ editor: ctx.editor, range: ctx.range });
510
+ }
511
+ }
512
+ };
513
+ },
514
+ addProseMirrorPlugins() {
515
+ const base = this.options.suggestion ?? {};
516
+ return [
517
+ Suggestion({
518
+ editor: this.editor,
519
+ char: base.char ?? "/",
520
+ items: base.items ?? (() => ["/"]),
521
+ command: (ctx) => {
522
+ if (typeof ctx?.props?.command === "function") {
523
+ ctx.props.command({ editor: ctx.editor, range: ctx.range });
524
+ }
525
+ },
526
+ ...base
527
+ })
528
+ ];
529
+ }
530
+ });
531
+ var renderItems = (elementRef) => {
532
+ let component = null;
533
+ let container = null;
534
+ const destroy = () => {
535
+ component?.destroy();
536
+ component = null;
537
+ if (container) {
538
+ container.remove();
539
+ container = null;
540
+ }
541
+ };
542
+ const updatePosition = (clientRect) => {
543
+ if (!container || !clientRect) return;
544
+ const top = Math.round(clientRect.bottom + 8);
545
+ const left = Math.round(clientRect.left);
546
+ container.style.top = `${top}px`;
547
+ container.style.left = `${left}px`;
548
+ };
549
+ return {
550
+ onStart: (props) => {
551
+ const { selection } = props.editor.state;
552
+ const parentNode = selection.$from.node(selection.$from.depth);
553
+ const blockType = parentNode.type.name;
554
+ if (blockType === "codeBlock") return false;
555
+ component = new ReactRenderer(EditorCommandOut, {
556
+ props: {
557
+ query: props.query ?? "",
558
+ range: props.range
559
+ },
560
+ editor: props.editor
561
+ });
562
+ container = document.createElement("div");
563
+ container.style.position = "fixed";
564
+ container.style.zIndex = "9999";
565
+ container.style.minWidth = "240px";
566
+ (elementRef?.current ?? document.body).appendChild(container);
567
+ container.appendChild(component.element);
568
+ const rect = typeof props.clientRect === "function" ? props.clientRect() : null;
569
+ if (rect) updatePosition(rect);
570
+ },
571
+ onUpdate: (props) => {
572
+ component?.updateProps({
573
+ query: props.query ?? "",
574
+ range: props.range
575
+ });
576
+ const rect = typeof props.clientRect === "function" ? props.clientRect() : null;
577
+ if (rect) updatePosition(rect);
578
+ },
579
+ onKeyDown: ({ event }) => {
580
+ if (event.key === "Escape") {
581
+ destroy();
582
+ return true;
583
+ }
584
+ return false;
585
+ },
586
+ onExit: () => {
587
+ destroy();
588
+ }
589
+ };
590
+ };
591
+ var createSuggestionItems = (items) => items;
592
+ var handleCommandNavigation = (event) => {
593
+ if (["ArrowUp", "ArrowDown", "Enter"].includes(event.key)) {
594
+ const slashCommand = document.querySelector("#slash-command");
595
+ if (slashCommand) return true;
596
+ }
597
+ };
598
+
599
+ export {
600
+ EditorRoot,
601
+ EditorContent,
602
+ EditorBubble,
603
+ EditorBubbleItem,
604
+ EditorCommandOut,
605
+ EditorCommand,
606
+ EditorCommandList,
607
+ EditorCommandItem,
608
+ EditorCommandEmpty,
609
+ CodeBlock,
610
+ Link,
611
+ ImageBlock,
612
+ StarterKit,
613
+ Placeholder,
614
+ Command2 as Command,
615
+ renderItems,
616
+ createSuggestionItems,
617
+ handleCommandNavigation,
618
+ useCurrentEditor4 as useCurrentEditor
619
+ };
620
+ //# sourceMappingURL=chunk-BYYL4NTM.js.map