@lobehub/editor 1.21.3 → 1.22.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.
@@ -47,7 +47,8 @@ var ReactPlainText = /*#__PURE__*/memo(function (_ref) {
47
47
  onPressEnter = _ref.onPressEnter,
48
48
  onCompositionStart = _ref.onCompositionStart,
49
49
  onCompositionEnd = _ref.onCompositionEnd,
50
- onContextMenu = _ref.onContextMenu;
50
+ onContextMenu = _ref.onContextMenu,
51
+ onTextChange = _ref.onTextChange;
51
52
  var isChat = variant === 'chat';
52
53
  var _theme$fontSize = theme.fontSize,
53
54
  fontSize = _theme$fontSize === void 0 ? isChat ? 14 : 16 : _theme$fontSize,
@@ -103,10 +104,29 @@ var ReactPlainText = /*#__PURE__*/memo(function (_ref) {
103
104
  editor.setDocument(type, content);
104
105
  setIsInitialized(true);
105
106
  }
106
- return (_editor$getLexicalEdi = editor.getLexicalEditor()) === null || _editor$getLexicalEdi === void 0 ? void 0 : _editor$getLexicalEdi.registerUpdateListener(function () {
107
+
108
+ // Track previous content for onTextChange comparison
109
+ var previousContent;
110
+ return (_editor$getLexicalEdi = editor.getLexicalEditor()) === null || _editor$getLexicalEdi === void 0 ? void 0 : _editor$getLexicalEdi.registerUpdateListener(function (_ref2) {
111
+ var dirtyElements = _ref2.dirtyElements,
112
+ dirtyLeaves = _ref2.dirtyLeaves;
113
+ // Always trigger onChange for any update
107
114
  onChange === null || onChange === void 0 || onChange(editor);
115
+
116
+ // Only trigger onTextChange when content actually changes
117
+ if (onTextChange && (dirtyElements.size > 0 || dirtyLeaves.size > 0)) {
118
+ var currentContent = JSON.stringify(editor.getDocument(type));
119
+ if (previousContent === undefined) {
120
+ // First update after initialization
121
+ previousContent = currentContent;
122
+ } else if (currentContent !== previousContent) {
123
+ // Content has actually changed
124
+ previousContent = currentContent;
125
+ onTextChange(editor);
126
+ }
127
+ }
108
128
  });
109
- }, [editor, type, content, onChange, isInitialized]);
129
+ }, [editor, type, content, onChange, onTextChange, isInitialized]);
110
130
  useEffect(function () {
111
131
  if (editor && onPressEnter) {
112
132
  return editor.registerHighCommand(KEY_DOWN_COMMAND, function (event) {
@@ -50,6 +50,11 @@ export interface ReactPlainTextProps {
50
50
  editor: IEditor;
51
51
  event: KeyboardEvent;
52
52
  }) => boolean | void;
53
+ /**
54
+ * Callback triggered only when text content changes
55
+ * Unlike onChange, this won't trigger on cursor movement or selection changes
56
+ */
57
+ onTextChange?: (editor: IEditor) => void;
53
58
  style?: CSSProperties;
54
59
  theme?: CommonPluginOptions['theme'] & {
55
60
  fontSize?: number;
@@ -53,7 +53,8 @@ var Editor = /*#__PURE__*/memo(function (_ref) {
53
53
  markdownOption = _ref$markdownOption === void 0 ? true : _ref$markdownOption,
54
54
  onCompositionStart = _ref.onCompositionStart,
55
55
  onCompositionEnd = _ref.onCompositionEnd,
56
- onContextMenu = _ref.onContextMenu;
56
+ onContextMenu = _ref.onContextMenu,
57
+ onTextChange = _ref.onTextChange;
57
58
  var _useEditorContent = useEditorContent(),
58
59
  config = _useEditorContent.config;
59
60
  var enableSlash = Boolean((slashOption === null || slashOption === void 0 ? void 0 : slashOption.items) && slashOption.items.length > 0);
@@ -107,6 +108,7 @@ var Editor = /*#__PURE__*/memo(function (_ref) {
107
108
  onFocus: onFocus,
108
109
  onKeyDown: onKeyDown,
109
110
  onPressEnter: onPressEnter,
111
+ onTextChange: onTextChange,
110
112
  style: style,
111
113
  variant: variant,
112
114
  children: /*#__PURE__*/_jsx(ReactEditorContent, {
@@ -29,6 +29,11 @@ export interface EditorProps extends Partial<ReactEditorContentProps>, Omit<Reac
29
29
  };
30
30
  mentionOption?: MentionOption;
31
31
  onInit?: (editor: IEditor) => void;
32
+ /**
33
+ * Callback triggered only when text content changes
34
+ * Unlike onChange, this won't trigger on cursor movement or selection changes
35
+ */
36
+ onTextChange?: (editor: IEditor) => void;
32
37
  plugins?: EditorPlugin[];
33
38
  slashOption?: Partial<ReactSlashOptionProps>;
34
39
  style?: CSSProperties;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/editor",
3
- "version": "1.21.3",
3
+ "version": "1.22.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",