draft-js icon indicating copy to clipboard operation
draft-js copied to clipboard

Draft not compatible with React 17

Open robbertbrak opened this issue 4 years ago • 5 comments

It appears that Draft is not fully compatible with React 17. The selection state sometimes isn't updated correctly.

To reproduce:

  • Check out the master branch of Draft JS
  • In package.json, update the versions of react and react-dom to "^17.0.1", and react-test-renderer to "^17.0.0"
  • Run yarn install and yarn run build
  • Open the rich.html example in a browser
  • Enter two paragraphs of text, e.g.:
We provide the building blocks to enable the creation of a broad variety  of rich text composition experiences, from basic text styles to  embedded media.

Draft.js fits seamlessly into React applications, abstracting away the  details of rendering, selection, and input behavior with a familiar  declarative API.
  • Select the word "seamlessly", and click the "B" icon twice to mark it as bold and unmark it again.
  • Click outside the editor
  • Select backwards from the end to the beginning, so that all text appears to be marked
  • Click the "B" icon

Result: only the word "seamlessly" is marked as bold. Expected result: the whole text should be marked as bold.

I was wondering if any work is already being done within Facebook to make Draft compatible with React 17? I'd like to help, but I have to admit that I don't really know where to start with this. I suspect that it has to do with the changes to the event delegation system described in https://reactjs.org/blog/2020/10/20/react-v17.html#changes-to-event-delegation, but I'm not sure.

robbertbrak avatar Jan 19 '21 08:01 robbertbrak

I am experiencing the same issue using React 17 and latest Draft-js. It seems like selection stops tracking events outside of viewport. If I start highlighting blocks and continue highlighting with my mouse outside of viewport, Selection loses highlighted text and once I attempt to toggle styles or block types it ends up only modifying the initial block.

https://codesandbox.io/s/formik-09x-draftjs-example-forked-0p9ce?file=/RichEditor.js:318-319

draft-js-selection

zen-tradeledger avatar Jan 30 '21 23:01 zen-tradeledger

If this helps anyone you can patch this issue by detecting out of viewport mouse release and trigger event on the root element within viewport bounds.

const useOutOfBoundsSelectionRecovery = (inFocus: boolean) => {
  useLayoutEffect(() => {
    if (!inFocus) {
      return
    }
    const handleOutsideMouseRelease = (e: MouseEvent) => {
      const vw = Math.max(
        document.documentElement.clientWidth || 0,
        window.innerWidth || 0
      )
      const vh = Math.max(
        document.documentElement.clientHeight || 0,
        window.innerHeight || 0
      )
      const isOutOfBounds =
        Math.min(e.offsetX, e.offsetY) < 0 || e.offsetX > vw || e.offsetY > vh
      if (isOutOfBounds) {
        const root = document.getElementById("root") as HTMLElement
        const mouseEvent = new MouseEvent("mouseup", {
          clientX: Math.min(vw, Math.max(0, e.clientX)),
          clientY: Math.min(vh, Math.max(0, e.clientY))
        })
        root.dispatchEvent(mouseEvent)
      }
    }
    document.addEventListener("mouseup", handleOutsideMouseRelease)

    return () => {
      document.removeEventListener("mouseup", handleOutsideMouseRelease)
    }
  }, [inFocus])
}

You can skip the inFocus check if you don't keep track of focus. Just run this hook within your Editor component.

zen-tradeledger avatar Jan 31 '21 04:01 zen-tradeledger

For anyone coming to GitHub issues for "cursor jumping", "text not deleting", or "unable to select" issues, we had a series of occasional, hard to reproduce issues after upgrading to React 17. After finding this issue, we downgraded back to React 16. Our hypothesis is that they were all related to the event delegation issues highlighted above.

keithhackbarth avatar Jul 21 '21 15:07 keithhackbarth

Is anyone running this with React 17 without any issues?

We would like to upgrade to React 17 because other packages are starting to depend on React 17 as well and DraftJS is the only one keeping us from upgrading.

danny-larsen avatar Aug 17 '21 15:08 danny-larsen

I have exactly the same issue, any solution? React17 was release a year ago

geniorgeous avatar Feb 08 '22 13:02 geniorgeous