@lobehub/editor 4.25.1 → 4.26.0
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/es/headless.d.ts
CHANGED
package/es/headless.js
CHANGED
package/es/locale/index.d.ts
CHANGED
package/es/locale/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useLexicalEditor } from "../../../../editor-kernel/react/useLexicalEditor.js";
|
|
2
|
+
import { useTranslation } from "../../../../editor-kernel/react/useTranslation.js";
|
|
2
3
|
import { $isBlockImageNode } from "../../node/block-image-node.js";
|
|
3
4
|
import { useLexicalNodeSelection } from "../../../../editor-kernel/react/useLexicalNodeSelection.js";
|
|
4
5
|
import { styles } from "./style.js";
|
|
@@ -6,20 +7,22 @@ import BrokenImage from "./BrokenImage.js";
|
|
|
6
7
|
import ImageEditPopover from "./ImageEditPopover.js";
|
|
7
8
|
import LazyImage from "./LazyImage.js";
|
|
8
9
|
import { ResizeHandle } from "./ResizeHandle.js";
|
|
9
|
-
import { Icon } from "@lobehub/ui";
|
|
10
|
-
import { LoaderCircleIcon } from "lucide-react";
|
|
10
|
+
import { ActionIcon, Icon } from "@lobehub/ui";
|
|
11
|
+
import { LoaderCircleIcon, ZoomInIcon } from "lucide-react";
|
|
11
12
|
import { Suspense, memo, useCallback, useMemo, useRef, useState } from "react";
|
|
12
13
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
13
14
|
import { cx } from "antd-style";
|
|
15
|
+
import { Image } from "antd";
|
|
14
16
|
import { COMMAND_PRIORITY_LOW, SELECTION_CHANGE_COMMAND } from "lexical";
|
|
15
17
|
//#region src/plugins/image/react/components/Image.tsx
|
|
16
18
|
function getResizedImageWidth(startWidth, deltaX, maxWidth) {
|
|
17
19
|
const adjustedDeltaX = deltaX * 2;
|
|
18
20
|
return Math.max(50, Math.min(startWidth + adjustedDeltaX, maxWidth));
|
|
19
21
|
}
|
|
20
|
-
const Image = memo(({ node, className, showScaleInfo = false, handleUpload, onPickFile }) => {
|
|
22
|
+
const Image$1 = memo(({ node, className, showScaleInfo = false, handleUpload, onPickFile }) => {
|
|
21
23
|
const [isSelected, setSelected] = useLexicalNodeSelection(node.getKey());
|
|
22
24
|
const [isHovered, setIsHovered] = useState(false);
|
|
25
|
+
const [previewOpen, setPreviewOpen] = useState(false);
|
|
23
26
|
const [scale, setScale] = useState(1);
|
|
24
27
|
const [size, setSize] = useState({
|
|
25
28
|
height: 0,
|
|
@@ -34,6 +37,7 @@ const Image = memo(({ node, className, showScaleInfo = false, handleUpload, onPi
|
|
|
34
37
|
const editorRef = useRef(null);
|
|
35
38
|
const startWidthRef = useRef(0);
|
|
36
39
|
const lastLoadedSrcRef = useRef(null);
|
|
40
|
+
const t = useTranslation();
|
|
37
41
|
const isBlock = useMemo(() => {
|
|
38
42
|
return $isBlockImageNode(node);
|
|
39
43
|
}, [node]);
|
|
@@ -92,6 +96,11 @@ const Image = memo(({ node, className, showScaleInfo = false, handleUpload, onPi
|
|
|
92
96
|
const handleMouseLeave = useCallback(() => {
|
|
93
97
|
setIsHovered(false);
|
|
94
98
|
}, []);
|
|
99
|
+
const handlePreview = useCallback((e) => {
|
|
100
|
+
e.preventDefault();
|
|
101
|
+
e.stopPropagation();
|
|
102
|
+
setPreviewOpen(true);
|
|
103
|
+
}, []);
|
|
95
104
|
const children = useMemo(() => {
|
|
96
105
|
switch (node.status) {
|
|
97
106
|
case "error": return /* @__PURE__ */ jsx(BrokenImage, {});
|
|
@@ -167,6 +176,23 @@ const Image = memo(({ node, className, showScaleInfo = false, handleUpload, onPi
|
|
|
167
176
|
spin: true
|
|
168
177
|
})
|
|
169
178
|
}),
|
|
179
|
+
(isHovered || isSelected) && node.status === "uploaded" && /* @__PURE__ */ jsx(ActionIcon, {
|
|
180
|
+
"aria-label": t("image.preview"),
|
|
181
|
+
glass: true,
|
|
182
|
+
className: styles.previewAction,
|
|
183
|
+
icon: ZoomInIcon,
|
|
184
|
+
onClick: handlePreview,
|
|
185
|
+
size: "small",
|
|
186
|
+
title: t("image.preview"),
|
|
187
|
+
variant: "filled"
|
|
188
|
+
}),
|
|
189
|
+
/* @__PURE__ */ jsx(Image.PreviewGroup, {
|
|
190
|
+
items: [node.src],
|
|
191
|
+
preview: {
|
|
192
|
+
open: previewOpen,
|
|
193
|
+
onOpenChange: setPreviewOpen
|
|
194
|
+
}
|
|
195
|
+
}),
|
|
170
196
|
showScaleInfo && isSelected && scale !== 1 && /* @__PURE__ */ jsxs("div", {
|
|
171
197
|
className: styles.scaleInfo,
|
|
172
198
|
children: [Math.round(scale * 100), "%"]
|
|
@@ -190,6 +216,6 @@ const Image = memo(({ node, className, showScaleInfo = false, handleUpload, onPi
|
|
|
190
216
|
})
|
|
191
217
|
});
|
|
192
218
|
});
|
|
193
|
-
Image.displayName = "Image";
|
|
219
|
+
Image$1.displayName = "Image";
|
|
194
220
|
//#endregion
|
|
195
|
-
export { Image as default };
|
|
221
|
+
export { Image$1 as default };
|
|
@@ -78,6 +78,32 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
78
78
|
justify-content: center;
|
|
79
79
|
|
|
80
80
|
color: ${cssVar.colorTextSecondary};
|
|
81
|
+
`,
|
|
82
|
+
previewAction: css`
|
|
83
|
+
position: absolute;
|
|
84
|
+
z-index: 10000;
|
|
85
|
+
inset-block-start: 8px;
|
|
86
|
+
inset-inline-end: 8px;
|
|
87
|
+
|
|
88
|
+
&& {
|
|
89
|
+
border: 1px solid rgb(255 255 255 / 24%);
|
|
90
|
+
|
|
91
|
+
color: rgb(255 255 255 / 96%);
|
|
92
|
+
|
|
93
|
+
background: rgb(0 0 0 / 58%);
|
|
94
|
+
backdrop-filter: saturate(120%) blur(12px);
|
|
95
|
+
box-shadow: 0 2px 8px rgb(0 0 0 / 36%);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
&&:hover {
|
|
99
|
+
color: rgb(255 255 255);
|
|
100
|
+
background: rgb(0 0 0 / 72%);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
&&:active {
|
|
104
|
+
color: rgb(255 255 255);
|
|
105
|
+
background: rgb(0 0 0 / 80%);
|
|
106
|
+
}
|
|
81
107
|
`,
|
|
82
108
|
resizeHandle: css`
|
|
83
109
|
pointer-events: auto;
|
package/package.json
CHANGED