Skip to content
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

Navigating away from a focused CodeMirror blocks all inputs on the page #677

Open
Hypnosphi opened this issue Jul 22, 2024 · 17 comments
Open

Comments

@Hypnosphi
Copy link

Example on CodeSandbox: https://codesandbox.io/p/devbox/react-codemirror-breaks-input-5sl4fw

To reproduce, click on "CodeMirror" link in the preview and then navigate back using the preview browser controls (that is, without blurring the CodeMirror element). After that, no input in the textarea is possible

@jaywcjlove
Copy link
Member

2024-07-23.01.46.02.mp4

@Hypnosphi After testing, I can edit. I’m not sure if I misunderstood.

@Hypnosphi
Copy link
Author

@jaywcjlove it's because the CodeMirror gets blurred when you click "TextArea" link. To reproduce, please use the browser "back" button above

@jaywcjlove
Copy link
Member

I reproduced the error. I think if you need to put the textarea in a component and maintain a state, it might solve the problem.

@Hypnosphi
Copy link
Author

@jaywcjlove No, it blocks absolutely all inputs, controlled or uncontrolled, and even the ones not rendered by React:

https://codesandbox.io/p/devbox/react-codemirror-breaks-input-5sl4fw

@atilara
Copy link

atilara commented Aug 1, 2024

Also noticed this happening here

1 similar comment
@helmutmigge
Copy link

Also noticed this happening here

@helmutmigge
Copy link

From what I've seen this happens when the codemirror is in focus and it happens to someone who removes the codemirror from the DOM. Ex radix Tabs

@Hypnosphi
Copy link
Author

Let me know if you find a workaround like performing some cleanup on unmounting codemirror

@jazeee
Copy link

jazeee commented Oct 17, 2024

I've seen this too. It seems to be dependent on how the component is managed in React code.
It locks every input field. The only workaround I have seen is that you can reopen the view that contains the ReactCodeMirror component, focus on it, and then blur away, and then go back to what you were on.
I am trying to reproduce it in a simple way. (I observe it without routing involved, but rather with conditionally showing the a side drawer that contains ReactCodeMirror.

@jazeee
Copy link

jazeee commented Oct 17, 2024

More specific observation

  1. Open a drawer with a container contianing an editable, focusable ReactCodeMirror. (It must get focus)
  2. Swap out the container contents to a different form. The inputs in that other form don't allow you to type. Nor do any other inputs in the dom. You can hit the back arrow to see the cursor move, but you cannot type anything.
Screen.Recording.2024-10-17.at.3.24.05.PM.mov

@jazeee
Copy link

jazeee commented Oct 21, 2024

We have seem intermittent issues without portals or drawers, but in order to reliably see the issue, here's a reproducible version:
https://codesandbox.io/p/devbox/react-codemirror-breaks-input-forked-l7rhtv
Generally, there appears to be issues related to grabbing input field focuses, and releasing focus.

To see the issue,

  1. focus on the code mirror within a drawer
  2. Click on a button outside of the drawer that sets focus on another input
  3. Attempt to type in any input field.
    Observe that the code mirror field has focus and gets data entry
    Expect that the focused input field gets data entry.

@jazeee
Copy link

jazeee commented Oct 21, 2024

Looking at the react-codemirror code, I see a prop root, related to portals. That doesn't seem to help.
In addition, there are useEffect functions that seem to introduce repeated calls to codemirror.
One thing that may help things:

      if (!view) {
        const viewCurrent = new EditorView({
          state: stateCurrent,
          parent: container,
          root,
        });
        setView(viewCurrent);
//...
     }

should be something like:

setView((currentView) => {
  if (currentView) {
    return currentView
  }
  return new EditorView... 
}

I don't know if this will solve the issue, but generally, updating state based on current state should be done functionally since the latest state is not updated immediately.

@jazeee
Copy link

jazeee commented Oct 21, 2024

Video example of
https://codesandbox.io/p/live/edbd7977-c460-48db-b3ea-c44807071ffe

Screen.Recording.2024-10-21.at.4.18.01.PM-1.mov

@jazeee
Copy link

jazeee commented Oct 24, 2024

@jaywcjlove
Copy link
Member

Looking at the react-codemirror code, I see a prop root, related to portals. That doesn't seem to help. In addition, there are useEffect functions that seem to introduce repeated calls to codemirror. One thing that may help things:

      if (!view) {
        const viewCurrent = new EditorView({
          state: stateCurrent,
          parent: container,
          root,
        });
        setView(viewCurrent);
//...
     }

should be something like:

setView((currentView) => {
  if (currentView) {
    return currentView
  }
  return new EditorView... 
}

I don't know if this will solve the issue, but generally, updating state based on current state should be done functionally since the latest state is not updated immediately.

@jazeee Contributions via PR to solve this issue are warmly welcomed!

jaywcjlove added a commit that referenced this issue Nov 13, 2024
@jaywcjlove
Copy link
Member

@jazeee I couldn’t reproduce this error in Next.js, and I still haven’t figured out the exact cause of the issue.

@jazeee
Copy link

jazeee commented Nov 14, 2024

@jaywcjlove yeah, it is a tricky bug. Here is the code sample I was able to repro in.
Codesandbox
Video
The bug seems to be related to how the component (or the underlying codemirror code) is rendered.
In my repro, it is inside a MUI Drawer, but others appear to have seen this bug during client side react-router-dom route changes.
(May need client side rendering to help see it more often)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants