diff --git a/docs/src/demos/Examples/Default/React/index.jsx b/docs/src/demos/Examples/Default/React/index.jsx index e7e6a894..e8d984b0 100644 --- a/docs/src/demos/Examples/Default/React/index.jsx +++ b/docs/src/demos/Examples/Default/React/index.jsx @@ -135,7 +135,6 @@ export default () => { draggable: true, addNodeView() { return ReactNodeViewRenderer((props) => { - // console.log({props}) return (
@@ -156,7 +155,6 @@ export default () => { }) } }), - ], content: `

heading

@@ -197,6 +195,10 @@ export default () => { return (
+
+ + +
diff --git a/packages/react/src/EditorContent.tsx b/packages/react/src/EditorContent.tsx index 537c493e..93029683 100644 --- a/packages/react/src/EditorContent.tsx +++ b/packages/react/src/EditorContent.tsx @@ -2,6 +2,7 @@ import React from 'react' import ReactDOM from 'react-dom' import { Editor } from './Editor' import { ReactRenderer } from './ReactRenderer' +import { ReactNodeViewContext } from './useReactNodeView' type EditorContentProps = { editor: Editor | null diff --git a/packages/react/src/NodeViewContent.tsx b/packages/react/src/NodeViewContent.tsx index 1a7eeb98..ad205bac 100644 --- a/packages/react/src/NodeViewContent.tsx +++ b/packages/react/src/NodeViewContent.tsx @@ -1,9 +1,10 @@ import React from 'react' +import { useReactNodeView } from './useReactNodeView' export const NodeViewContent: React.FC = props => { - // TODO - const isEditable = true + // @ts-ignore + const { isEditable } = useReactNodeView() return (
{ - // TODO - const onDragStart = () => { - console.log('drag start') - } + // @ts-ignore + const { onDragStart } = useReactNodeView() return (
boolean) | null, @@ -40,7 +42,24 @@ class ReactNodeView implements NodeView { this.mount(component) } - mount(component: any) { + onDragStart(event: DragEvent) { + const { view } = this.editor + const target = (event.target as HTMLElement) + + if (this.contentDOM?.contains(target)) { + return + } + + // sometimes `event.target` is not the `dom` element + event.dataTransfer?.setDragImage(this.dom, 0, 0) + + const selection = NodeSelection.create(view.state.doc, this.getPos()) + const transaction = view.state.tr.setSelection(selection) + + view.dispatch(transaction) + } + + mount(Component: any) { const props = { editor: this.editor, node: this.node, @@ -51,11 +70,44 @@ class ReactNodeView implements NodeView { updateAttributes: (attributes = {}) => this.updateAttributes(attributes), } - if (!component.displayName) { - component.displayName = this.extension.config.name + if (!Component.displayName) { + const capitalizeFirstChar = (string: string): string => { + return string.charAt(0).toUpperCase() + string.substring(1) + } + + Component.displayName = capitalizeFirstChar(this.extension.config.name) } - this.renderer = new ReactRenderer(component, { + const ReactNodeView: React.FC = (props) => { + const [isEditable, setIsEditable] = useState(this.editor.isEditable) + + const handleEditableChange = () => { + setIsEditable(this.editor.isEditable) + } + + const onDragStart = this.onDragStart.bind(this) + + useEffect(() => { + this.editor.on('viewUpdate', handleEditableChange) + + return () => { + this.editor.off('viewUpdate', handleEditableChange) + } + }, []) + + return ( + + + + ) + } + + this.renderer = new ReactRenderer(ReactNodeView, { editor: this.editor, props, }) diff --git a/packages/react/src/useReactNodeView.ts b/packages/react/src/useReactNodeView.ts new file mode 100644 index 00000000..0225a201 --- /dev/null +++ b/packages/react/src/useReactNodeView.ts @@ -0,0 +1,8 @@ +import React, { useContext } from 'react' + +export const ReactNodeViewContext = React.createContext({ + isEditable: undefined, + onDragStart: undefined, +}) + +export const useReactNodeView = () => useContext(ReactNodeViewContext)