@elia-ori/editor 0.1.1 → 0.1.3

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.d.cts CHANGED
@@ -23,7 +23,7 @@ interface ToolbarProps {
23
23
  toolbarEnd?: React.ReactNode;
24
24
  theme?: string;
25
25
  onThemeToggle?: () => void;
26
- onImageUpload?: (file: File) => void;
26
+ onImageUpload?: (file: File) => Promise<string> | void;
27
27
  }
28
28
  declare function Toolbar({ editor, config, toolbarStart, toolbarEnd, theme, onThemeToggle, onImageUpload, }: ToolbarProps): react_jsx_runtime.JSX.Element | null;
29
29
 
@@ -42,7 +42,7 @@ interface EliaEditorProps {
42
42
  readOnly?: boolean;
43
43
  theme?: string;
44
44
  onThemeToggle?: () => void;
45
- onImageUpload?: (file: File) => void;
45
+ onImageUpload?: (file: File) => Promise<string> | void;
46
46
  }
47
47
  declare function EliaEditor({ content, onChange, placeholder, toolbar, header, toolbarStart, toolbarEnd, footer, className, editorClassName, autofocus, readOnly, theme, onThemeToggle, onImageUpload, }: EliaEditorProps): react_jsx_runtime.JSX.Element;
48
48
 
package/dist/index.d.ts CHANGED
@@ -23,7 +23,7 @@ interface ToolbarProps {
23
23
  toolbarEnd?: React.ReactNode;
24
24
  theme?: string;
25
25
  onThemeToggle?: () => void;
26
- onImageUpload?: (file: File) => void;
26
+ onImageUpload?: (file: File) => Promise<string> | void;
27
27
  }
28
28
  declare function Toolbar({ editor, config, toolbarStart, toolbarEnd, theme, onThemeToggle, onImageUpload, }: ToolbarProps): react_jsx_runtime.JSX.Element | null;
29
29
 
@@ -42,7 +42,7 @@ interface EliaEditorProps {
42
42
  readOnly?: boolean;
43
43
  theme?: string;
44
44
  onThemeToggle?: () => void;
45
- onImageUpload?: (file: File) => void;
45
+ onImageUpload?: (file: File) => Promise<string> | void;
46
46
  }
47
47
  declare function EliaEditor({ content, onChange, placeholder, toolbar, header, toolbarStart, toolbarEnd, footer, className, editorClassName, autofocus, readOnly, theme, onThemeToggle, onImageUpload, }: EliaEditorProps): react_jsx_runtime.JSX.Element;
48
48
 
package/dist/index.js CHANGED
@@ -4145,6 +4145,50 @@ var Callout = Node3.create({
4145
4145
  // src/components/Toolbar.tsx
4146
4146
  import { useRef } from "react";
4147
4147
 
4148
+ // src/lib/compress-image.ts
4149
+ var DEFAULT_MAX_SIZE_MB = 1;
4150
+ var DEFAULT_MAX_DIMENSION = 1920;
4151
+ var DEFAULT_QUALITY = 0.85;
4152
+ async function compressImage(file, options = {}) {
4153
+ const {
4154
+ maxSizeMB = DEFAULT_MAX_SIZE_MB,
4155
+ maxDimension = DEFAULT_MAX_DIMENSION,
4156
+ quality = DEFAULT_QUALITY
4157
+ } = options;
4158
+ if (file.size <= maxSizeMB * 1024 * 1024) {
4159
+ return file;
4160
+ }
4161
+ const img = new Image();
4162
+ const canvas = document.createElement("canvas");
4163
+ const ctx = canvas.getContext("2d");
4164
+ return new Promise((resolve, reject) => {
4165
+ img.onload = () => {
4166
+ let { width, height } = img;
4167
+ if (width > maxDimension || height > maxDimension) {
4168
+ const ratio = Math.min(maxDimension / width, maxDimension / height);
4169
+ width = Math.round(width * ratio);
4170
+ height = Math.round(height * ratio);
4171
+ }
4172
+ canvas.width = width;
4173
+ canvas.height = height;
4174
+ ctx.drawImage(img, 0, 0, width, height);
4175
+ canvas.toBlob(
4176
+ (blob) => {
4177
+ if (!blob) {
4178
+ reject(new Error("\u5716\u7247\u58D3\u7E2E\u5931\u6557"));
4179
+ return;
4180
+ }
4181
+ resolve(new File([blob], file.name, { type: "image/jpeg" }));
4182
+ },
4183
+ "image/jpeg",
4184
+ quality
4185
+ );
4186
+ };
4187
+ img.onerror = () => reject(new Error("\u5716\u7247\u8F09\u5165\u5931\u6557"));
4188
+ img.src = URL.createObjectURL(file);
4189
+ });
4190
+ }
4191
+
4148
4192
  // src/ui/button.tsx
4149
4193
  import * as React from "react";
4150
4194
 
@@ -4653,27 +4697,32 @@ function Toolbar({
4653
4697
  }
4654
4698
  editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
4655
4699
  };
4656
- const handleImageUpload = (e) => {
4700
+ const handleImageUpload = async (e) => {
4657
4701
  const file = e.target.files?.[0];
4658
4702
  if (!file) return;
4659
- const MAX_SIZE = 5 * 1024 * 1024;
4660
- if (file.size > MAX_SIZE) {
4661
- alert("\u5716\u7247\u5927\u5C0F\u4E0D\u53EF\u8D85\u904E 5MB");
4662
- e.target.value = "";
4663
- return;
4664
- }
4665
- if (onImageUpload) {
4666
- onImageUpload(file);
4667
- } else {
4668
- const reader = new FileReader();
4669
- reader.onload = () => {
4670
- const base64 = reader.result;
4671
- editor.chain().focus().setImage({ src: base64 }).run();
4672
- };
4673
- reader.onerror = () => {
4674
- console.error("\u5716\u7247\u8B80\u53D6\u5931\u6557");
4675
- };
4676
- reader.readAsDataURL(file);
4703
+ try {
4704
+ const compressed = await compressImage(file);
4705
+ if (onImageUpload) {
4706
+ const result = onImageUpload(compressed);
4707
+ if (result instanceof Promise) {
4708
+ const url = await result;
4709
+ if (url) {
4710
+ editor.chain().focus().setImage({ src: url }).run();
4711
+ }
4712
+ }
4713
+ } else {
4714
+ const reader = new FileReader();
4715
+ reader.onload = () => {
4716
+ const base64 = reader.result;
4717
+ editor.chain().focus().setImage({ src: base64 }).run();
4718
+ };
4719
+ reader.onerror = () => {
4720
+ console.error("\u5716\u7247\u8B80\u53D6\u5931\u6557");
4721
+ };
4722
+ reader.readAsDataURL(compressed);
4723
+ }
4724
+ } catch (error) {
4725
+ console.error("\u5716\u7247\u8655\u7406\u5931\u6557:", error);
4677
4726
  }
4678
4727
  e.target.value = "";
4679
4728
  };