@lobehub/editor 1.8.5 → 1.9.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.
@@ -23,3 +23,10 @@ export declare function isDocumentFragment(x: unknown): x is DocumentFragment;
23
23
  export declare function getParentElement(node: Node): HTMLElement | null;
24
24
  export declare function $getNearestNodeFromDOMNode(startingDOM: Node, editor: LexicalEditor, editorState?: ReturnType<LexicalEditor['getEditorState']>): LexicalNode | null;
25
25
  export declare function getKernelFromEditor(editor: LexicalEditor): IEditorKernel;
26
+ /**
27
+ *
28
+ * @param nodeA
29
+ * @param nodeB
30
+ * @returns
31
+ */
32
+ export declare function compareNodeOrder(nodeA: LexicalNode, nodeB: LexicalNode): number;
@@ -68,4 +68,44 @@ export function getKernelFromEditor(editor) {
68
68
  var _editor$_createEditor;
69
69
  // @ts-expect-error __kernel is injected into the lexical editor instance
70
70
  return ((_editor$_createEditor = editor._createEditorArgs) === null || _editor$_createEditor === void 0 ? void 0 : _editor$_createEditor.__kernel) || editor._kernel;
71
+ }
72
+
73
+ /**
74
+ *
75
+ * @param nodeA
76
+ * @param nodeB
77
+ * @returns
78
+ */
79
+ export function compareNodeOrder(nodeA, nodeB) {
80
+ if (nodeA === nodeB) {
81
+ return 0;
82
+ }
83
+ var pathA = [];
84
+ var pathB = [];
85
+ var currentA = nodeA;
86
+ var currentB = nodeB;
87
+ while (currentA) {
88
+ pathA.unshift(currentA);
89
+ currentA = currentA.getParent();
90
+ }
91
+ while (currentB) {
92
+ pathB.unshift(currentB);
93
+ currentB = currentB.getParent();
94
+ }
95
+ var minLength = Math.min(pathA.length, pathB.length);
96
+ for (var i = 0; i < minLength; i++) {
97
+ if (pathA[i] !== pathB[i]) {
98
+ var _pathA$i$getParent;
99
+ var siblings = ((_pathA$i$getParent = pathA[i].getParent()) === null || _pathA$i$getParent === void 0 ? void 0 : _pathA$i$getParent.getChildren()) || [];
100
+ return siblings.indexOf(pathA[i]) - siblings.indexOf(pathB[i]);
101
+ }
102
+ }
103
+
104
+ // If all nodes in the shorter path are the same, the shorter path's node comes first
105
+ if (pathA.length !== pathB.length) {
106
+ return pathA.length - pathB.length;
107
+ }
108
+
109
+ // This case should not happen as we checked for equality at the start
110
+ return 0;
71
111
  }
@@ -202,7 +202,7 @@ export function registerRichKeydown(editor, kernel, options) {
202
202
  });
203
203
  event.preventDefault();
204
204
  return true;
205
- } else if (possibleNode) {
205
+ } else if (possibleNode && possibleNode.getType() !== 'linebreak') {
206
206
  possibleNode === null || possibleNode === void 0 || possibleNode.selectEnd();
207
207
  event.preventDefault();
208
208
  return true;
@@ -254,7 +254,7 @@ export function registerRichKeydown(editor, kernel, options) {
254
254
  });
255
255
  event.preventDefault();
256
256
  return true;
257
- } else if (possibleNode) {
257
+ } else if (possibleNode && possibleNode.getType() !== 'linebreak') {
258
258
  possibleNode === null || possibleNode === void 0 || possibleNode.selectStart();
259
259
  event.preventDefault();
260
260
  return true;
@@ -170,6 +170,8 @@ var ReactPlainText = /*#__PURE__*/memo(function (_ref) {
170
170
  onFocus: handleFocus,
171
171
  ref: editorContainerRef,
172
172
  style: {
173
+ flex: 1,
174
+ minHeight: 0,
173
175
  outline: 'none'
174
176
  }
175
177
  }), /*#__PURE__*/_jsx(Placeholder, {
@@ -26,7 +26,7 @@ export var useStyles = createStyles(function (_ref2, _ref3) {
26
26
  marginMultiple = _ref3$marginMultiple === void 0 ? 2 : _ref3$marginMultiple,
27
27
  _ref3$lineHeight = _ref3.lineHeight,
28
28
  lineHeight = _ref3$lineHeight === void 0 ? 1.8 : _ref3$lineHeight;
29
- var __root = css(_templateObject6 || (_templateObject6 = _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 width: 100%;\n max-width: 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-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.colorText);
29
+ var __root = css(_templateObject6 || (_templateObject6 = _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-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.colorText);
30
30
  var header = css(_templateObject7 || (_templateObject7 = _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 "])));
31
31
  var p = css(_templateObject8 || (_templateObject8 = _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 "])));
32
32
  var blockquote = css(_templateObject9 || (_templateObject9 = _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);
@@ -5,10 +5,11 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
5
5
  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
6
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
7
  import { mergeRegister } from '@lexical/utils';
8
- import { $getSelection, $isElementNode, $isNodeSelection, $isRangeSelection, $isTextNode } from 'lexical';
8
+ import { $getNodeByKey, $getSelection, $isNodeSelection, $isRangeSelection } from 'lexical';
9
9
  import { memo, useCallback, useEffect, useRef, useState } from 'react';
10
10
  import { useLexicalComposerContext, useLexicalEditor } from "../../../../editor-kernel/react";
11
11
  import PortalAnchor from "../../../../editor-kernel/react/PortalAnchor";
12
+ import { compareNodeOrder } from "../../../../editor-kernel/utils";
12
13
  import { SELECT_MATH_SIDE_COMMAND, UPDATE_MATH_COMMAND } from "../../command";
13
14
  import { $isMathNode, MathBlockNode } from "../../node";
14
15
  import MathEditorContainer from "./MathEditorContainer";
@@ -64,8 +65,10 @@ var MathEdit = /*#__PURE__*/memo(function (_ref) {
64
65
  return lexicalEditor.getElementByKey(mathNode.getKey());
65
66
  });
66
67
  if (currentNode) {
67
- var writableNode = mathNode.getWritable();
68
- writableNode.__code = value;
68
+ lexicalEditor.update(function () {
69
+ var writableNode = mathNode.getWritable();
70
+ writableNode.__code = value;
71
+ });
69
72
  }
70
73
  return;
71
74
  }
@@ -81,8 +84,8 @@ var MathEdit = /*#__PURE__*/memo(function (_ref) {
81
84
  return lexicalEditor.getElementByKey(mathNode.getKey());
82
85
  });
83
86
  if (currentNode) {
84
- var _writableNode = mathNode.getWritable();
85
- _writableNode.__code = value;
87
+ var writableNode = mathNode.getWritable();
88
+ writableNode.__code = value;
86
89
  }
87
90
  });
88
91
  // 延迟重置更新标志,确保更新监听器不会立即触发
@@ -204,25 +207,23 @@ var MathEdit = /*#__PURE__*/memo(function (_ref) {
204
207
  return node;
205
208
  });
206
209
  if (canEdit) {
207
- var node = prevEditorState.read(function () {
210
+ var anchorNodeKey = prevEditorState.read(function () {
208
211
  var sel = prevEditorState._selection;
209
- if (!$isRangeSelection(sel) || !sel.isCollapsed()) {
212
+ if (!$isRangeSelection(sel)) {
210
213
  return false;
211
214
  }
212
- var node = sel.anchor.getNode();
213
- if ($isTextNode(node)) {
214
- return node.getNextSibling();
215
- }
216
- if (!$isElementNode(node)) {
217
- return false;
215
+ var node = sel.anchor.key;
216
+ return node;
217
+ });
218
+ editor.read(function () {
219
+ var anchorNode = anchorNodeKey ? $getNodeByKey(anchorNodeKey) : null;
220
+ var isPrev = anchorNode && compareNodeOrder(anchorNode, canEdit) < 0;
221
+ if (isPrev) {
222
+ setPrev(true);
223
+ } else {
224
+ setPrev(false);
218
225
  }
219
- return node.getChildAtIndex(sel.anchor.offset);
220
226
  });
221
- if (canEdit === node) {
222
- setPrev(true);
223
- } else {
224
- setPrev(false);
225
- }
226
227
  setIsOpen(true);
227
228
  }
228
229
  if (!canEdit) {
@@ -252,8 +253,9 @@ var MathEdit = /*#__PURE__*/memo(function (_ref) {
252
253
  lastValidRef.current = value;
253
254
  }
254
255
  },
255
- onValueChange: setValue,
256
- prev: prev,
256
+ onValueChange: setValue
257
+ // prev={prev}
258
+ ,
257
259
  value: value
258
260
  });
259
261
 
@@ -16,6 +16,8 @@ var MathEditorContainer = /*#__PURE__*/memo(function (_ref) {
16
16
  return updatePosition({
17
17
  callback: function callback() {
18
18
  if (!divRef.current || !mathDOM) return;
19
+ // 展示的时候聚焦
20
+ onFocus === null || onFocus === void 0 || onFocus();
19
21
  if (!isBlockMode) {
20
22
  divRef.current.style.width = '';
21
23
  return;
@@ -21,7 +21,6 @@ export interface MathEditorContentProps {
21
21
  /** 值变化回调 */
22
22
  onValueChange: (value: string) => void;
23
23
  /** 是否从前一个位置进入 */
24
- prev: boolean;
25
24
  /** 当前输入值 */
26
25
  value: string;
27
26
  }
@@ -25,7 +25,6 @@ var MathEditorContent = /*#__PURE__*/memo(function (_ref) {
25
25
  onSubmit = _ref.onSubmit,
26
26
  onValidationChange = _ref.onValidationChange,
27
27
  onValueChange = _ref.onValueChange,
28
- prev = _ref.prev,
29
28
  value = _ref.value;
30
29
  var t = useTranslation();
31
30
  var textareaRef = useRef(null);
@@ -41,16 +40,15 @@ var MathEditorContent = /*#__PURE__*/memo(function (_ref) {
41
40
  focusRef === null || focusRef === void 0 || focusRef(textareaRef.current);
42
41
  }, [focusRef]);
43
42
 
44
- // 聚焦和光标位置处理
45
- useEffect(function () {
46
- if (textareaRef.current) {
47
- textareaRef.current.focus();
48
- if (prev) {
49
- var _textareaRef$current$;
50
- (_textareaRef$current$ = textareaRef.current.resizableTextArea) === null || _textareaRef$current$ === void 0 || (_textareaRef$current$ = _textareaRef$current$.textArea) === null || _textareaRef$current$ === void 0 || _textareaRef$current$.setSelectionRange(0, 0);
51
- }
52
- }
53
- }, [prev]);
43
+ // // 聚焦和光标位置处理
44
+ // useEffect(() => {
45
+ // if (textareaRef.current) {
46
+ // textareaRef.current.focus();
47
+ // if (prev) {
48
+ // textareaRef.current.resizableTextArea?.textArea?.setSelectionRange(0, 0);
49
+ // }
50
+ // }
51
+ // }, [prev]);
54
52
 
55
53
  // 实时验证 LaTeX 语法
56
54
  useEffect(function () {
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  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); }
4
- var _excluded = ["defaultHeight", "height", "maxHeight", "minHeight", "resizeMaxHeightOffset", "resize", "onSizeChange", "onSizeDragging", "className", "children", "footer", "header", "style", "slashMenuRef", "classNames", "fullscreen", "showResizeHandle", "styles"];
4
+ var _excluded = ["defaultHeight", "height", "maxHeight", "minHeight", "resizeMaxHeightOffset", "resize", "onSizeChange", "onSizeDragging", "className", "children", "footer", "header", "style", "slashMenuRef", "classNames", "fullscreen", "showResizeHandle", "onBodyClick", "styles"];
5
5
  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; }
6
6
  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; }
7
7
  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; }
@@ -46,6 +46,7 @@ var ChatInput = /*#__PURE__*/memo(function (props) {
46
46
  classNames = props.classNames,
47
47
  fullscreen = props.fullscreen,
48
48
  showResizeHandle = props.showResizeHandle,
49
+ onBodyClick = props.onBodyClick,
49
50
  customStyles = props.styles,
50
51
  rest = _objectWithoutProperties(props, _excluded);
51
52
  var _useStyles = useStyles(),
@@ -79,6 +80,8 @@ var ChatInput = /*#__PURE__*/memo(function (props) {
79
80
  }, [onSizeDragging, defaultHeight]);
80
81
  var bodyNode = /*#__PURE__*/_jsx("div", {
81
82
  className: cx(styles.editor, classNames === null || classNames === void 0 ? void 0 : classNames.body),
83
+ draggable: false,
84
+ onClick: onBodyClick,
82
85
  style: _objectSpread(_objectSpread({}, customStyles === null || customStyles === void 0 ? void 0 : customStyles.body), {}, {
83
86
  flex: 1,
84
87
  maxHeight: fullscreen ? '100%' : maxHeight,
@@ -6,8 +6,8 @@ export var useStyles = createStyles(function (_ref) {
6
6
  token = _ref.token;
7
7
  return {
8
8
  container: css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n position: relative;\n\n display: flex;\n flex-direction: column;\n\n height: 100%;\n border: 1px solid ", ";\n border-radius: ", "px;\n\n background-color: ", ";\n box-shadow:\n ", ",\n 0 32px 0 ", ";\n "])), token.colorBorderSecondary, token.borderRadiusLG, token.colorBgContainer, token.boxShadowTertiary, token.colorBgContainerSecondary),
9
- editor: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n overflow: hidden auto;\n flex: 1;\n\n width: 100%;\n padding-block: 8px 0;\n padding-inline: 12px;\n "]))),
10
- resizableContainer: css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n position: relative;\n\n display: flex;\n flex-direction: column;\n align-self: flex-end;\n\n width: 100%;\n\n &:hover .resize-handle {\n opacity: 1;\n }\n "]))),
9
+ editor: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n cursor: text;\n\n overflow: hidden auto;\n flex: 1;\n\n width: 100%;\n padding-block: 8px 0;\n padding-inline: 12px;\n "]))),
10
+ resizableContainer: css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n position: relative;\n\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n align-self: flex-end;\n\n width: 100%;\n\n &:hover .resize-handle {\n opacity: 1;\n }\n "]))),
11
11
  resizeHandle: css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n position: absolute;\n inset-block-start: -4px;\n inset-inline-start: 50%;\n transform: translateX(-50%);\n\n width: 100%;\n height: 8px;\n\n opacity: 0;\n\n transition: opacity 0.2s ease-in-out;\n\n &::before {\n content: '';\n\n position: absolute;\n inset-block-start: 0;\n inset-inline-start: 50%;\n transform: translateX(-50%);\n\n width: 32px;\n height: 4px;\n border-radius: 4px;\n\n background-color: ", ";\n box-shadow: 0 1px 2px ", "20;\n }\n\n &:hover {\n opacity: 1 !important;\n\n &::before {\n background-color: ", ";\n box-shadow: 0 2px 4px ", "40;\n }\n }\n\n &:active {\n &::before {\n background-color: ", ";\n }\n }\n "])), token.colorPrimary, token.colorTextSecondary, token.colorPrimaryHover, token.colorTextSecondary, token.colorPrimaryActive)
12
12
  };
13
13
  });
@@ -13,6 +13,7 @@ export interface ChatInputProps extends Omit<FlexboxProps, 'height'> {
13
13
  height?: number;
14
14
  maxHeight?: number;
15
15
  minHeight?: number;
16
+ onBodyClick?: FlexboxProps['onClick'];
16
17
  onSizeChange?: (height: number) => void;
17
18
  onSizeDragging?: (height: number) => void;
18
19
  resize?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/editor",
3
- "version": "1.8.5",
3
+ "version": "1.9.0",
4
4
  "description": "A powerful and extensible rich text editor built on Meta's Lexical framework, providing a modern editing experience with React integration.",
5
5
  "keywords": [
6
6
  "lobehub",