Cannot interact with a form inside NodeView

We have a NodeView for images that displays an form on click. I made a helper function to create NodeViews for React components. This form renders correctly, however when I try to click on one of the inputs it does not focus correctly. After several clicks it appears to focus on the input, but typing then gets caught by prosemirror and overwrites the image.

Animation

ImageNodeView

ImageNodeView.ts

This is a simplified representation of the form in the gif.

export const ImageNodeView = reactNodeView(
  class Image extends React.Component {
    onChange = () => { /* ... */ }
    render() {
      const { node } = this.props
      return (
        <div>
          <input type="text" name="alt" value={node.attrs.alt} onChange={this.onChange} />
          <img src={node.attrs.src} />
        </div>
      )
    }
  }
)

reactNodeView.ts

import { render, unmountComponentAtNode } from 'react-dom';

export interface Props {
  view: EditorView
  node: Node
  getPos(): number
  decorations: Decoration[]
}

export function reactNodeView(Component: any) {
  const renderComponent = (props: any, dom: any) => render(<Component {...props} />, dom)

  return (node: Node, view: EditorView, getPos: () => number, decorations: Decoration[]): NodeView => {
    let dom = document.createElement("div")
    renderComponent({ node, view, decorations, getPos }, dom)
    return {
      dom,
      update(node, decorations) {
        renderComponent({ node, view, decorations, getPos }, dom)
        return true
      },
      destroy() {
        unmountComponentAtNode(dom)
      },
    }
  }
}

Adding these two functions to the reactNodeView seemed to help.

      stopEvent() {
        return true
      },
      ignoreMutation(e) {
        return true
      },

I’m not sure if this is the right thing to do though.

Edit: Not entirely. When I drag images around it now duplicates the image without attrs instead of moving it.

Yes, those methods are the way to stop prosemirror from handling events and mutations inside your node. You might in some cases need to be more specific in which mutations and events you handle and which you let through, but often just returning true is fine.

There’s some issue around dragging and node views, it seems. See also this thread. I’ll see if I can reproduce that.

1 Like