[lexical][@lexical/react] Bug Fix: Fix cursor disappearing in Firefox when dragging blocks#8065
Conversation
…n Yjs collaboration
In Firefox, clicking the draggable block handle fires a blur event before dragstart, causing focus loss and making the cursor invisible. This fix detects blur events caused by drag handle clicks and immediately restores focus synchronously to prevent cursor loss. - Detect blur from drag handle in LexicalEvents.ts blur handler - Restore focus synchronously when drag handle blur is detected - Add fallback focus restoration in onDragStart for Firefox - Ensure cursor remains visible throughout drag operations Fixes cursor visibility issue in Firefox (version 146.0.1+) when interacting with draggable block handles.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
etrepum
left a comment
There was a problem hiding this comment.
LexicalEvents shouldn’t hardcode any specific class names, the workaround for this should be contained to the plugin.
Refactor blur event handling to prevent cursor loss when clicking on drag handles in Firefox. The changes include: - Moved blur detection logic from LexicalEvents.ts to LexicalDraggableBlockPlugin.tsx for better encapsulation. - Implemented synchronous focus restoration to maintain cursor visibility. - Added a fallback mechanism to intercept the BLUR_COMMAND when focus is on the menu. This addresses the issue of cursor disappearance during drag operations in Firefox.
|
Thanks for the feedback! I've refactored the fix to keep the workaround contained within the plugin as requested. Changes made:
The plugin now handles its own blur prevention without any hardcoded class names in the core, maintaining proper separation of concerns. The fix still works correctly in Firefox - the cursor remains visible when dragging blocks. |
|
Right now this PR also includes the changes from #8062 so I think it will fail the type check for the same reason. I'll take another look at this one once that PR is fixed and merged. |
| // explicitly set it again right after focus | ||
| try { | ||
| // Use requestAnimationFrame to ensure this happens in the next frame after focus | ||
| requestAnimationFrame(() => { |
There was a problem hiding this comment.
This seems like it could be problematic since there could be another update which changes the selection before the rAF callback
There was a problem hiding this comment.
Yeah, just noticed it. Using requestAnimationFrame here could race with another update that modifies the selection. I’ll remove this and handle it synchronously within the update cycle instead.
| Promise.resolve().then(() => { | ||
| editor.focus(); | ||
| }); |
There was a problem hiding this comment.
Did you try using $onUpdate first?
| Promise.resolve().then(() => { | |
| editor.focus(); | |
| }); | |
| $onUpdate(() => { | |
| editor.focus(); | |
| }); |
There was a problem hiding this comment.
Not yet, good call. I’ll try using $onUpdate first and update the PR.
… remove requestAnimationFrame race condition
…aldoprogrammer/lexical into fix/cursor-disappearing-firefox
|
I’ve updated the PR. Please let me know if I missed anything. |
Description
Problem:
In Firefox (version 146.0.1+), the text cursor disappears when interacting with the draggable block handle (hand icon). The cursor becomes invisible when starting a drag operation, even though typing still works. This issue does not occur in Chrome or Edge.
Root Cause:
Firefox fires a
blurevent on the editor root element when clicking the drag handle, which happens before thedragstartevent. This causes focus loss and makes the cursor invisible.Solution:
Blur handler fix (
LexicalEvents.ts): Detect when blur is caused by clicking the drag handle (by checking ifrelatedTargethas classdraggable-block-menu). When detected, immediately restore focus synchronously and prevent theBLUR_COMMANDfrom being dispatched.Drag start fallback (
LexicalDraggableBlockPlugin.tsx): Add synchronous focus restoration inonDragStartas a fallback to ensure cursor visibility during drag operations.Changes:
packages/lexical/src/LexicalEvents.ts- Added Firefox-specific blur handler logicpackages/lexical-react/src/LexicalDraggableBlockPlugin.tsx- Added focus restoration inonDragStartandonDragEndTest plan
Before
We can't see the pointer cursor poisitoin, after we make a drag action on left side, please check the demo ini #8064 to see it.
After
Now the cursor position remains visible after we did drag action on left side.
Demo
Watch here
Testing:
Closes #8064