fix: use ref to move contentDOM (#1960), fix #1942

This commit is contained in:
Philipp Kühn 2021-09-30 21:13:37 +02:00 committed by GitHub
parent f9493c289f
commit dead826250
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 18 additions and 29 deletions

View File

@ -1,4 +1,4 @@
import React, { useEffect } from 'react'
import React from 'react'
import { useReactNodeView } from './useReactNodeView'
export interface NodeViewContentProps {
@ -6,18 +6,14 @@ export interface NodeViewContentProps {
as?: React.ElementType,
}
export const NodeViewContent: React.FC<NodeViewContentProps> = React.forwardRef((props, ref) => {
export const NodeViewContent: React.FC<NodeViewContentProps> = props => {
const Tag = props.as || 'div'
const { maybeMoveContentDOM } = useReactNodeView()
useEffect(() => {
maybeMoveContentDOM?.()
}, [])
const { nodeViewContentRef } = useReactNodeView()
return (
<Tag
{...props}
ref={ref}
ref={nodeViewContentRef}
data-node-view-content=""
style={{
...props.style,
@ -25,4 +21,4 @@ export const NodeViewContent: React.FC<NodeViewContentProps> = React.forwardRef(
}}
/>
)
})
}

View File

@ -10,7 +10,7 @@ import { Decoration, NodeView as ProseMirrorNodeView } from 'prosemirror-view'
import { Node as ProseMirrorNode } from 'prosemirror-model'
import { Editor } from './Editor'
import { ReactRenderer } from './ReactRenderer'
import { ReactNodeViewContext } from './useReactNodeView'
import { ReactNodeViewContext, ReactNodeViewContextProps } from './useReactNodeView'
export interface ReactNodeViewRendererOptions extends NodeViewRendererOptions {
update: ((props: {
@ -49,12 +49,20 @@ class ReactNodeView extends NodeView<React.FunctionComponent, Editor, ReactNodeV
}
const ReactNodeViewProvider: React.FunctionComponent = componentProps => {
const onDragStart = this.onDragStart.bind(this)
const maybeMoveContentDOM = this.maybeMoveContentDOM.bind(this)
const Component = this.component
const onDragStart = this.onDragStart.bind(this)
const nodeViewContentRef: ReactNodeViewContextProps['nodeViewContentRef'] = element => {
if (
element
&& this.contentDOMElement
&& element.firstChild !== this.contentDOMElement
) {
element.appendChild(this.contentDOMElement)
}
}
return (
<ReactNodeViewContext.Provider value={{ onDragStart, maybeMoveContentDOM }}>
<ReactNodeViewContext.Provider value={{ onDragStart, nodeViewContentRef }}>
<Component {...componentProps} />
</ReactNodeViewContext.Provider>
)
@ -98,27 +106,12 @@ class ReactNodeView extends NodeView<React.FunctionComponent, Editor, ReactNodeV
return null
}
this.maybeMoveContentDOM()
return this.contentDOMElement
}
maybeMoveContentDOM(): void {
const contentElement = this.dom.querySelector('[data-node-view-content]')
if (
this.contentDOMElement
&& contentElement
&& !contentElement.contains(this.contentDOMElement)
) {
contentElement.appendChild(this.contentDOMElement)
}
}
update(node: ProseMirrorNode, decorations: Decoration[]) {
const updateProps = (props?: Record<string, any>) => {
this.renderer.updateProps(props)
this.maybeMoveContentDOM()
}
if (typeof this.options.update === 'function') {

View File

@ -2,7 +2,7 @@ import { createContext, useContext } from 'react'
export interface ReactNodeViewContextProps {
onDragStart: (event: DragEvent) => void,
maybeMoveContentDOM: () => void,
nodeViewContentRef: (element: HTMLElement | null) => void,
}
export const ReactNodeViewContext = createContext<Partial<ReactNodeViewContextProps>>({