From ff745bfebe524141608f53b2318ec22263e32b4a Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 8 Nov 2025 17:16:06 +0000 Subject: [PATCH] feat(web): improve list auto-completion and tag insertion UX Two user experience improvements based on feedback: 1. **GitHub-style empty list item handling:** - When pressing Enter on an empty list item (e.g., just "- "), remove the list marker instead of continuing the list - Matches GitHub's behavior for exiting list mode - Works for all list types: unordered (-, *, +), ordered (1., 2.), and task lists (- [ ]) - Makes it easier to exit list mode without manual deletion 2. **Auto-space after tag selection:** - When selecting a tag from suggestions, automatically add a trailing space after the tag - Improves typing flow - users can immediately continue typing - Matches common expectation for autocomplete behavior These changes make the editor feel more intuitive and reduce friction during content creation. --- .../MemoEditor/Editor/TagSuggestions.tsx | 4 ++-- .../Editor/useListAutoCompletion.ts | 24 +++++++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/web/src/components/MemoEditor/Editor/TagSuggestions.tsx b/web/src/components/MemoEditor/Editor/TagSuggestions.tsx index 780cae3aa..da2141aef 100644 --- a/web/src/components/MemoEditor/Editor/TagSuggestions.tsx +++ b/web/src/components/MemoEditor/Editor/TagSuggestions.tsx @@ -43,9 +43,9 @@ const TagSuggestions = observer(({ editorRef, editorActions }: TagSuggestionsPro return items.filter((tag) => tag.toLowerCase().includes(searchQuery)); }, onAutocomplete: (tag, word, index, actions) => { - // Replace the trigger word with the complete tag + // Replace the trigger word with the complete tag and add a trailing space actions.removeText(index, word.length); - actions.insertText(`#${tag}`); + actions.insertText(`#${tag} `); }, }); diff --git a/web/src/components/MemoEditor/Editor/useListAutoCompletion.ts b/web/src/components/MemoEditor/Editor/useListAutoCompletion.ts index 2fd3aa703..ce250b1ef 100644 --- a/web/src/components/MemoEditor/Editor/useListAutoCompletion.ts +++ b/web/src/components/MemoEditor/Editor/useListAutoCompletion.ts @@ -52,8 +52,28 @@ export function useListAutoCompletion({ editorRef, editorActions, isInIME }: Use if (listInfo.type) { event.preventDefault(); - const continuation = generateListContinuation(listInfo); - actions.insertText("\n" + continuation); + + // Check if current list item is empty (GitHub-style behavior) + // Extract the current line + const lines = contentBeforeCursor.split("\n"); + const currentLine = lines[lines.length - 1]; + + // Check if line only contains list marker (no content after it) + const isEmptyListItem = + /^(\s*)([-*+])\s*$/.test(currentLine) || // Empty unordered list + /^(\s*)([-*+])\s+\[([ xX])\]\s*$/.test(currentLine) || // Empty task list + /^(\s*)(\d+)[.)]\s*$/.test(currentLine); // Empty ordered list + + if (isEmptyListItem) { + // Remove the empty list marker and exit list mode + const lineStartPos = cursorPosition - currentLine.length; + actions.removeText(lineStartPos, currentLine.length); + actions.insertText("\n"); + } else { + // Continue the list with the next item + const continuation = generateListContinuation(listInfo); + actions.insertText("\n" + continuation); + } } };