@overlap/rte 0.1.7 → 0.1.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.
- package/dist/components/Editor.d.ts.map +1 -1
- package/dist/index.esm.js +83 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +83 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3053,8 +3053,75 @@ const Editor = ({ initialContent, onChange, plugins: providedPlugins, placeholde
|
|
|
3053
3053
|
if (onEditorAPIReady)
|
|
3054
3054
|
onEditorAPIReady(editorAPI);
|
|
3055
3055
|
}, [editorAPI, onEditorAPIReady]);
|
|
3056
|
+
// --- Helper: insert an image file via the onImageUpload callback ---
|
|
3057
|
+
const insertImageFile = React.useCallback(async (file) => {
|
|
3058
|
+
if (!onImageUpload || !file.type.startsWith("image/"))
|
|
3059
|
+
return;
|
|
3060
|
+
const editor = editorRef.current;
|
|
3061
|
+
if (!editor)
|
|
3062
|
+
return;
|
|
3063
|
+
try {
|
|
3064
|
+
// Show a placeholder while uploading
|
|
3065
|
+
const placeholder = document.createElement("img");
|
|
3066
|
+
placeholder.setAttribute("data-uploading", "true");
|
|
3067
|
+
placeholder.style.maxWidth = "100%";
|
|
3068
|
+
placeholder.style.height = "auto";
|
|
3069
|
+
placeholder.style.display = "block";
|
|
3070
|
+
placeholder.style.margin = "16px 0";
|
|
3071
|
+
placeholder.style.opacity = "0.5";
|
|
3072
|
+
// Use a tiny transparent gif as placeholder src
|
|
3073
|
+
placeholder.src =
|
|
3074
|
+
"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
3075
|
+
placeholder.alt = file.name;
|
|
3076
|
+
const sel = window.getSelection();
|
|
3077
|
+
if (sel && sel.rangeCount > 0) {
|
|
3078
|
+
const range = sel.getRangeAt(0);
|
|
3079
|
+
range.deleteContents();
|
|
3080
|
+
range.insertNode(placeholder);
|
|
3081
|
+
range.setStartAfter(placeholder);
|
|
3082
|
+
range.collapse(true);
|
|
3083
|
+
sel.removeAllRanges();
|
|
3084
|
+
sel.addRange(range);
|
|
3085
|
+
}
|
|
3086
|
+
else {
|
|
3087
|
+
editor.appendChild(placeholder);
|
|
3088
|
+
}
|
|
3089
|
+
// Upload
|
|
3090
|
+
const url = await onImageUpload(file);
|
|
3091
|
+
// Replace placeholder with final image
|
|
3092
|
+
placeholder.src = url;
|
|
3093
|
+
placeholder.removeAttribute("data-uploading");
|
|
3094
|
+
placeholder.style.opacity = "1";
|
|
3095
|
+
// Preserve data-attachment-id if returned in a special format
|
|
3096
|
+
// The onImageUpload callback can return "url|attachmentId"
|
|
3097
|
+
if (url.includes("|__aid__:")) {
|
|
3098
|
+
const [realUrl, aid] = url.split("|__aid__:");
|
|
3099
|
+
placeholder.src = realUrl;
|
|
3100
|
+
placeholder.setAttribute("data-attachment-id", aid);
|
|
3101
|
+
}
|
|
3102
|
+
notifyChange(domToContent(editor));
|
|
3103
|
+
}
|
|
3104
|
+
catch (err) {
|
|
3105
|
+
console.error("Image upload failed:", err);
|
|
3106
|
+
// Remove failed placeholder
|
|
3107
|
+
const failedImg = editor.querySelector('img[data-uploading="true"]');
|
|
3108
|
+
failedImg?.remove();
|
|
3109
|
+
}
|
|
3110
|
+
}, [onImageUpload, notifyChange]);
|
|
3056
3111
|
// --- Paste handler ---
|
|
3057
3112
|
const handlePaste = (e) => {
|
|
3113
|
+
// Check for pasted image files first
|
|
3114
|
+
const items = e.clipboardData.items;
|
|
3115
|
+
for (let i = 0; i < items.length; i++) {
|
|
3116
|
+
const item = items[i];
|
|
3117
|
+
if (item.type.startsWith("image/")) {
|
|
3118
|
+
e.preventDefault();
|
|
3119
|
+
const file = item.getAsFile();
|
|
3120
|
+
if (file)
|
|
3121
|
+
insertImageFile(file);
|
|
3122
|
+
return;
|
|
3123
|
+
}
|
|
3124
|
+
}
|
|
3058
3125
|
e.preventDefault();
|
|
3059
3126
|
const html = e.clipboardData.getData("text/html");
|
|
3060
3127
|
const text = e.clipboardData.getData("text/plain");
|
|
@@ -3121,7 +3188,22 @@ const Editor = ({ initialContent, onChange, plugins: providedPlugins, placeholde
|
|
|
3121
3188
|
}),
|
|
3122
3189
|
}
|
|
3123
3190
|
: {};
|
|
3124
|
-
return (jsxRuntime.jsxs("div", { className: `rte-container ${className || ""}`, style: containerStyle, children: [jsxRuntime.jsx(Toolbar, { plugins: plugins, editorAPI: editorAPI, className: toolbarClassName }), jsxRuntime.jsx("div", { ref: editorRef, contentEditable: true, className: `rte-editor ${editorClassName || ""}`, "data-placeholder": placeholder, onPaste: handlePaste,
|
|
3191
|
+
return (jsxRuntime.jsxs("div", { className: `rte-container ${className || ""}`, style: containerStyle, children: [jsxRuntime.jsx(Toolbar, { plugins: plugins, editorAPI: editorAPI, className: toolbarClassName }), jsxRuntime.jsx("div", { ref: editorRef, contentEditable: true, className: `rte-editor ${editorClassName || ""}`, "data-placeholder": placeholder, onPaste: handlePaste, onDrop: (e) => {
|
|
3192
|
+
const files = e.dataTransfer.files;
|
|
3193
|
+
for (let i = 0; i < files.length; i++) {
|
|
3194
|
+
if (files[i].type.startsWith("image/")) {
|
|
3195
|
+
e.preventDefault();
|
|
3196
|
+
insertImageFile(files[i]);
|
|
3197
|
+
return;
|
|
3198
|
+
}
|
|
3199
|
+
}
|
|
3200
|
+
}, onDragOver: (e) => {
|
|
3201
|
+
// Allow drop
|
|
3202
|
+
const types = e.dataTransfer.types;
|
|
3203
|
+
if (types && Array.from(types).includes("Files")) {
|
|
3204
|
+
e.preventDefault();
|
|
3205
|
+
}
|
|
3206
|
+
}, suppressContentEditableWarning: true })] }));
|
|
3125
3207
|
};
|
|
3126
3208
|
// --- Helper: Insert Image ---
|
|
3127
3209
|
function handleInsertImage(editor, value, isUpdatingRef, historyRef, notifyChange) {
|