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
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' import { useReactNodeView } from './useReactNodeView'
export interface NodeViewContentProps { export interface NodeViewContentProps {
@@ -6,18 +6,14 @@ export interface NodeViewContentProps {
as?: React.ElementType, 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 Tag = props.as || 'div'
const { maybeMoveContentDOM } = useReactNodeView() const { nodeViewContentRef } = useReactNodeView()
useEffect(() => {
maybeMoveContentDOM?.()
}, [])
return ( return (
<Tag <Tag
{...props} {...props}
ref={ref} ref={nodeViewContentRef}
data-node-view-content="" data-node-view-content=""
style={{ style={{
...props.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 { Node as ProseMirrorNode } from 'prosemirror-model'
import { Editor } from './Editor' import { Editor } from './Editor'
import { ReactRenderer } from './ReactRenderer' import { ReactRenderer } from './ReactRenderer'
import { ReactNodeViewContext } from './useReactNodeView' import { ReactNodeViewContext, ReactNodeViewContextProps } from './useReactNodeView'
export interface ReactNodeViewRendererOptions extends NodeViewRendererOptions { export interface ReactNodeViewRendererOptions extends NodeViewRendererOptions {
update: ((props: { update: ((props: {
@@ -49,12 +49,20 @@ class ReactNodeView extends NodeView<React.FunctionComponent, Editor, ReactNodeV
} }
const ReactNodeViewProvider: React.FunctionComponent = componentProps => { const ReactNodeViewProvider: React.FunctionComponent = componentProps => {
const onDragStart = this.onDragStart.bind(this)
const maybeMoveContentDOM = this.maybeMoveContentDOM.bind(this)
const Component = this.component 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 ( return (
<ReactNodeViewContext.Provider value={{ onDragStart, maybeMoveContentDOM }}> <ReactNodeViewContext.Provider value={{ onDragStart, nodeViewContentRef }}>
<Component {...componentProps} /> <Component {...componentProps} />
</ReactNodeViewContext.Provider> </ReactNodeViewContext.Provider>
) )
@@ -98,27 +106,12 @@ class ReactNodeView extends NodeView<React.FunctionComponent, Editor, ReactNodeV
return null return null
} }
this.maybeMoveContentDOM()
return this.contentDOMElement 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[]) { update(node: ProseMirrorNode, decorations: Decoration[]) {
const updateProps = (props?: Record<string, any>) => { const updateProps = (props?: Record<string, any>) => {
this.renderer.updateProps(props) this.renderer.updateProps(props)
this.maybeMoveContentDOM()
} }
if (typeof this.options.update === 'function') { if (typeof this.options.update === 'function') {

View File

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