@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.
- package/dist/DropZoneOverlay.d.ts +24 -0
- package/dist/DropZoneOverlay.d.ts.map +1 -0
- package/dist/DropZoneOverlay.js +53 -0
- package/dist/DropZoneOverlay.js.map +1 -0
- package/dist/EditorContext.d.ts +10 -2
- package/dist/EditorContext.d.ts.map +1 -1
- package/dist/EditorContext.js +49 -1
- package/dist/EditorContext.js.map +1 -1
- package/dist/EditorShell.d.ts +16 -1
- package/dist/EditorShell.d.ts.map +1 -1
- package/dist/EditorShell.js +55 -8
- package/dist/EditorShell.js.map +1 -1
- package/dist/ImageNodeView.d.ts +15 -0
- package/dist/ImageNodeView.d.ts.map +1 -0
- package/dist/ImageNodeView.js +52 -0
- package/dist/ImageNodeView.js.map +1 -0
- package/dist/MediaBin.d.ts +18 -0
- package/dist/MediaBin.d.ts.map +1 -0
- package/dist/MediaBin.js +141 -0
- package/dist/MediaBin.js.map +1 -0
- package/dist/PreviewControls.d.ts +41 -0
- package/dist/PreviewControls.d.ts.map +1 -0
- package/dist/PreviewControls.js +201 -0
- package/dist/PreviewControls.js.map +1 -0
- package/dist/PreviewPanel.d.ts +7 -7
- package/dist/PreviewPanel.d.ts.map +1 -1
- package/dist/PreviewPanel.js +183 -199
- package/dist/PreviewPanel.js.map +1 -1
- package/dist/Toolbar.d.ts +12 -1
- package/dist/Toolbar.d.ts.map +1 -1
- package/dist/Toolbar.js +4 -12
- package/dist/Toolbar.js.map +1 -1
- package/dist/WysiwygEditor.d.ts.map +1 -1
- package/dist/WysiwygEditor.js +3 -1
- package/dist/WysiwygEditor.js.map +1 -1
- package/dist/hooks/useFileDrop.d.ts +41 -0
- package/dist/hooks/useFileDrop.d.ts.map +1 -0
- package/dist/hooks/useFileDrop.js +167 -0
- package/dist/hooks/useFileDrop.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/tiptapBridge.d.ts.map +1 -1
- package/dist/tiptapBridge.js +4 -5
- package/dist/tiptapBridge.js.map +1 -1
- package/dist/utils/dropUtils.d.ts +36 -0
- package/dist/utils/dropUtils.d.ts.map +1 -0
- package/dist/utils/dropUtils.js +71 -0
- package/dist/utils/dropUtils.js.map +1 -0
- package/package.json +5 -3
- package/src/DropZoneOverlay.tsx +137 -0
- package/src/EditorContext.tsx +64 -1
- package/src/EditorShell.tsx +153 -20
- package/src/ImageNodeView.tsx +70 -0
- package/src/MediaBin.tsx +223 -0
- package/src/PreviewControls.tsx +340 -0
- package/src/PreviewPanel.tsx +216 -287
- package/src/Toolbar.tsx +40 -3
- package/src/WysiwygEditor.tsx +3 -1
- package/src/hooks/useFileDrop.ts +226 -0
- package/src/index.ts +29 -0
- package/src/styles/editor.css +349 -8
- package/src/tiptapBridge.ts +5 -6
- package/src/utils/dropUtils.ts +88 -0
package/src/tiptapBridge.ts
CHANGED
|
@@ -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
|
-
//
|
|
43
|
-
|
|
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:  — 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: 
|
|
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
|
+
}
|