@lobehub/editor 1.24.0 → 1.25.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.
Files changed (57) hide show
  1. package/README.md +9 -4
  2. package/es/editor-kernel/kernel.d.ts +3 -1
  3. package/es/editor-kernel/kernel.js +27 -8
  4. package/es/editor-kernel/react/useEditable.d.ts +3 -0
  5. package/es/editor-kernel/react/useEditable.js +32 -0
  6. package/es/index.d.ts +1 -0
  7. package/es/index.js +1 -0
  8. package/es/plugins/auto-complete/index.d.ts +2 -0
  9. package/es/plugins/auto-complete/index.js +2 -0
  10. package/es/plugins/auto-complete/node/placeholderNode.d.ts +30 -0
  11. package/es/plugins/auto-complete/node/placeholderNode.js +171 -0
  12. package/es/plugins/auto-complete/plugin/index.d.ts +17 -0
  13. package/es/plugins/auto-complete/plugin/index.js +398 -0
  14. package/es/plugins/auto-complete/react/ReactAutoCompletePlugin.d.ts +4 -0
  15. package/es/plugins/auto-complete/react/ReactAutoCompletePlugin.js +35 -0
  16. package/es/plugins/auto-complete/react/index.d.ts +1 -0
  17. package/es/plugins/auto-complete/react/index.js +1 -0
  18. package/es/plugins/auto-complete/react/style.d.ts +4 -0
  19. package/es/plugins/auto-complete/react/style.js +10 -0
  20. package/es/plugins/auto-complete/react/type.d.ts +11 -0
  21. package/es/plugins/auto-complete/react/type.js +1 -0
  22. package/es/plugins/common/plugin/index.js +0 -1
  23. package/es/plugins/common/plugin/register.js +3 -0
  24. package/es/plugins/common/react/ReactPlainText.js +9 -2
  25. package/es/plugins/common/react/style.js +1 -1
  26. package/es/plugins/common/react/type.d.ts +1 -0
  27. package/es/plugins/image/command/index.d.ts +2 -0
  28. package/es/plugins/image/command/index.js +10 -2
  29. package/es/plugins/image/node/basie-image-node.d.ts +1 -0
  30. package/es/plugins/image/node/basie-image-node.js +5 -0
  31. package/es/plugins/image/node/block-image-node.d.ts +31 -0
  32. package/es/plugins/image/node/block-image-node.js +209 -0
  33. package/es/plugins/image/node/image-node.d.ts +3 -0
  34. package/es/plugins/image/node/image-node.js +17 -0
  35. package/es/plugins/image/plugin/index.d.ts +4 -1
  36. package/es/plugins/image/plugin/index.js +51 -11
  37. package/es/plugins/image/react/ReactImagePlugin.js +3 -1
  38. package/es/plugins/image/react/components/Image.d.ts +4 -3
  39. package/es/plugins/image/react/components/Image.js +272 -24
  40. package/es/plugins/image/react/components/LazyImage.d.ts +7 -1
  41. package/es/plugins/image/react/components/LazyImage.js +11 -3
  42. package/es/plugins/image/react/components/style.d.ts +40 -0
  43. package/es/plugins/image/react/components/style.js +43 -0
  44. package/es/plugins/image/react/style.d.ts +10 -0
  45. package/es/plugins/image/react/style.js +10 -0
  46. package/es/plugins/image/react/type.d.ts +2 -0
  47. package/es/plugins/link/react/components/LinkEdit.js +4 -1
  48. package/es/plugins/link/react/components/LinkToolbar.js +5 -1
  49. package/es/plugins/markdown/service/shortcut.d.ts +7 -2
  50. package/es/plugins/markdown/service/shortcut.js +12 -1
  51. package/es/plugins/markdown/utils/index.d.ts +2 -0
  52. package/es/plugins/markdown/utils/index.js +4 -1
  53. package/es/react/Editor/Editor.js +2 -0
  54. package/es/react/Editor/type.d.ts +1 -0
  55. package/es/react/hooks/useEditorState/index.js +41 -33
  56. package/es/types/kernel.d.ts +14 -1
  57. package/package.json +1 -1
@@ -1,39 +1,231 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
1
2
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
3
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
4
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
5
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
5
6
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
6
7
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
8
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
9
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
10
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
11
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
12
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7
13
  import { COMMAND_PRIORITY_LOW, SELECTION_CHANGE_COMMAND } from 'lexical';
8
- import { memo, useMemo } from 'react';
14
+ import React, { memo, useCallback, useMemo, useRef, useState } from 'react';
9
15
  import { useLexicalEditor } from "../../../../editor-kernel/react/useLexicalEditor";
10
16
  import { useLexicalNodeSelection } from "../../../../editor-kernel/react/useLexicalNodeSelection";
17
+ import { $isBlockImageNode } from "../../node/block-image-node";
11
18
  import BrokenImage from "./BrokenImage";
12
19
  import LazyImage from "./LazyImage";
20
+ import { useStyles } from "./style";
13
21
  import { jsx as _jsx } from "react/jsx-runtime";
14
- var Image = /*#__PURE__*/memo(function (_ref) {
15
- var node = _ref.node,
16
- className = _ref.className;
22
+ import { jsxs as _jsxs } from "react/jsx-runtime";
23
+ import { Fragment as _Fragment } from "react/jsx-runtime";
24
+ var ResizeHandle = /*#__PURE__*/memo(function (_ref) {
25
+ var onResize = _ref.onResize,
26
+ onResizeEnd = _ref.onResizeEnd,
27
+ onResizeStart = _ref.onResizeStart,
28
+ position = _ref.position,
29
+ isBlock = _ref.isBlock,
30
+ imageRef = _ref.imageRef;
31
+ var startWidthRef = useRef(0);
32
+ var handleMouseDown = useCallback(function (e) {
33
+ var _imageRef$current;
34
+ e.preventDefault();
35
+ e.stopPropagation();
36
+
37
+ // Get the actual current width at mousedown time
38
+ var initialWidth = ((_imageRef$current = imageRef.current) === null || _imageRef$current === void 0 ? void 0 : _imageRef$current.offsetWidth) || 0;
39
+ startWidthRef.current = initialWidth;
40
+
41
+ // Notify parent component of the initial width
42
+ onResizeStart(initialWidth);
43
+ var startX = e.clientX;
44
+ var startY = e.clientY;
45
+ var rect = isBlock ? e.target.getBoundingClientRect() : {
46
+ height: 0,
47
+ left: 0,
48
+ top: 0,
49
+ width: 0
50
+ };
51
+ var centerX = rect.left + rect.width / 2;
52
+ var lastDeltaX = 0;
53
+ var lastDeltaY = 0;
54
+ var handleMouseMove = function handleMouseMove(e) {
55
+ var deltaX = e.clientX - startX;
56
+ var deltaY = e.clientY - startY;
57
+
58
+ // Only adjust deltaX based on the resize handle position
59
+ switch (position) {
60
+ case 'left':
61
+ {
62
+ deltaX = isBlock ? centerX - e.clientX : -deltaX;
63
+ break;
64
+ }
65
+ case 'right':
66
+ {
67
+ if (isBlock) {
68
+ deltaX = e.clientX - centerX;
69
+ }
70
+ break;
71
+ }
72
+ }
73
+ lastDeltaX = deltaX;
74
+ lastDeltaY = deltaY;
75
+ onResize(deltaX, deltaY, position);
76
+ };
77
+ var handleMouseUp = function handleMouseUp() {
78
+ document.removeEventListener('mousemove', handleMouseMove);
79
+ document.removeEventListener('mouseup', handleMouseUp);
80
+ if (typeof onResizeEnd === 'function') {
81
+ onResizeEnd(lastDeltaX, lastDeltaY);
82
+ }
83
+ };
84
+ document.addEventListener('mousemove', handleMouseMove);
85
+ document.addEventListener('mouseup', handleMouseUp);
86
+ }, [onResize, onResizeEnd, onResizeStart, position, imageRef]);
87
+ var getPositionStyle = function getPositionStyle() {
88
+ var baseStyle = {
89
+ backgroundColor: '#999999',
90
+ borderRadius: 2,
91
+ cursor: 'col-resize',
92
+ height: '60%',
93
+ opacity: 0.6,
94
+ pointerEvents: 'auto',
95
+ position: 'absolute',
96
+ top: '20%',
97
+ width: 4,
98
+ zIndex: 9999
99
+ };
100
+ switch (position) {
101
+ case 'left':
102
+ {
103
+ return _objectSpread(_objectSpread({}, baseStyle), {}, {
104
+ left: 20
105
+ });
106
+ }
107
+ case 'right':
108
+ {
109
+ return _objectSpread(_objectSpread({}, baseStyle), {}, {
110
+ right: 20
111
+ });
112
+ }
113
+ }
114
+ };
115
+ return /*#__PURE__*/_jsx("div", {
116
+ onMouseDown: handleMouseDown,
117
+ style: getPositionStyle()
118
+ });
119
+ });
120
+ ResizeHandle.displayName = 'ResizeHandle';
121
+ var Image = /*#__PURE__*/memo(function (_ref2) {
122
+ var node = _ref2.node,
123
+ className = _ref2.className;
124
+ var _useStyles = useStyles(),
125
+ styles = _useStyles.styles,
126
+ cx = _useStyles.cx;
17
127
  var _useLexicalNodeSelect = useLexicalNodeSelection(node.getKey()),
18
128
  _useLexicalNodeSelect2 = _slicedToArray(_useLexicalNodeSelect, 2),
19
129
  isSelected = _useLexicalNodeSelect2[0],
20
130
  setSelected = _useLexicalNodeSelect2[1];
21
- // const [isNodeSelect] = useState(false);
22
-
23
- // useEffect(() => {
24
- // if (isSelected) {
25
- // console.log('Image selected:', node.getKey());
26
- // } else {
27
- // console.log('Image deselected:', node.getKey());
28
- // }
29
- // }, [isSelected, node]);
30
-
131
+ var _useState = useState(1),
132
+ _useState2 = _slicedToArray(_useState, 2),
133
+ scale = _useState2[0],
134
+ setScale = _useState2[1];
135
+ var _useState3 = useState({
136
+ height: 0,
137
+ width: 0
138
+ }),
139
+ _useState4 = _slicedToArray(_useState3, 2),
140
+ size = _useState4[0],
141
+ setSize = _useState4[1];
142
+ var _useState5 = useState(null),
143
+ _useState6 = _slicedToArray(_useState5, 2),
144
+ newWidth = _useState6[0],
145
+ setNewWidth = _useState6[1];
146
+ var imageRef = useRef(null);
147
+ var originalSizeRef = useRef({
148
+ height: 0,
149
+ width: 0
150
+ });
151
+ var editorRef = useRef(null);
152
+ var startWidthRef = useRef(0);
153
+ var isBlock = useMemo(function () {
154
+ return $isBlockImageNode(node);
155
+ }, [node]);
31
156
  useLexicalEditor(function (editor) {
32
- return editor.registerCommand(SELECTION_CHANGE_COMMAND,
157
+ editorRef.current = editor;
158
+ var unregister = editor.registerCommand(SELECTION_CHANGE_COMMAND,
33
159
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
34
160
  function (_, _activeEditor) {
35
161
  return false;
36
162
  }, COMMAND_PRIORITY_LOW);
163
+ return function () {
164
+ editorRef.current = null;
165
+ unregister();
166
+ };
167
+ }, []);
168
+
169
+ // Resize by dragging - only control width; height is calculated by aspect ratio
170
+ var handleResize = useCallback(function (deltaX) {
171
+ var _imageRef$current$par;
172
+ if (!originalSizeRef.current.width || !originalSizeRef.current.height) return;
173
+ if (!imageRef.current) return;
174
+ var aspectRatio = originalSizeRef.current.width / originalSizeRef.current.height;
175
+
176
+ // Get parent container width to limit max width
177
+ var parentWidth = ((_imageRef$current$par = imageRef.current.parentElement) === null || _imageRef$current$par === void 0 ? void 0 : _imageRef$current$par.clientWidth) || window.innerWidth;
178
+ var maxWidth = parentWidth;
179
+
180
+ // Since image is centered, delta is halved (both sides resize)
181
+ var adjustedDeltaX = deltaX * 2;
182
+
183
+ // Use the width captured at mousedown time
184
+ var newWidth = Math.max(50, Math.min(startWidthRef.current + adjustedDeltaX, maxWidth));
185
+
186
+ // Calculate new height based on the original aspect ratio
187
+ var newHeight = newWidth / aspectRatio;
188
+ setSize({
189
+ height: newHeight,
190
+ width: newWidth
191
+ });
192
+ setNewWidth(newWidth);
193
+
194
+ // Update the scale
195
+ var newScale = newWidth / originalSizeRef.current.width;
196
+ setScale(newScale);
197
+ }, []);
198
+
199
+ // Store the initial width when resize starts
200
+ var handleResizeStart = useCallback(function (initialWidth) {
201
+ startWidthRef.current = initialWidth;
202
+ }, []);
203
+
204
+ // Click to select
205
+ var handleClick = useCallback(function (e) {
206
+ e.stopPropagation();
207
+ setSelected(true);
208
+ }, [setSelected]);
209
+
210
+ // Double-click to reset to original size and aspect ratio
211
+ var handleDoubleClick = useCallback(function (e) {
212
+ var editor = editorRef.current;
213
+ if (!editor) return;
214
+ e.stopPropagation();
215
+ e.preventDefault();
216
+ var orig = originalSizeRef.current;
217
+ if (!orig.width || !orig.height) return;
218
+ setSize(orig);
219
+ setScale(1);
220
+ setNewWidth(orig.width);
221
+ editor.update(function () {
222
+ try {
223
+ node.setWidth(orig.width);
224
+ node.setMaxWidth(orig.width);
225
+ } catch (_unused) {
226
+ // ignore errors silently
227
+ }
228
+ });
37
229
  }, []);
38
230
  var children = useMemo(function () {
39
231
  switch (node.status) {
@@ -46,7 +238,13 @@ var Image = /*#__PURE__*/memo(function (_ref) {
46
238
  {
47
239
  return /*#__PURE__*/_jsx(LazyImage, {
48
240
  className: className,
49
- node: node
241
+ newWidth: newWidth,
242
+ node: node,
243
+ onLoad: function onLoad(size) {
244
+ originalSizeRef.current.width = size.width;
245
+ originalSizeRef.current.height = size.height;
246
+ setSize(size);
247
+ }
50
248
  });
51
249
  }
52
250
  default:
@@ -54,17 +252,67 @@ var Image = /*#__PURE__*/memo(function (_ref) {
54
252
  return null;
55
253
  }
56
254
  }
57
- }, [node.status, className, node]);
58
- return /*#__PURE__*/_jsx("div", {
255
+ }, [node.status, className, node, newWidth]);
256
+
257
+ // On resize end, persist to node (set maxWidth)
258
+ var handleResizeEnd = useCallback(function (deltaX) {
259
+ var _imageRef$current$par2;
260
+ if (!originalSizeRef.current.width || !originalSizeRef.current.height) return;
261
+ if (!imageRef.current) return;
262
+
263
+ // Get parent container width to limit max width
264
+ var parentWidth = ((_imageRef$current$par2 = imageRef.current.parentElement) === null || _imageRef$current$par2 === void 0 ? void 0 : _imageRef$current$par2.clientWidth) || window.innerWidth;
265
+ var maxWidth = parentWidth;
266
+
267
+ // Since image is centered, delta is halved (both sides resize)
268
+ var adjustedDeltaX = deltaX / 2;
269
+
270
+ // Use the width captured at mousedown time
271
+ var finalWidth = Math.max(50, Math.min(startWidthRef.current + adjustedDeltaX, maxWidth));
272
+
273
+ // persist to node via editor.update
274
+ var editor = editorRef.current;
275
+ if (!editor) return;
276
+ editor.update(function () {
277
+ try {
278
+ node.setWidth(finalWidth);
279
+ node.setMaxWidth(finalWidth);
280
+ } catch (_unused2) {
281
+ // ignore errors silently
282
+ }
283
+ });
284
+ }, [node]);
285
+ return /*#__PURE__*/_jsxs("div", {
286
+ className: cx(styles.imageContainer, {
287
+ selected: isSelected
288
+ }),
59
289
  draggable: false,
60
- onClick: function onClick() {
61
- return setSelected(true);
62
- },
290
+ onClick: handleClick,
291
+ onDoubleClick: handleDoubleClick,
292
+ ref: imageRef,
63
293
  style: {
64
- border: isSelected ? '1px solid blue' : '1px solid transparent',
65
- display: 'inline-block'
294
+ width: size.width || 'auto'
66
295
  },
67
- children: children
296
+ children: [children, isSelected && scale !== 1 && /*#__PURE__*/_jsxs("div", {
297
+ className: styles.scaleInfo,
298
+ children: [Math.round(scale * 100), "%"]
299
+ }), isSelected && /*#__PURE__*/_jsxs(_Fragment, {
300
+ children: [/*#__PURE__*/_jsx(ResizeHandle, {
301
+ imageRef: imageRef,
302
+ isBlock: isBlock,
303
+ onResize: handleResize,
304
+ onResizeEnd: handleResizeEnd,
305
+ onResizeStart: handleResizeStart,
306
+ position: "left"
307
+ }), /*#__PURE__*/_jsx(ResizeHandle, {
308
+ imageRef: imageRef,
309
+ isBlock: isBlock,
310
+ onResize: handleResize,
311
+ onResizeEnd: handleResizeEnd,
312
+ onResizeStart: handleResizeStart,
313
+ position: "right"
314
+ })]
315
+ })]
68
316
  });
69
317
  });
70
318
  Image.displayName = 'Image';
@@ -1,8 +1,14 @@
1
1
  /// <reference types="react" />
2
+ import { BlockImageNode } from '../../node/block-image-node';
2
3
  import { ImageNode } from '../../node/image-node';
3
4
  declare const LazyImage: import("react").NamedExoticComponent<{
4
5
  className?: string | null | undefined;
5
- node: ImageNode;
6
+ newWidth?: number | null | undefined;
7
+ node: ImageNode | BlockImageNode;
6
8
  onError?: (() => void) | undefined;
9
+ onLoad?: ((dimensions: {
10
+ height: number;
11
+ width: number;
12
+ }) => void) | undefined;
7
13
  }>;
8
14
  export default LazyImage;
@@ -20,7 +20,9 @@ function isSVG(src) {
20
20
  var LazyImage = /*#__PURE__*/memo(function (_ref) {
21
21
  var className = _ref.className,
22
22
  node = _ref.node,
23
- onError = _ref.onError;
23
+ newWidth = _ref.newWidth,
24
+ onError = _ref.onError,
25
+ _onLoad = _ref.onLoad;
24
26
  var src = node.src,
25
27
  altText = node.altText,
26
28
  maxWidth = node.maxWidth,
@@ -81,17 +83,23 @@ var LazyImage = /*#__PURE__*/memo(function (_ref) {
81
83
  draggable: "false",
82
84
  onError: onError,
83
85
  onLoad: function onLoad(e) {
86
+ var img = e.currentTarget;
84
87
  if (isSVGImage) {
85
- var img = e.currentTarget;
86
88
  setDimensions({
87
89
  height: img.naturalHeight,
88
90
  width: img.naturalWidth
89
91
  });
90
92
  }
93
+ _onLoad === null || _onLoad === void 0 || _onLoad({
94
+ height: img.naturalHeight,
95
+ width: img.naturalWidth
96
+ });
91
97
  },
92
98
  src: src,
93
99
  style: _objectSpread(_objectSpread({}, imageStyle), {}, {
94
- cursor: 'default'
100
+ cursor: 'default',
101
+ maxWidth: "calc(min(".concat(newWidth || imageStyle.maxWidth, "px, 100%))"),
102
+ width: newWidth || imageStyle.width
95
103
  })
96
104
  });
97
105
  });
@@ -0,0 +1,40 @@
1
+ export declare const useStyles: (props?: unknown) => import("antd-style").ReturnStyles<{
2
+ imageContainer: {
3
+ '&.selected': {
4
+ cursor: "pointer";
5
+ outline: string;
6
+ };
7
+ '&.selected::after': {
8
+ backgroundColor: "rgba(0, 102, 255, 0.15)";
9
+ bottom: number;
10
+ content: "\"\"";
11
+ left: number;
12
+ pointerEvents: "none";
13
+ position: "absolute";
14
+ right: number;
15
+ top: number;
16
+ zIndex: number;
17
+ };
18
+ cursor: "default";
19
+ display: "inline-block";
20
+ height: string;
21
+ maxWidth: string;
22
+ outline: string;
23
+ position: "relative";
24
+ transition: "border-color 0.2s ease";
25
+ userSelect: "none";
26
+ width: string;
27
+ };
28
+ scaleInfo: {
29
+ backgroundColor: "rgba(0, 0, 0, 0.7)";
30
+ borderRadius: number;
31
+ color: "white";
32
+ fontSize: number;
33
+ left: number;
34
+ padding: string;
35
+ pointerEvents: "none";
36
+ position: "absolute";
37
+ top: number;
38
+ zIndex: number;
39
+ };
40
+ }>;
@@ -0,0 +1,43 @@
1
+ import { createStyles } from 'antd-style';
2
+ export var useStyles = createStyles(function () {
3
+ return {
4
+ imageContainer: {
5
+ '&.selected': {
6
+ cursor: 'pointer',
7
+ outline: 'none'
8
+ },
9
+ '&.selected::after': {
10
+ backgroundColor: 'rgba(0, 102, 255, 0.15)',
11
+ bottom: 0,
12
+ content: '""',
13
+ left: 0,
14
+ pointerEvents: 'none',
15
+ position: 'absolute',
16
+ right: 0,
17
+ top: 0,
18
+ zIndex: 10
19
+ },
20
+ 'cursor': 'default',
21
+ 'display': 'inline-block',
22
+ 'height': 'auto',
23
+ 'maxWidth': '100%',
24
+ 'outline': '2px solid transparent',
25
+ 'position': 'relative',
26
+ 'transition': 'border-color 0.2s ease',
27
+ 'userSelect': 'none',
28
+ 'width': 'auto'
29
+ },
30
+ scaleInfo: {
31
+ backgroundColor: 'rgba(0, 0, 0, 0.7)',
32
+ borderRadius: 3,
33
+ color: 'white',
34
+ fontSize: 12,
35
+ left: 0,
36
+ padding: '2px 6px',
37
+ pointerEvents: 'none',
38
+ position: 'absolute',
39
+ top: -25,
40
+ zIndex: 11
41
+ }
42
+ };
43
+ });
@@ -8,5 +8,15 @@ export declare const useStyles: (props?: unknown) => import("antd-style").Return
8
8
  backgroundColor: string;
9
9
  };
10
10
  };
11
+ blockImage: {
12
+ userSelect: "none";
13
+ position: "relative";
14
+ display: "block";
15
+ textAlign: "center";
16
+ cursor: "default";
17
+ '&.selected': {
18
+ backgroundColor: string;
19
+ };
20
+ };
11
21
  }>;
12
22
  export declare const imageBroken = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA2NDAgNDAwIj48cGF0aCBmaWxsPSIjM0IzQjNCIiBkPSJNMCAwaDY0MHY0MDBIMHoiLz48cGF0aCBzdHJva2U9IiM2MjYyNjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxNSIgZD0iTTM3Mi41IDEzMi41aC0xMDVjLTguMjg0IDAtMTUgNi43MTYtMTUgMTV2MTA1YzAgOC4yODQgNi43MTYgMTUgMTUgMTVoMTA1YzguMjg0IDAgMTUtNi43MTYgMTUtMTV2LTEwNWMwLTguMjg0LTYuNzE2LTE1LTE1LTE1eiIvPjxwYXRoIHN0cm9rZT0iIzYyNjI2MiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjE1IiBkPSJNMjk3LjUgMTkyLjVjOC4yODQgMCAxNS02LjcxNiAxNS0xNSAwLTguMjg0LTYuNzE2LTE1LTE1LTE1LTguMjg0IDAtMTUgNi43MTYtMTUgMTUgMCA4LjI4NCA2LjcxNiAxNSAxNSAxNXpNMzg3LjUgMjIyLjUwMmwtMjMuMTQ1LTIzLjE0NWExNS4wMDEgMTUuMDAxIDAgMDAtMjEuMjEgMEwyNzUgMjY3LjUwMiIvPjwvc3ZnPg==";
@@ -11,6 +11,16 @@ export var useStyles = createStyles(function (_ref) {
11
11
  '&.selected': {
12
12
  backgroundColor: token.colorPrimaryBg
13
13
  }
14
+ },
15
+ blockImage: {
16
+ 'userSelect': 'none',
17
+ 'position': 'relative',
18
+ 'display': 'block',
19
+ 'textAlign': 'center',
20
+ 'cursor': 'default',
21
+ '&.selected': {
22
+ backgroundColor: token.colorPrimaryBg
23
+ }
14
24
  }
15
25
  };
16
26
  });
@@ -1,6 +1,8 @@
1
1
  export interface ReactImagePluginProps {
2
2
  className?: string;
3
+ defaultBlockImage?: boolean;
3
4
  theme?: {
5
+ blockImage?: string;
4
6
  image?: string;
5
7
  };
6
8
  }
@@ -11,6 +11,7 @@ import { BaselineIcon, LinkIcon } from 'lucide-react';
11
11
  import { memo, useCallback, useEffect, useRef, useState } from 'react';
12
12
  import { Flexbox } from 'react-layout-kit';
13
13
  import { useLexicalEditor } from "../../../../editor-kernel/react";
14
+ import { useEditable } from "../../../../editor-kernel/react/useEditable";
14
15
  import { useTranslation } from "../../../../editor-kernel/react/useTranslation";
15
16
  import { cleanPosition, updatePosition } from "../../../../utils/updatePosition";
16
17
  import { UPDATE_LINK_TEXT_COMMAND } from "../../command";
@@ -36,6 +37,8 @@ var LinkEdit = /*#__PURE__*/memo(function (_ref) {
36
37
  _useState6 = _slicedToArray(_useState5, 2),
37
38
  linkDom = _useState6[0],
38
39
  setLinkDom = _useState6[1];
40
+ var _useEditable = useEditable(),
41
+ editable = _useEditable.editable;
39
42
  var t = useTranslation();
40
43
  var _useStyles = useStyles(),
41
44
  styles = _useStyles.styles,
@@ -194,7 +197,7 @@ var LinkEdit = /*#__PURE__*/memo(function (_ref) {
194
197
  return false;
195
198
  }, COMMAND_PRIORITY_NORMAL));
196
199
  }, []);
197
- if (!linkNodeRef.current) return null;
200
+ if (!linkNodeRef.current || !editable) return null;
198
201
  return /*#__PURE__*/_jsxs(Block, {
199
202
  className: styles.linkEdit,
200
203
  ref: divRef,
@@ -11,6 +11,7 @@ import { $createRangeSelection, $getNodeByKey, $getSelection, $isRangeSelection,
11
11
  import { EditIcon, ExternalLinkIcon, UnlinkIcon } from 'lucide-react';
12
12
  import { memo, useCallback, useRef, useState } from 'react';
13
13
  import { useLexicalEditor } from "../../../../editor-kernel/react";
14
+ import { useEditable } from "../../../../editor-kernel/react/useEditable";
14
15
  import { useTranslation } from "../../../../editor-kernel/react/useTranslation";
15
16
  import { getSelectedNode } from "../../utils";
16
17
  import { cleanPosition, updatePosition } from "../../../../utils/updatePosition";
@@ -33,6 +34,8 @@ var LinkToolbar = /*#__PURE__*/memo(function (_ref) {
33
34
  });
34
35
  var t = useTranslation();
35
36
  var clearTimerRef = useRef(-1);
37
+ var _useEditable = useEditable(),
38
+ editable = _useEditable.editable;
36
39
  var handleEdit = useCallback(function () {
37
40
  if (!linkNode) return;
38
41
  editor.dispatchCommand(EDIT_LINK_COMMAND, {
@@ -90,6 +93,7 @@ var LinkToolbar = /*#__PURE__*/memo(function (_ref) {
90
93
  window.open(url, '_blank');
91
94
  }, [editor, linkNode]);
92
95
  useLexicalEditor(function (editor) {
96
+ if (!editable) return;
93
97
  return mergeRegister(editor.registerUpdateListener(function () {
94
98
  var selection = editor.read(function () {
95
99
  return $getSelection();
@@ -137,7 +141,7 @@ var LinkToolbar = /*#__PURE__*/memo(function (_ref) {
137
141
  clearTimerRef.current = setTimeout(handleCancel, 300);
138
142
  return true;
139
143
  }, COMMAND_PRIORITY_NORMAL));
140
- }, []);
144
+ }, [editable]);
141
145
  return /*#__PURE__*/_jsx(ActionIconGroup, {
142
146
  className: styles.linkToolbar,
143
147
  items: [{
@@ -1,6 +1,7 @@
1
- import { ElementNode, LexicalNode, TextNode } from 'lexical';
1
+ import { BaseSelection, ElementNode, LexicalEditor, LexicalNode, TextNode } from 'lexical';
2
+ import { IRootNode } from "../../../editor-kernel/inode";
2
3
  import type { IEditorKernel, IServiceID } from "../../../types/kernel";
3
- import type { MarkdownReaderFunc, TransformerRecord, TransfromerRecordArray } from '../data-source/markdown/parse';
4
+ import { type MarkdownReaderFunc, type TransformerRecord, type TransfromerRecordArray } from '../data-source/markdown/parse';
4
5
  import type { Transformer } from './transformers';
5
6
  export interface IMarkdownWriterContext {
6
7
  /**
@@ -27,6 +28,8 @@ export declare const MARKDOWN_READER_LEVEL_HIGH = 1;
27
28
  export declare const MARKDOWN_READER_LEVEL_NORMAL = 2;
28
29
  export type MARKDOWN_READER_LEVEL = typeof MARKDOWN_READER_LEVEL_HIGH | typeof MARKDOWN_READER_LEVEL_NORMAL | typeof MARKDOWN_WRITER_LEVEL_MAX;
29
30
  export interface IMarkdownShortCutService {
31
+ insertIRootNode(editor: LexicalEditor, root: IRootNode, selection: BaseSelection): void;
32
+ parseMarkdownToLexical(markdown: string): IRootNode;
30
33
  /**
31
34
  * Register Markdown reader
32
35
  */
@@ -75,4 +78,6 @@ export declare class MarkdownShortCutService implements IMarkdownShortCutService
75
78
  runTransformers(parentNode: ElementNode, anchorNode: TextNode, anchorOffset: number, trigger?: 'enter'): boolean;
76
79
  registerMarkdownWriter(type: string, writer: (ctx: IMarkdownWriterContext, node: LexicalNode) => boolean | void): void;
77
80
  registerMarkdownReader<K extends keyof TransformerRecord>(type: K, reader: MarkdownReaderFunc<K>, level?: MARKDOWN_READER_LEVEL): void;
81
+ parseMarkdownToLexical(markdown: string): IRootNode;
82
+ insertIRootNode(editor: LexicalEditor, root: IRootNode, selection: BaseSelection): void;
78
83
  }
@@ -17,7 +17,8 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
17
17
 
18
18
  import { genServiceId } from "../../../editor-kernel";
19
19
  import { createDebugLogger } from "../../../utils/debug";
20
- import { indexBy } from "../utils";
20
+ import { parseMarkdownToLexical as _parseMarkdownToLexical } from "../data-source/markdown/parse";
21
+ import { indexBy, insertIRootNode as _insertIRootNode } from "../utils";
21
22
  import { $runTextFormatTransformers, runElementTransformers, runTextMatchTransformers, testElementTransformers } from "./transformers";
22
23
  export var MARKDOWN_WRITER_LEVEL_MAX = 0;
23
24
  export var MARKDOWN_READER_LEVEL_HIGH = 1;
@@ -169,6 +170,16 @@ export var MarkdownShortCutService = /*#__PURE__*/function () {
169
170
  (_this$_markdownReader = this._markdownReaders[level][type]) === null || _this$_markdownReader === void 0 || _this$_markdownReader.push(reader);
170
171
  }
171
172
  }
173
+ }, {
174
+ key: "parseMarkdownToLexical",
175
+ value: function parseMarkdownToLexical(markdown) {
176
+ return _parseMarkdownToLexical(markdown, this.markdownReaders);
177
+ }
178
+ }, {
179
+ key: "insertIRootNode",
180
+ value: function insertIRootNode(editor, root, selection) {
181
+ _insertIRootNode(editor, root, selection);
182
+ }
172
183
  }]);
173
184
  return MarkdownShortCutService;
174
185
  }();
@@ -1,4 +1,5 @@
1
1
  import { BaseSelection, LexicalEditor, LexicalNode, TextNode } from 'lexical';
2
+ import { IRootNode } from "../../../editor-kernel/inode";
2
3
  /**
3
4
  * Returns true if the node can contain transformable markdown.
4
5
  * Code nodes cannot contain transformable markdown.
@@ -60,3 +61,4 @@ export declare function $addNodeStyle(node: TextNode): void;
60
61
  * @returns an Array of Lexical Node objects.
61
62
  */
62
63
  export declare function $generateNodesFromSerializedNodes(serializedNodes: Array<BaseSerializedNode>): Array<LexicalNode>;
64
+ export declare function insertIRootNode(editor: LexicalEditor, root: IRootNode, selection: BaseSelection): void;
@@ -6,7 +6,6 @@ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol
6
6
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
7
7
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
8
8
  import { $caretFromPoint, $getCaretRange, $getChildCaret, $getRoot, $isElementNode, $isRangeSelection, $isTextNode, $isTextPointCaret, $parseSerializedNode, SELECTION_INSERT_CLIPBOARD_NODES_COMMAND } from 'lexical';
9
-
10
9
  /**
11
10
  * Returns true if the node can contain transformable markdown.
12
11
  * Code nodes cannot contain transformable markdown.
@@ -217,4 +216,8 @@ export function $generateNodesFromSerializedNodes(serializedNodes) {
217
216
  _iterator4.f();
218
217
  }
219
218
  return nodes;
219
+ }
220
+ export function insertIRootNode(editor, root, selection) {
221
+ var nodes = $generateNodesFromSerializedNodes(root.children);
222
+ $insertGeneratedNodes(editor, nodes, selection);
220
223
  }