Hey all!
A little while ago, we shared our React ProseMirror integration library, @nytimes/react-prosemirror. Thank you so much to everyone who gave feedback, tried out the library, and posted issues on our repo!
For the past several months, I’ve been hard at work on a very different approach to integrate React and ProseMirror. The pull request is here for anyone who wishes to take a look.
The summary is this: the new approach completely replaces ProseMirror’s DOM management system with one built in React. We’re still using prosemirror-view for everything outside of change detection and DOM updates, which means we are exposing exactly the same API. In fact, I’ve ported over most of the unit tests from prosemirror-view to ensure that behavior matches the default library.
This change allows us to have a much cleaner integration with React, especially with regard to implementing node views with React components. Context flows as expected from parents to children, events bubble as expected, and node view components are just React components, without any special work needed. It also fixes a few edge case-y bugs, including significant issues with IME composition input. Overall, I feel confident that this is a huge improvement over the previous implementation, and one that could even be eventually pulled into higher level libraries like ReMirror and TipTap.
This new approach is implemented by subclassing EditorView and overriding some of the default behavior to essentially disable the DOM management. To do this subclassing, we needed to make two very small changes to the EditorView class, and I’m curious about how open you would be, Marijn, to incorporating these changes into prosemirror-view.
- We changed
updateStateInner
to beprotected
, rather thanprivate
. This allowed us to override its implementation in our subclass, to essentially drop everything except for the selection syncing. - We moved all of the side effect-y code out of the EditorView constructor and into a new,
protected
,init
method. This is still called in the constructor, but having it in an override-able method allows us to again drop the pieces of this that are managed by our new, React-based system.
Here’s the place in the pull request where this happens, in case anyone wants to take a look:
There are also a few internal functions that we’re using. It would obviously make my life easier if these were exposed in some way, but I don’t want to ask for a huge increase in the API surface of prosemirror-view if that’s not something you’re interested in. These are the internal functions we’re using:
storeScrollPos
andresetScrollPos
(These are used in ourupdateStateInner
override)selectionFromDOM
andselectionToDOM
computeDocDeco
Anyway, I’m looking for thoughts and feedback! In particular, Marijn, I’m very interested in hearing whether you would be open to a pull request against prosemirror-view with some or all of these changes. Please let me know if you have any questions!