@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/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, suppressContentEditableWarning: true })] }));
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) {