refactor: simplify editor scroll logic

- Extract `scrollToCaret` helper to deduplicate scroll logic
- Unify precise scroll behavior for both manual triggers and auto-scroll
This commit is contained in:
Steven 2026-01-13 21:23:23 +08:00
parent 4e34ef22bf
commit 73c301072b
1 changed files with 24 additions and 18 deletions

View File

@ -52,6 +52,26 @@ const Editor = forwardRef(function Editor(props: EditorProps, ref: React.Forward
}
}, [handleContentChangeCallback, updateEditorHeight]);
const scrollToCaret = useCallback((options: { force?: boolean } = {}) => {
const editor = editorRef.current;
if (!editor) return;
const { force = false } = options;
const caret = getCaretCoordinates(editor, editor.selectionEnd);
if (force) {
editor.scrollTop = Math.max(0, caret.top - editor.clientHeight / 2);
return;
}
const lineHeight = parseFloat(getComputedStyle(editor).lineHeight) || 24;
const viewportBottom = editor.scrollTop + editor.clientHeight;
// Scroll if cursor is near or beyond bottom edge (within 2 lines)
if (caret.top + lineHeight * 2 > viewportBottom) {
editor.scrollTop = Math.max(0, caret.top - editor.clientHeight / 2);
}
}, []);
useEffect(() => {
if (editorRef.current && initialContent) {
editorRef.current.value = initialContent;
@ -75,12 +95,7 @@ const Editor = forwardRef(function Editor(props: EditorProps, ref: React.Forward
getEditor: () => editorRef.current,
focus: () => editorRef.current?.focus(),
scrollToCursor: () => {
const editor = editorRef.current;
if (!editor) return;
const caret = getCaretCoordinates(editor, editor.selectionEnd);
// Scroll to center cursor vertically
editor.scrollTop = Math.max(0, caret.top - editor.clientHeight / 2);
scrollToCaret({ force: true });
},
insertText: (content = "", prefix = "", suffix = "") => {
const editor = editorRef.current;
@ -143,7 +158,7 @@ const Editor = forwardRef(function Editor(props: EditorProps, ref: React.Forward
updateContent();
},
}),
[updateContent],
[updateContent, scrollToCaret],
);
useImperativeHandle(ref, () => editorActions, [editorActions]);
@ -155,18 +170,9 @@ const Editor = forwardRef(function Editor(props: EditorProps, ref: React.Forward
// Auto-scroll to keep cursor visible when typing
// See: https://github.com/usememos/memos/issues/5469
const editor = editorRef.current;
const caret = getCaretCoordinates(editor, editor.selectionEnd);
const lineHeight = parseFloat(getComputedStyle(editor).lineHeight) || 24;
// Scroll if cursor is near or beyond bottom edge (within 2 lines)
const viewportBottom = editor.scrollTop + editor.clientHeight;
if (caret.top + lineHeight * 2 > viewportBottom) {
// Scroll to center cursor vertically
editor.scrollTop = Math.max(0, caret.top - editor.clientHeight / 2);
}
scrollToCaret();
}
}, [handleContentChangeCallback, updateEditorHeight]);
}, [handleContentChangeCallback, updateEditorHeight, scrollToCaret]);
// Auto-complete markdown lists when pressing Enter
useListCompletion({