mirror of https://github.com/usememos/memos.git
refactor(web): extract list auto-completion logic into custom hook
- Create useListAutoCompletion hook to encapsulate list continuation logic - Simplify handleEditorKeyDown in Editor component - Improve code organization and testability - Add comprehensive documentation for the hook - Maintain all existing functionality for markdown lists The handleEditorKeyDown function is now much cleaner, delegating list auto-completion concerns to a dedicated, reusable hook.
This commit is contained in:
parent
f11c355446
commit
7f8f0c753d
|
|
@ -1,10 +1,10 @@
|
|||
import { forwardRef, ReactNode, useCallback, useEffect, useImperativeHandle, useRef, useState } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { detectLastListItem, generateListContinuation } from "@/utils/markdown-list-detection";
|
||||
import { Command } from "../types/command";
|
||||
import CommandSuggestions from "./CommandSuggestions";
|
||||
import TagSuggestions from "./TagSuggestions";
|
||||
import { editorCommands } from "./commands";
|
||||
import { useListAutoCompletion } from "./useListAutoCompletion";
|
||||
|
||||
export interface EditorRefActions {
|
||||
getEditor: () => HTMLTextAreaElement | null;
|
||||
|
|
@ -152,22 +152,14 @@ const Editor = forwardRef(function Editor(props: Props, ref: React.ForwardedRef<
|
|||
updateEditorHeight();
|
||||
}, []);
|
||||
|
||||
const handleEditorKeyDown = async (event: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
||||
if (event.key === "Enter" && !isInIME) {
|
||||
if (event.shiftKey || event.ctrlKey || event.metaKey || event.altKey) {
|
||||
return;
|
||||
}
|
||||
const { handleEnterKey } = useListAutoCompletion({
|
||||
editorActions,
|
||||
isInIME,
|
||||
});
|
||||
|
||||
const cursorPosition = editorActions.getCursorPosition();
|
||||
const prevContent = editorActions.getContent().substring(0, cursorPosition);
|
||||
|
||||
// Detect list item using regex-based detection
|
||||
const listInfo = detectLastListItem(prevContent);
|
||||
if (listInfo.type) {
|
||||
event.preventDefault();
|
||||
const insertText = "\n" + generateListContinuation(listInfo);
|
||||
editorActions.insertText(insertText);
|
||||
}
|
||||
const handleEditorKeyDown = (event: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
||||
if (event.key === "Enter") {
|
||||
handleEnterKey(event);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
import { useCallback } from "react";
|
||||
import { detectLastListItem, generateListContinuation } from "@/utils/markdown-list-detection";
|
||||
import { EditorRefActions } from ".";
|
||||
|
||||
interface UseListAutoCompletionOptions {
|
||||
editorActions: EditorRefActions;
|
||||
isInIME: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom hook for handling markdown list auto-completion.
|
||||
* When the user presses Enter on a list item, this hook automatically
|
||||
* continues the list with the appropriate formatting.
|
||||
*
|
||||
* Supports:
|
||||
* - Ordered lists (1. item, 2. item, etc.)
|
||||
* - Unordered lists (- item, * item, + item)
|
||||
* - Task lists (- [ ] task, - [x] task)
|
||||
* - Nested lists with proper indentation
|
||||
*/
|
||||
export function useListAutoCompletion({ editorActions, isInIME }: UseListAutoCompletionOptions) {
|
||||
/**
|
||||
* Handles the Enter key press to auto-complete list items.
|
||||
* Returns true if the event was handled, false otherwise.
|
||||
*/
|
||||
const handleEnterKey = useCallback(
|
||||
(event: React.KeyboardEvent<HTMLTextAreaElement>): boolean => {
|
||||
// Don't handle if in IME composition (for Asian languages)
|
||||
if (isInIME) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't handle if modifier keys are pressed (user wants manual control)
|
||||
if (event.shiftKey || event.ctrlKey || event.metaKey || event.altKey) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const cursorPosition = editorActions.getCursorPosition();
|
||||
const contentBeforeCursor = editorActions.getContent().substring(0, cursorPosition);
|
||||
|
||||
// Detect if we're on a list item
|
||||
const listInfo = detectLastListItem(contentBeforeCursor);
|
||||
|
||||
if (listInfo.type) {
|
||||
event.preventDefault();
|
||||
const continuation = generateListContinuation(listInfo);
|
||||
editorActions.insertText("\n" + continuation);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
[editorActions, isInIME],
|
||||
);
|
||||
|
||||
return { handleEnterKey };
|
||||
}
|
||||
Loading…
Reference in New Issue