@lobehub/editor 1.24.0 → 1.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.
Files changed (77) 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 +2 -0
  7. package/es/index.js +2 -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/index.d.ts +1 -0
  48. package/es/plugins/link/index.js +2 -1
  49. package/es/plugins/link/plugin/index.js +3 -0
  50. package/es/plugins/link/react/ReactLinkPlugin.js +20 -2
  51. package/es/plugins/link/react/components/LinkEdit.js +4 -1
  52. package/es/plugins/link/react/components/LinkToolbar.d.ts +1 -0
  53. package/es/plugins/link/react/components/LinkToolbar.js +8 -2
  54. package/es/plugins/link/service/i-link-service.d.ts +11 -0
  55. package/es/plugins/link/service/i-link-service.js +46 -0
  56. package/es/plugins/markdown/service/shortcut.d.ts +7 -2
  57. package/es/plugins/markdown/service/shortcut.js +12 -1
  58. package/es/plugins/markdown/utils/index.d.ts +2 -0
  59. package/es/plugins/markdown/utils/index.js +4 -1
  60. package/es/plugins/toolbar/index.d.ts +1 -0
  61. package/es/plugins/toolbar/index.js +1 -0
  62. package/es/plugins/toolbar/react/index.d.ts +3 -0
  63. package/es/plugins/toolbar/react/index.js +80 -0
  64. package/es/plugins/toolbar/react/style.d.ts +1 -0
  65. package/es/plugins/toolbar/react/style.js +9 -0
  66. package/es/plugins/toolbar/react/type.d.ts +5 -0
  67. package/es/plugins/toolbar/react/type.js +1 -0
  68. package/es/plugins/toolbar/utils/getDOMRangeRect.d.ts +8 -0
  69. package/es/plugins/toolbar/utils/getDOMRangeRect.js +21 -0
  70. package/es/plugins/toolbar/utils/setFloatingElemPosition.d.ts +1 -0
  71. package/es/plugins/toolbar/utils/setFloatingElemPosition.js +54 -0
  72. package/es/react/ChatInput/style.js +3 -2
  73. package/es/react/Editor/Editor.js +2 -0
  74. package/es/react/Editor/type.d.ts +1 -0
  75. package/es/react/hooks/useEditorState/index.js +41 -33
  76. package/es/types/kernel.d.ts +14 -1
  77. package/package.json +1 -1
@@ -0,0 +1,398 @@
1
+ var _class;
2
+ 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); }
3
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
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); }
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; }
6
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
8
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
9
+ function _get() { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get.bind(); } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(arguments.length < 3 ? target : receiver); } return desc.value; }; } return _get.apply(this, arguments); }
10
+ function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; }
11
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
12
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
13
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
14
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
15
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
16
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
17
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
18
+ 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; }
19
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
20
+ 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); }
21
+ import { $getSelection, $insertNodes, $isRangeSelection, $setSelection, COMMAND_PRIORITY_CRITICAL, COMMAND_PRIORITY_HIGH, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND } from 'lexical';
22
+ import { INodeHelper } from "../../../editor-kernel/inode/helper";
23
+ import { KernelPlugin } from "../../../editor-kernel/plugin";
24
+ import { IMarkdownShortCutService } from "../../markdown";
25
+ import { PlaceholderBlockNode, PlaceholderNode } from "../node/placeholderNode";
26
+ export var AutoCompletePlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
27
+ _inherits(AutoCompletePlugin, _KernelPlugin);
28
+ var _super = _createSuper(AutoCompletePlugin);
29
+ function AutoCompletePlugin(kernel, config) {
30
+ var _config$delay;
31
+ var _this;
32
+ _classCallCheck(this, AutoCompletePlugin);
33
+ _this = _super.call(this);
34
+ _defineProperty(_assertThisInitialized(_this), "lastCursorPosition", null);
35
+ _defineProperty(_assertThisInitialized(_this), "cursorStableTimer", null);
36
+ _defineProperty(_assertThisInitialized(_this), "abortController", null);
37
+ _defineProperty(_assertThisInitialized(_this), "delay", void 0);
38
+ _defineProperty(_assertThisInitialized(_this), "placeholderNodes", []);
39
+ _defineProperty(_assertThisInitialized(_this), "currentSuggestion", null);
40
+ _defineProperty(_assertThisInitialized(_this), "markdownService", null);
41
+ _this.kernel = kernel;
42
+ _this.config = config;
43
+ _this.delay = (_config$delay = config === null || config === void 0 ? void 0 : config.delay) !== null && _config$delay !== void 0 ? _config$delay : 1000;
44
+ kernel.registerNodes([PlaceholderNode, PlaceholderBlockNode]);
45
+ if (config !== null && config !== void 0 && config.theme) {
46
+ kernel.registerThemes(config === null || config === void 0 ? void 0 : config.theme);
47
+ }
48
+ return _this;
49
+ }
50
+ _createClass(AutoCompletePlugin, [{
51
+ key: "onInit",
52
+ value: function onInit(editor) {
53
+ var _this2 = this;
54
+ this.markdownService = this.kernel.requireService(IMarkdownShortCutService);
55
+ if (!this.markdownService) {
56
+ console.error('MarkdownShortCutService is required for AutoCompletePlugin');
57
+ return;
58
+ }
59
+ this.register(editor.registerUpdateListener(function (_ref) {
60
+ var editorState = _ref.editorState;
61
+ editorState.read(function () {
62
+ if (editor.isComposing()) {
63
+ return;
64
+ }
65
+ var selection = $getSelection();
66
+ if (!$isRangeSelection(selection) || !selection.isCollapsed()) {
67
+ _this2.clearTimer();
68
+ _this2.clearPlaceholderNodes(editor);
69
+ return;
70
+ }
71
+ var currentPosition = {
72
+ key: selection.anchor.key,
73
+ offset: selection.anchor.offset,
74
+ type: selection.anchor.type
75
+ };
76
+
77
+ // Check if cursor position has changed
78
+ if (_this2.hasPositionChanged(currentPosition)) {
79
+ _this2.clearTimer();
80
+ _this2.clearPlaceholderNodes(editor);
81
+ _this2.abortController = new AbortController();
82
+ // Start new timer for cursor stability check
83
+ _this2.cursorStableTimer = window.setTimeout(function () {
84
+ _this2.handleCursorStable(editor, currentPosition);
85
+ }, _this2.delay);
86
+ }
87
+ });
88
+ }));
89
+
90
+ // Register Tab key handler to apply suggestion
91
+ this.register(editor.registerCommand(KEY_TAB_COMMAND, function (event) {
92
+ if (_this2.currentSuggestion) {
93
+ event === null || event === void 0 || event.preventDefault();
94
+ _this2.applySuggestion(editor);
95
+ return true;
96
+ }
97
+ return false;
98
+ }, COMMAND_PRIORITY_HIGH));
99
+ this.register(editor.registerCommand(KEY_ESCAPE_COMMAND, function (event) {
100
+ if (_this2.currentSuggestion) {
101
+ event === null || event === void 0 || event.preventDefault();
102
+ _this2.clearPlaceholderNodes(editor);
103
+ _this2.currentSuggestion = null;
104
+ return true;
105
+ }
106
+ return false;
107
+ }, COMMAND_PRIORITY_CRITICAL));
108
+
109
+ // Register text content listener to clear placeholder on any other input
110
+ this.register(editor.registerTextContentListener(function () {
111
+ // If user types anything while placeholder is visible, clear it
112
+ if (_this2.placeholderNodes.length > 0) {
113
+ _this2.clearPlaceholderNodes(editor);
114
+ }
115
+ }));
116
+ }
117
+ }, {
118
+ key: "hasPositionChanged",
119
+ value: function hasPositionChanged(currentPosition) {
120
+ if (!this.lastCursorPosition) {
121
+ return true;
122
+ }
123
+ return this.lastCursorPosition.key !== currentPosition.key || this.lastCursorPosition.offset !== currentPosition.offset || this.lastCursorPosition.type !== currentPosition.type;
124
+ }
125
+ }, {
126
+ key: "clearTimer",
127
+ value: function clearTimer() {
128
+ var _this$abortController;
129
+ (_this$abortController = this.abortController) === null || _this$abortController === void 0 || _this$abortController.abort('use cancel');
130
+ if (this.cursorStableTimer) {
131
+ clearTimeout(this.cursorStableTimer);
132
+ this.cursorStableTimer = null;
133
+ }
134
+ }
135
+ }, {
136
+ key: "handleCursorStable",
137
+ value: function handleCursorStable(editor, position) {
138
+ var _this3 = this;
139
+ editor.read(function () {
140
+ var _this3$config;
141
+ if (editor.isComposing()) {
142
+ return;
143
+ }
144
+ if (!_this3.abortController || _this3.abortController.signal.aborted) {
145
+ return;
146
+ }
147
+ var selection = $getSelection();
148
+ if (!$isRangeSelection(selection) || !selection.isCollapsed()) {
149
+ return;
150
+ }
151
+
152
+ // Verify cursor is still at the same position
153
+ var currentPosition = {
154
+ key: selection.anchor.key,
155
+ offset: selection.anchor.offset,
156
+ type: selection.anchor.type
157
+ };
158
+ if (!_this3.isSamePosition(position, currentPosition)) {
159
+ return;
160
+ }
161
+
162
+ // Avoid duplicate triggers for the same position
163
+ if (_this3.lastCursorPosition && _this3.isSamePosition(position, _this3.lastCursorPosition)) {
164
+ return;
165
+ }
166
+ _this3.lastCursorPosition = currentPosition;
167
+
168
+ // Get context around cursor for auto-complete
169
+ var anchorNode = selection.anchor.getNode();
170
+ var selectionType = 'unknown';
171
+
172
+ // Get text before cursor in the entire paragraph
173
+ var textRet = _this3.getTextBeforeCursor(selection);
174
+ selectionType = anchorNode.getType();
175
+
176
+ // Trigger auto-complete callback if provided
177
+ if ((_this3$config = _this3.config) !== null && _this3$config !== void 0 && _this3$config.onAutoComplete) {
178
+ _this3.config.onAutoComplete({
179
+ abortSignal: _this3.abortController.signal,
180
+ afterText: textRet.textAfter,
181
+ editor: _this3.kernel,
182
+ input: textRet.textBefore,
183
+ selectionType: selectionType
184
+ }).then(function (result) {
185
+ if (result) {
186
+ // Store suggestion and show placeholder
187
+ _this3.currentSuggestion = result;
188
+ _this3.showPlaceholderNodes(editor, result);
189
+ console.log('Auto-complete triggered:', {
190
+ afterText: textRet.textAfter,
191
+ input: textRet.textBefore,
192
+ position: currentPosition,
193
+ result: result,
194
+ selectionType: selectionType
195
+ });
196
+ } else {
197
+ _this3.clearPlaceholderNodes(editor);
198
+ }
199
+ });
200
+ }
201
+ });
202
+ }
203
+ }, {
204
+ key: "getTextBeforeCursor",
205
+ value: function getTextBeforeCursor(selection) {
206
+ var ret = {
207
+ textAfter: '',
208
+ textBefore: ''
209
+ };
210
+ var anchorNode = selection.anchor.getNode();
211
+ var anchorOffset = selection.anchor.offset;
212
+
213
+ // Find the paragraph or root container
214
+ var paragraphNode = anchorNode;
215
+ while (paragraphNode && paragraphNode.isInline()) {
216
+ var parent = paragraphNode.getParent();
217
+ if (!parent) break;
218
+ paragraphNode = parent;
219
+ }
220
+ if (!paragraphNode) {
221
+ return ret;
222
+ }
223
+ console.info('Paragraph Node Type:', paragraphNode, anchorNode);
224
+ var founded = false;
225
+
226
+ // Collect all text before cursor in the paragraph
227
+ var collectTextBeforeCursor = function collectTextBeforeCursor(node, targetNode, targetOffset) {
228
+ if (node === targetNode) {
229
+ founded = true;
230
+ // We've reached the target node, get text up to the cursor position
231
+ if (node.getTextContent) {
232
+ var nodeText = node.getTextContent();
233
+ return {
234
+ text: nodeText.slice(0, targetOffset),
235
+ textAfter: nodeText.slice(targetOffset)
236
+ };
237
+ }
238
+ return {
239
+ text: '',
240
+ textAfter: ''
241
+ };
242
+ }
243
+ var collectedText = '';
244
+ var collectedTextAfter = '';
245
+
246
+ // If this is a text node, collect all its text
247
+ if (node.getTextContent && node.getType() === 'text') {
248
+ if (founded) {
249
+ collectedTextAfter += node.getTextContent();
250
+ } else {
251
+ collectedText += node.getTextContent();
252
+ }
253
+ }
254
+
255
+ // Recursively check children
256
+ if (node.getChildren) {
257
+ var children = node.getChildren();
258
+ var _iterator = _createForOfIteratorHelper(children),
259
+ _step;
260
+ try {
261
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
262
+ var child = _step.value;
263
+ var _result = collectTextBeforeCursor(child, targetNode, targetOffset);
264
+ collectedTextAfter += _result.textAfter;
265
+ collectedText += _result.text;
266
+ }
267
+ } catch (err) {
268
+ _iterator.e(err);
269
+ } finally {
270
+ _iterator.f();
271
+ }
272
+ }
273
+ return {
274
+ text: collectedText,
275
+ textAfter: collectedTextAfter
276
+ };
277
+ };
278
+ var result = collectTextBeforeCursor(paragraphNode, anchorNode, anchorOffset);
279
+ return {
280
+ textAfter: result.textAfter,
281
+ textBefore: result.text
282
+ };
283
+ }
284
+ }, {
285
+ key: "showPlaceholderNodes",
286
+ value: function showPlaceholderNodes(editor, suggestion) {
287
+ var _this4 = this;
288
+ // this.clearPlaceholderNodes(editor); // Remove existing placeholder first
289
+
290
+ editor.update(function () {
291
+ var selection = $getSelection();
292
+ if (!$isRangeSelection(selection) || !selection.isCollapsed()) {
293
+ console.warn('No valid selection for placeholder');
294
+ return;
295
+ }
296
+ if (!_this4.markdownService) {
297
+ console.warn('No valid markdown service for placeholder');
298
+ return;
299
+ }
300
+ var nodes = _this4.markdownService.parseMarkdownToLexical(suggestion);
301
+ if (nodes.children[0]) {
302
+ var firstChild = nodes.children[0];
303
+ // Do something with the first child node
304
+ // @ts-expect-error not error
305
+ var oldChildren = firstChild.children;
306
+ // @ts-expect-error not error
307
+ firstChild.children = [{
308
+ children: oldChildren,
309
+ type: 'PlaceholderInline'
310
+ }];
311
+ }
312
+ for (var i = 1; i < nodes.children.length; i++) {
313
+ var child = nodes.children[i];
314
+ nodes.children[i] = {
315
+ // @ts-expect-error not error
316
+ children: [child],
317
+ type: 'PlaceholderBlock'
318
+ };
319
+ }
320
+
321
+ // 创建标记节点并保存其key
322
+ var markerNode = INodeHelper.createTextNode("\u200B"); // 使用零宽空格
323
+ nodes.children.push({
324
+ // @ts-expect-error not error
325
+ children: [markerNode],
326
+ name: '',
327
+ type: 'PlaceholderInline'
328
+ });
329
+ var saveSel = selection.clone();
330
+ _this4.markdownService.insertIRootNode(editor, nodes, selection);
331
+ $setSelection(saveSel);
332
+ });
333
+ }
334
+ }, {
335
+ key: "clearPlaceholderNodes",
336
+ value: function clearPlaceholderNodes(editor) {
337
+ editor.update(function () {
338
+ editor.getEditorState()._nodeMap.forEach(function (node) {
339
+ var selection = $getSelection();
340
+ var clonedSelection = selection ? selection.clone() : null;
341
+ if (node.isAttached() && ['PlaceholderBlock', 'PlaceholderInline'].includes(node.getType())) {
342
+ if (node.getType() === 'PlaceholderInline' && node.getTextContent().includes("\u200B") && node.getPreviousSibling() === null) {
343
+ var _node$getParent;
344
+ while (node.getNextSibling()) {
345
+ var next = node.getNextSibling();
346
+ if (next) {
347
+ $insertNodes([next]);
348
+ }
349
+ }
350
+ $setSelection(clonedSelection);
351
+ (_node$getParent = node.getParent()) === null || _node$getParent === void 0 || _node$getParent.remove();
352
+ return;
353
+ }
354
+ node.remove();
355
+ }
356
+ });
357
+ });
358
+ }
359
+ }, {
360
+ key: "applySuggestion",
361
+ value: function applySuggestion(editor) {
362
+ var _this5 = this;
363
+ if (!this.currentSuggestion) {
364
+ return;
365
+ }
366
+ var markdown = this.currentSuggestion;
367
+ editor.update(function () {
368
+ var selection = $getSelection();
369
+ if (!$isRangeSelection(selection) || !selection.isCollapsed() || !_this5.markdownService) {
370
+ return;
371
+ }
372
+ editor.getEditorState()._nodeMap.forEach(function (node) {
373
+ if (node.isAttached() && ['PlaceholderBlock', 'PlaceholderInline'].includes(node.getType())) {
374
+ node.remove();
375
+ }
376
+ });
377
+ var nodes = _this5.markdownService.parseMarkdownToLexical(markdown);
378
+ _this5.markdownService.insertIRootNode(editor, nodes, selection);
379
+ _this5.clearPlaceholderNodes(editor);
380
+ _this5.currentSuggestion = null;
381
+ });
382
+ }
383
+ }, {
384
+ key: "isSamePosition",
385
+ value: function isSamePosition(pos1, pos2) {
386
+ return pos1.key === pos2.key && pos1.offset === pos2.offset && pos1.type === pos2.type;
387
+ }
388
+ }, {
389
+ key: "destroy",
390
+ value: function destroy() {
391
+ this.clearTimer();
392
+ // Note: clearPlaceholderNodes needs editor instance, so it should be called before destroy
393
+ this.placeholderNodes = []; // Clear references
394
+ _get(_getPrototypeOf(AutoCompletePlugin.prototype), "destroy", this).call(this);
395
+ }
396
+ }]);
397
+ return AutoCompletePlugin;
398
+ }(KernelPlugin), _defineProperty(_class, "pluginName", 'AutoCompletePlugin'), _class);
@@ -0,0 +1,4 @@
1
+ import { type FC } from 'react';
2
+ import { ReactAutoCompletePluginProps } from './type';
3
+ declare const ReactAutoCompletePlugin: FC<ReactAutoCompletePluginProps>;
4
+ export default ReactAutoCompletePlugin;
@@ -0,0 +1,35 @@
1
+ 'use client';
2
+
3
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
4
+ 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."); }
5
+ 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); }
6
+ 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; }
7
+ 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; } }
8
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
9
+ import { useLayoutEffect } from 'react';
10
+ import { useLexicalComposerContext } from "../../../editor-kernel/react/react-context";
11
+ import { AutoCompletePlugin } from "../plugin";
12
+ import { useStyles } from "./style";
13
+ var ReactAutoCompletePlugin = function ReactAutoCompletePlugin(_ref) {
14
+ var onAutoComplete = _ref.onAutoComplete,
15
+ delay = _ref.delay;
16
+ var _useLexicalComposerCo = useLexicalComposerContext(),
17
+ _useLexicalComposerCo2 = _slicedToArray(_useLexicalComposerCo, 1),
18
+ editor = _useLexicalComposerCo2[0];
19
+ var _useStyles = useStyles(),
20
+ cx = _useStyles.cx,
21
+ styles = _useStyles.styles;
22
+ useLayoutEffect(function () {
23
+ editor.registerPlugin(AutoCompletePlugin, {
24
+ delay: delay,
25
+ onAutoComplete: onAutoComplete,
26
+ theme: {
27
+ placeholderBlock: cx(styles.placeholderBlock),
28
+ placeholderInline: cx(styles.placeholderInline)
29
+ }
30
+ });
31
+ }, []);
32
+ return null;
33
+ };
34
+ ReactAutoCompletePlugin.displayName = 'ReactAutoCompletePlugin';
35
+ export default ReactAutoCompletePlugin;
@@ -0,0 +1 @@
1
+ export { default as ReactAutoCompletePlugin } from './ReactAutoCompletePlugin';
@@ -0,0 +1 @@
1
+ export { default as ReactAutoCompletePlugin } from "./ReactAutoCompletePlugin";
@@ -0,0 +1,4 @@
1
+ export declare const useStyles: (props?: unknown) => import("antd-style").ReturnStyles<{
2
+ placeholderBlock: import("antd-style").SerializedStyles;
3
+ placeholderInline: import("antd-style").SerializedStyles;
4
+ }>;
@@ -0,0 +1,10 @@
1
+ var _templateObject, _templateObject2;
2
+ function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
3
+ import { createStyles } from 'antd-style';
4
+ export var useStyles = createStyles(function (_ref) {
5
+ var css = _ref.css;
6
+ return {
7
+ placeholderBlock: css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n opacity: 0.4;\n "]))),
8
+ placeholderInline: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n opacity: 0.4;\n "])))
9
+ };
10
+ });
@@ -0,0 +1,11 @@
1
+ import { IEditor } from "../../../types";
2
+ export interface ReactAutoCompletePluginProps {
3
+ delay?: number;
4
+ onAutoComplete?: (opt: {
5
+ abortSignal: AbortSignal;
6
+ afterText: string;
7
+ editor: IEditor;
8
+ input: string;
9
+ selectionType: string;
10
+ }) => Promise<string | null>;
11
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -332,7 +332,6 @@ export var CommonPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
332
332
  // editor.read(() => {
333
333
  var selection = $getSelection();
334
334
  if (!$isRangeSelection(selection)) {
335
- console.info('---------?');
336
335
  return false;
337
336
  }
338
337
 
@@ -331,6 +331,9 @@ export function registerLastElement(editor) {
331
331
  var isProcessing = false;
332
332
  return editor.registerUpdateListener(function (_ref3) {
333
333
  var dirtyElements = _ref3.dirtyElements;
334
+ if (!editor.isEditable()) {
335
+ return;
336
+ }
334
337
  // Only process when root node or its direct children have changes
335
338
  if (!dirtyElements.has('root') && !Array.from(dirtyElements.keys()).some(function (key) {
336
339
  var _node$getParent;
@@ -32,6 +32,7 @@ var ReactPlainText = /*#__PURE__*/memo(function (_ref) {
32
32
  _ref$theme = _ref.theme,
33
33
  theme = _ref$theme === void 0 ? {} : _ref$theme,
34
34
  onChange = _ref.onChange,
35
+ editable = _ref.editable,
35
36
  className = _ref.className,
36
37
  variant = _ref.variant,
37
38
  _ref$enableHotkey = _ref.enableHotkey,
@@ -99,7 +100,7 @@ var ReactPlainText = /*#__PURE__*/memo(function (_ref) {
99
100
  var container = editorContainerRef.current;
100
101
  if (container && !isInitialized) {
101
102
  // Initialize the editor
102
- editor.setRootElement(container);
103
+ editor.setRootElement(container, editable);
103
104
 
104
105
  // Set initial document content only once
105
106
  editor.setDocument(type, content);
@@ -128,6 +129,12 @@ var ReactPlainText = /*#__PURE__*/memo(function (_ref) {
128
129
  }
129
130
  });
130
131
  }, [editor, type, content, onChange, onTextChange, isInitialized]);
132
+ useEffect(function () {
133
+ if (!isInitialized) return;
134
+ if (typeof editable === 'boolean') {
135
+ editor.setEditable(editable);
136
+ }
137
+ }, [isInitialized, editable]);
131
138
  useEffect(function () {
132
139
  if (editor && onPressEnter) {
133
140
  return editor.registerHighCommand(KEY_DOWN_COMMAND, function (event) {
@@ -190,7 +197,7 @@ var ReactPlainText = /*#__PURE__*/memo(function (_ref) {
190
197
  className: cx(styles.root, markdownOption === true && styles.variant, markdownOption === false && styles.noStyle, markdownOption === false && styles.noHeader, _typeof(markdownOption) === 'object' && markdownOption.header === true && styles.header, _typeof(markdownOption) === 'object' && markdownOption.header === false && styles.noHeader, _typeof(markdownOption) === 'object' && markdownOption.code === true && styles.code, _typeof(markdownOption) === 'object' && markdownOption.quote === true && styles.blockquote, className),
191
198
  style: style,
192
199
  children: [/*#__PURE__*/_jsx("div", {
193
- contentEditable: true,
200
+ contentEditable: editable !== null && editable !== void 0 ? editable : true,
194
201
  onBlur: handleBlur,
195
202
  onCompositionEnd: handleCompositionEnd,
196
203
  onCompositionStart: handleCompositionStart,
@@ -28,7 +28,7 @@ export var useStyles = createStyles(function (_ref2, _ref3) {
28
28
  marginMultiple = _ref3$marginMultiple === void 0 ? 2 : _ref3$marginMultiple,
29
29
  _ref3$lineHeight = _ref3.lineHeight,
30
30
  lineHeight = _ref3$lineHeight === void 0 ? 1.8 : _ref3$lineHeight;
31
- var __root = css(_templateObject11 || (_templateObject11 = _taggedTemplateLiteral(["\n --lobe-markdown-font-size: ", "px;\n --lobe-markdown-header-multiple: ", ";\n --lobe-markdown-margin-multiple: ", ";\n --lobe-markdown-line-height: ", ";\n --lobe-markdown-border-radius: ", ";\n --lobe-markdown-border-color: ", ";\n\n position: relative;\n\n display: flex;\n flex-direction: column;\n\n width: 100%;\n max-width: 100%;\n height: 100%;\n\n font-size: var(--lobe-markdown-font-size);\n line-height: var(--lobe-markdown-line-height);\n word-break: break-word;\n\n @keyframes cursor-blink {\n to {\n visibility: hidden;\n }\n }\n\n [data-placeholder] {\n position: relative;\n }\n\n [data-placeholder]::after {\n pointer-events: none;\n content: attr(data-placeholder);\n user-select: none;\n user-select: none;\n user-select: none;\n\n position: absolute;\n inset-block-start: 50%;\n transform: translateY(-50%);\n\n padding-inline-start: 2px;\n\n color: ", ";\n white-space: nowrap;\n }\n\n [data-lexical-cursor='true'] {\n pointer-events: none;\n position: absolute;\n display: block;\n\n &::after {\n content: '';\n\n position: absolute;\n inset-block-start: -2px;\n\n display: block;\n\n width: 20px;\n border-block-start: 1px solid ", ";\n\n animation: cursor-blink 1.1s steps(2, start) infinite;\n }\n }\n "])), fontSize, headerMultiple, marginMultiple, lineHeight, token.borderRadiusLG, token.colorFillQuaternary, token.colorTextDescription, token.colorText);
31
+ var __root = css(_templateObject11 || (_templateObject11 = _taggedTemplateLiteral(["\n --lobe-markdown-font-size: ", "px;\n --lobe-markdown-header-multiple: ", ";\n --lobe-markdown-margin-multiple: ", ";\n --lobe-markdown-line-height: ", ";\n --lobe-markdown-border-radius: ", ";\n --lobe-markdown-border-color: ", ";\n\n position: relative;\n\n display: flex;\n flex-direction: column;\n\n width: 100%;\n max-width: 100%;\n height: 100%;\n\n font-size: var(--lobe-markdown-font-size);\n line-height: var(--lobe-markdown-line-height);\n word-break: break-word;\n\n @keyframes cursor-blink {\n to {\n visibility: hidden;\n }\n }\n\n [data-placeholder] {\n position: relative;\n }\n\n [data-placeholder]::after {\n pointer-events: none;\n content: attr(data-placeholder);\n user-select: none;\n\n position: absolute;\n inset-block-start: 50%;\n transform: translateY(-50%);\n\n padding-inline-start: 2px;\n\n color: ", ";\n white-space: nowrap;\n }\n\n [data-lexical-cursor='true'] {\n pointer-events: none;\n position: absolute;\n display: block;\n\n &::after {\n content: '';\n\n position: absolute;\n inset-block-start: -2px;\n\n display: block;\n\n width: 20px;\n border-block-start: 1px solid ", ";\n\n animation: cursor-blink 1.1s steps(2, start) infinite;\n }\n }\n "])), fontSize, headerMultiple, marginMultiple, lineHeight, token.borderRadiusLG, token.colorFillQuaternary, token.colorTextDescription, token.colorText);
32
32
  var header = css(_templateObject12 || (_templateObject12 = _taggedTemplateLiteral(["\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n margin-block: max(\n calc(var(--lobe-markdown-header-multiple) * var(--lobe-markdown-margin-multiple) * 0.4em),\n var(--lobe-markdown-font-size)\n );\n font-weight: bold;\n line-height: 1.25;\n }\n\n h1 {\n font-size: calc(\n var(--lobe-markdown-font-size) * (1 + 1.5 * var(--lobe-markdown-header-multiple))\n );\n }\n\n h2 {\n font-size: calc(\n var(--lobe-markdown-font-size) * (1 + var(--lobe-markdown-header-multiple))\n );\n }\n\n h3 {\n font-size: calc(\n var(--lobe-markdown-font-size) * (1 + 0.5 * var(--lobe-markdown-header-multiple))\n );\n }\n\n h4 {\n font-size: calc(\n var(--lobe-markdown-font-size) * (1 + 0.25 * var(--lobe-markdown-header-multiple))\n );\n }\n\n h5,\n h6 {\n font-size: calc(var(--lobe-markdown-font-size) * 1);\n }\n "])));
33
33
  var p = css(_templateObject13 || (_templateObject13 = _taggedTemplateLiteral(["\n p {\n margin-block: 4px;\n line-height: var(--lobe-markdown-line-height);\n letter-spacing: 0.02em;\n\n &:not(:first-child) {\n margin-block-start: calc(var(--lobe-markdown-margin-multiple) * 0.5em);\n }\n\n &:not(:last-child) {\n margin-block-end: calc(var(--lobe-markdown-margin-multiple) * 0.5em);\n }\n }\n "])));
34
34
  var blockquote = css(_templateObject14 || (_templateObject14 = _taggedTemplateLiteral(["\n .editor_quote {\n margin-block: calc(var(--lobe-markdown-margin-multiple) * 0.5em);\n margin-inline: 0;\n padding-block: 0;\n padding-inline: 1em;\n border-inline-start: solid 4px ", ";\n\n color: ", ";\n }\n "])), token.colorBorder, token.colorTextSecondary);
@@ -11,6 +11,7 @@ export interface ReactPlainTextProps {
11
11
  autoFocus?: boolean;
12
12
  children: ReactElement<ReactEditorContentProps>;
13
13
  className?: string;
14
+ editable?: boolean;
14
15
  enableHotkey?: boolean;
15
16
  /**
16
17
  * Enable automatic markdown formatting for pasted content
@@ -1,6 +1,8 @@
1
1
  import { LexicalEditor } from 'lexical';
2
2
  export declare const INSERT_IMAGE_COMMAND: import("lexical").LexicalCommand<{
3
+ block?: boolean | undefined;
3
4
  file: File;
5
+ maxWidth?: number | undefined;
4
6
  range?: Range | null | undefined;
5
7
  }>;
6
8
  export declare function registerImageCommand(editor: LexicalEditor, handleUpload: (file: File) => Promise<{
@@ -1,6 +1,7 @@
1
1
  import { $wrapNodeInElement } from '@lexical/utils';
2
2
  import { $createParagraphNode, $createRangeSelection, $insertNodes, $isRootOrShadowRoot, $setSelection, COMMAND_PRIORITY_EDITOR, createCommand } from 'lexical';
3
3
  import { createDebugLogger } from "../../../utils/debug";
4
+ import { $createBlockImageNode } from "../node/block-image-node";
4
5
  import { $createImageNode } from "../node/image-node";
5
6
  var logger = createDebugLogger('plugin', 'image');
6
7
  export var INSERT_IMAGE_COMMAND = createCommand('INSERT_IMAGE_COMMAND');
@@ -10,7 +11,9 @@ function isImageFile(file) {
10
11
  export function registerImageCommand(editor, handleUpload) {
11
12
  return editor.registerCommand(INSERT_IMAGE_COMMAND, function (payload) {
12
13
  var file = payload.file,
13
- range = payload.range;
14
+ range = payload.range,
15
+ block = payload.block,
16
+ maxWidth = payload.maxWidth;
14
17
  if (!isImageFile(file)) {
15
18
  return false; // Not an image file
16
19
  }
@@ -23,8 +26,13 @@ export function registerImageCommand(editor, handleUpload) {
23
26
  }
24
27
  $setSelection(rangeSelection);
25
28
  }
26
- var imageNode = $createImageNode({
29
+ var imageNode = block ? $createBlockImageNode({
27
30
  altText: file.name,
31
+ maxWidth: maxWidth || 800,
32
+ src: placeholderURL
33
+ }) : $createImageNode({
34
+ altText: file.name,
35
+ maxWidth: maxWidth || 800,
28
36
  src: placeholderURL
29
37
  });
30
38
  $insertNodes([imageNode]); // Insert a zero-width space to ensure the image is not the last child
@@ -37,6 +37,7 @@ export declare class BaseImageNode extends DecoratorNode<any> {
37
37
  exportJSON(): SerializedImageNode;
38
38
  setWidthAndHeight(width: 'inherit' | number, height: 'inherit' | number): void;
39
39
  setShowCaption(showCaption: boolean): void;
40
+ isInline(): boolean;
40
41
  createDOM(config: EditorConfig): HTMLElement;
41
42
  updateDOM(): false;
42
43
  getSrc(): string;
@@ -96,6 +96,11 @@ export var BaseImageNode = /*#__PURE__*/function (_DecoratorNode) {
96
96
  var writable = this.getWritable();
97
97
  writable.__showCaption = showCaption;
98
98
  }
99
+ }, {
100
+ key: "isInline",
101
+ value: function isInline() {
102
+ return true;
103
+ }
99
104
 
100
105
  // View
101
106
  }, {