@bendyline/squisq-editor-react 1.0.1 → 1.1.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 (65) hide show
  1. package/dist/DropZoneOverlay.d.ts +24 -0
  2. package/dist/DropZoneOverlay.d.ts.map +1 -0
  3. package/dist/DropZoneOverlay.js +53 -0
  4. package/dist/DropZoneOverlay.js.map +1 -0
  5. package/dist/EditorContext.d.ts +10 -2
  6. package/dist/EditorContext.d.ts.map +1 -1
  7. package/dist/EditorContext.js +49 -1
  8. package/dist/EditorContext.js.map +1 -1
  9. package/dist/EditorShell.d.ts +16 -1
  10. package/dist/EditorShell.d.ts.map +1 -1
  11. package/dist/EditorShell.js +55 -8
  12. package/dist/EditorShell.js.map +1 -1
  13. package/dist/ImageNodeView.d.ts +15 -0
  14. package/dist/ImageNodeView.d.ts.map +1 -0
  15. package/dist/ImageNodeView.js +52 -0
  16. package/dist/ImageNodeView.js.map +1 -0
  17. package/dist/MediaBin.d.ts +18 -0
  18. package/dist/MediaBin.d.ts.map +1 -0
  19. package/dist/MediaBin.js +141 -0
  20. package/dist/MediaBin.js.map +1 -0
  21. package/dist/PreviewControls.d.ts +41 -0
  22. package/dist/PreviewControls.d.ts.map +1 -0
  23. package/dist/PreviewControls.js +201 -0
  24. package/dist/PreviewControls.js.map +1 -0
  25. package/dist/PreviewPanel.d.ts +7 -7
  26. package/dist/PreviewPanel.d.ts.map +1 -1
  27. package/dist/PreviewPanel.js +183 -199
  28. package/dist/PreviewPanel.js.map +1 -1
  29. package/dist/Toolbar.d.ts +12 -1
  30. package/dist/Toolbar.d.ts.map +1 -1
  31. package/dist/Toolbar.js +4 -12
  32. package/dist/Toolbar.js.map +1 -1
  33. package/dist/WysiwygEditor.d.ts.map +1 -1
  34. package/dist/WysiwygEditor.js +3 -1
  35. package/dist/WysiwygEditor.js.map +1 -1
  36. package/dist/hooks/useFileDrop.d.ts +41 -0
  37. package/dist/hooks/useFileDrop.d.ts.map +1 -0
  38. package/dist/hooks/useFileDrop.js +167 -0
  39. package/dist/hooks/useFileDrop.js.map +1 -0
  40. package/dist/index.d.ts +9 -0
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +6 -0
  43. package/dist/index.js.map +1 -1
  44. package/dist/tiptapBridge.d.ts.map +1 -1
  45. package/dist/tiptapBridge.js +4 -5
  46. package/dist/tiptapBridge.js.map +1 -1
  47. package/dist/utils/dropUtils.d.ts +36 -0
  48. package/dist/utils/dropUtils.d.ts.map +1 -0
  49. package/dist/utils/dropUtils.js +71 -0
  50. package/dist/utils/dropUtils.js.map +1 -0
  51. package/package.json +5 -3
  52. package/src/DropZoneOverlay.tsx +137 -0
  53. package/src/EditorContext.tsx +64 -1
  54. package/src/EditorShell.tsx +153 -20
  55. package/src/ImageNodeView.tsx +70 -0
  56. package/src/MediaBin.tsx +223 -0
  57. package/src/PreviewControls.tsx +340 -0
  58. package/src/PreviewPanel.tsx +216 -287
  59. package/src/Toolbar.tsx +40 -3
  60. package/src/WysiwygEditor.tsx +3 -1
  61. package/src/hooks/useFileDrop.ts +226 -0
  62. package/src/index.ts +29 -0
  63. package/src/styles/editor.css +349 -8
  64. package/src/tiptapBridge.ts +5 -6
  65. package/src/utils/dropUtils.ts +88 -0
@@ -39,9 +39,8 @@ const RE_STRIP_TAGS = /<[^>]+>/g;
39
39
  export function markdownToTiptap(markdown: string): string {
40
40
  if (!markdown.trim()) return '<p></p>';
41
41
 
42
- // Simple conversion of markdown constructs to HTML that Tiptap understands.
43
- // This is intentionally straightforward — Tiptap's parser handles the HTML.
44
- const html = markdown;
42
+ // Normalize line endings content from zip archives may use \r\n
43
+ const html = markdown.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
45
44
 
46
45
  // Process blocks line by line for accurate conversion
47
46
  const lines = html.split('\n');
@@ -384,12 +383,12 @@ function inlineToHtml(text: string): string {
384
383
  // Inline code: `text`
385
384
  result = result.replace(RE_INLINE_CODE, '<code>$1</code>');
386
385
 
386
+ // Images first: ![alt](src) — must be before links so the `!` prefix is consumed
387
+ result = result.replace(RE_IMAGE, '<img alt="$1" src="$2">');
388
+
387
389
  // Links: [text](url)
388
390
  result = result.replace(RE_LINK, '<a href="$2">$1</a>');
389
391
 
390
- // Images: ![alt](src)
391
- result = result.replace(RE_IMAGE, '<img alt="$1" src="$2">');
392
-
393
392
  return result;
394
393
  }
395
394
 
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Drop Utilities
3
+ *
4
+ * File processing pipeline for dropped files. Classifies files by type,
5
+ * processes media files into a MediaProvider, and converts text files
6
+ * (.md, .txt, .docx) to markdown strings.
7
+ */
8
+
9
+ import type { MediaProvider } from '@bendyline/squisq/schemas';
10
+ import { stringifyMarkdown } from '@bendyline/squisq/markdown';
11
+ import { docxToMarkdownDoc } from '@bendyline/squisq-formats/docx';
12
+ import { classifyFile, type FileCategory } from '../hooks/useFileDrop';
13
+
14
+ export type { FileCategory };
15
+ export { classifyFile };
16
+
17
+ /**
18
+ * Partition an array of files into media and text categories.
19
+ * Files with unknown type are skipped.
20
+ */
21
+ export function partitionFiles(files: File[]): { media: File[]; text: File[] } {
22
+ const media: File[] = [];
23
+ const text: File[] = [];
24
+
25
+ for (const file of files) {
26
+ const cat = classifyFile(file);
27
+ if (cat === 'media') media.push(file);
28
+ else if (cat === 'text') text.push(file);
29
+ }
30
+
31
+ return { media, text };
32
+ }
33
+
34
+ /**
35
+ * Add media files to a MediaProvider. Returns the relative paths
36
+ * assigned by the provider.
37
+ */
38
+ export async function processMediaFiles(
39
+ files: File[],
40
+ mediaProvider: MediaProvider,
41
+ ): Promise<string[]> {
42
+ const paths: string[] = [];
43
+
44
+ for (const file of files) {
45
+ const buffer = await file.arrayBuffer();
46
+ const mimeType = file.type || 'application/octet-stream';
47
+ const path = await mediaProvider.addMedia(file.name, buffer, mimeType);
48
+ paths.push(path);
49
+ }
50
+
51
+ return paths;
52
+ }
53
+
54
+ /**
55
+ * Read a text-content file and return its content as a markdown string.
56
+ *
57
+ * - `.md` and `.txt` files are read as UTF-8 text directly
58
+ * - `.docx` files are converted to markdown via `@bendyline/squisq-formats/docx`
59
+ */
60
+ export async function processTextFile(file: File): Promise<string> {
61
+ const ext = file.name.split('.').pop()?.toLowerCase() ?? '';
62
+
63
+ if (ext === 'md' || ext === 'txt') {
64
+ return await file.text();
65
+ }
66
+
67
+ if (ext === 'docx') {
68
+ const buffer = await file.arrayBuffer();
69
+ const markdownDoc = await docxToMarkdownDoc(buffer);
70
+ return stringifyMarkdown(markdownDoc);
71
+ }
72
+
73
+ return await file.text();
74
+ }
75
+
76
+ /**
77
+ * Process multiple text files and concatenate their content.
78
+ */
79
+ export async function processTextFiles(files: File[]): Promise<string> {
80
+ const results: string[] = [];
81
+
82
+ for (const file of files) {
83
+ const content = await processTextFile(file);
84
+ results.push(content);
85
+ }
86
+
87
+ return results.join('\n\n');
88
+ }