-
Notifications
You must be signed in to change notification settings - Fork 2.3k
better textarea using lexical #8192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this PR implementing the Lexical-based textarea! This is a great start toward improving the UX for context mentions. However, there are several critical issues that need to be addressed before this can be merged:
Critical Issues (Must Fix):
-
Incomplete Migration -
ChatRow.tsx
still imports and uses the oldChatTextArea
component for edit mode. This needs to be updated to use the newChatLexicalTextArea
. -
Missing TypeScript Types - The build is failing with multiple TypeScript errors. While the Lexical dependencies are added to package.json, they may need to be installed with
pnpm install
. -
Missing Core Functionality:
- No send button or keyboard shortcut (Enter/Cmd+Enter) handling
- Missing enhance prompt functionality
- Missing mode switching via keyboard shortcuts
- No integration with queued messages
- Several props (
onSend
,onSelectImages
,onHeightChange
,onCancel
,ref
) are commented out but never implemented
Important Suggestions:
-
Global Function Pattern - Using
window.__lexicalInsertMention
for cross-component communication is fragile. Consider using React context or callback props. -
Test Coverage - Only one test file exists for select-all functionality. Missing tests for mentions, context menu, image handling, etc.
-
Performance - The
validMentions
state updates on every input change could be optimized with debouncing.
Minor Improvements:
-
Code Organization - Consider extracting mention extraction and display name logic into utility functions.
-
Accessibility - Missing ARIA labels and keyboard navigation announcements for screen readers.
This is marked as a draft PR which is appropriate given the current state. The core Lexical integration looks promising, but significant work is needed to achieve feature parity with the existing textarea before this can be merged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found some issues that need attention. Inline comments call out concrete fixes with minimal diffs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found a new issue that isn’t covered by existing comments. Inline note explains the concrete failure scenario and a targeted approach to fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found some issues that need attention. Inline comments call out concrete fixes with minimal diffs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found some issues that need attention. Inline comments call out concrete fixes with minimal diffs.
Co-authored-by: roomote[bot] <219738659+roomote[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found some issues that need attention. Inline comments call out concrete fixes with minimal diffs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found some issues that need attention. Inline comments include targeted fixes with minimal diffs.
setIsEnhancingPrompt(true) | ||
vscode.postMessage({ type: "enhancePrompt" as const, text: trimmedInput }) | ||
} else { | ||
setInputValue(t("chat:enhancePromptDescription")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: When Enhance Prompt is clicked with empty input, only inputValue is updated, leaving the Lexical editor empty. This desynchronizes UI state from the editor and confuses subsequent actions (serialization, send). Write the description into the editor so the content is visible and consistent.
setInputValue(t("chat:enhancePromptDescription")) | |
} else { | |
const msg = t("chat:enhancePromptDescription") | |
setInputValue(msg) | |
editorRef.current?.update(() => { | |
const root = $getRoot() | |
root.clear() | |
const p = $createParagraphNode() | |
p.append($createTextNode(msg)) | |
root.append(p) | |
root.selectEnd() | |
}) | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found some issues that need attention. Inline comments call out concrete fixes with minimal diffs.
const text = root.getTextContent() | ||
|
||
const isAtBeginning = anchor.offset === 0 | ||
const isAtEnd = anchor.offset === text.length |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P1] End-of-editor detection compares anchor.offset with the entire document length. anchor.offset is relative to its text node, so this will rarely be true in multi-node content. Down-arrow history navigation may not exit at the true end. Suggest computing against the last text node instead.
const isAtEnd = anchor.offset === text.length | |
const anchor = selection.anchor | |
const root = $getRoot() | |
const last = root.getLastDescendant() | |
const isAtBeginning = anchor.offset === 0 | |
const isAtEnd = $isTextNode(last) && anchor.key === last.getKey() && anchor.offset === last.getTextContentSize() | |
return { isAtBeginning, isAtEnd } |
if (type === ContextMenuOptionType.Folder) { | ||
processedValue = normalizeDirectoryPath(processedValue) | ||
} | ||
insertValue = escapeSpaces(processedValue) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P1] Double-escaping file/folder paths. Values are escaped on insertion and escaped again when serializing, producing extra backslashes (e.g., @/My\\ File.ts
). Keep the raw path in the node and escape only during serialization.
insertValue = escapeSpaces(processedValue) | |
insertValue = processedValue |
Related GitHub Issue
Closes: #4372
Roo Code Task Context (Optional)
Description
This is still a work in progress, I've described the goal in the original issue. I'm making a draft just for visibility. This isn't the final work since the main goal here is to prototype how it will look / function. I will clean up the code later when this feature gets a green flag to be integrated into Roo.
Test Procedure
Pre-Submission Checklist
Screenshots / Videos
These are temporary as I will keep updating them until I mark this PR as ready
Screen.Recording.2025-09-29.at.17.58.26.mov
Documentation Updates
Additional Notes
Get in Touch
@elianiva