Skip to content

[lexical][@lexical/react] Bug Fix: Fix cursor disappearing in Firefox when dragging blocks#8065

Merged
etrepum merged 7 commits intofacebook:mainfrom
aldoprogrammer:fix/cursor-disappearing-firefox
Jan 11, 2026
Merged

[lexical][@lexical/react] Bug Fix: Fix cursor disappearing in Firefox when dragging blocks#8065
etrepum merged 7 commits intofacebook:mainfrom
aldoprogrammer:fix/cursor-disappearing-firefox

Conversation

@aldoprogrammer
Copy link
Copy Markdown
Contributor

@aldoprogrammer aldoprogrammer commented Jan 5, 2026

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 blur event on the editor root element when clicking the drag handle, which happens before the dragstart event. This causes focus loss and makes the cursor invisible.

Solution:

  1. Blur handler fix (LexicalEvents.ts): Detect when blur is caused by clicking the drag handle (by checking if relatedTarget has class draggable-block-menu). When detected, immediately restore focus synchronously and prevent the BLUR_COMMAND from being dispatched.

  2. Drag start fallback (LexicalDraggableBlockPlugin.tsx): Add synchronous focus restoration in onDragStart as a fallback to ensure cursor visibility during drag operations.

Changes:

  • Modified packages/lexical/src/LexicalEvents.ts - Added Firefox-specific blur handler logic
  • Modified packages/lexical-react/src/LexicalDraggableBlockPlugin.tsx - Added focus restoration in onDragStart and onDragEnd

Test 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:

  • ✅ Tested in Firefox 146.0.1 - cursor remains visible during drag
  • ✅ Tested in Chrome - no regressions
  • ✅ Tested in Edge - no regressions
  • ✅ Normal typing behavior unchanged in all browsers
  • ✅ Unit tests pass (LexicalSelection tests)
  • ✅ Linting passes

Closes #8064

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.
@vercel
Copy link
Copy Markdown

vercel bot commented Jan 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
lexical Ready Ready Preview, Comment Jan 9, 2026 2:12pm
lexical-playground Ready Ready Preview, Comment Jan 9, 2026 2:12pm

@meta-cla meta-cla bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jan 5, 2026
Copy link
Copy Markdown
Collaborator

@etrepum etrepum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LexicalEvents shouldn’t hardcode any specific class names, the workaround for this should be contained to the plugin.

@etrepum etrepum added the extended-tests Run extended e2e tests on a PR label Jan 5, 2026
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.
@aldoprogrammer
Copy link
Copy Markdown
Contributor Author

Thanks for the feedback! I've refactored the fix to keep the workaround contained within the plugin as requested.

Changes made:

  • Removed the hardcoded draggable-block-menu class check from LexicalEvents.ts
  • Moved the blur prevention logic to LexicalDraggableBlockPlugin.tsx using the existing isOnMenu function (which is already provided to the plugin)
  • Added a blur event listener via registerRootListener that detects when blur is caused by clicking the drag handle
  • Added a BLUR_COMMAND handler as a fallback to intercept the command if needed

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.

@etrepum
Copy link
Copy Markdown
Collaborator

etrepum commented Jan 5, 2026

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(() => {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like it could be problematic since there could be another update which changes the selection before the rAF callback

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +423 to +425
Promise.resolve().then(() => {
editor.focus();
});
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you try using $onUpdate first?

Suggested change
Promise.resolve().then(() => {
editor.focus();
});
$onUpdate(() => {
editor.focus();
});

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not yet, good call. I’ll try using $onUpdate first and update the PR.

@aldoprogrammer
Copy link
Copy Markdown
Contributor Author

aldoprogrammer commented Jan 9, 2026

I’ve updated the PR. Please let me know if I missed anything.

@etrepum etrepum added this pull request to the merge queue Jan 11, 2026
Merged via the queue into facebook:main with commit f80066c Jan 11, 2026
39 checks passed
@aldoprogrammer aldoprogrammer deleted the fix/cursor-disappearing-firefox branch January 22, 2026 23:35
@etrepum etrepum mentioned this pull request Jan 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. extended-tests Run extended e2e tests on a PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Cursor disappears when dragging or interacting with the left-side section (hand icon gesture)

2 participants