add useReactNodeView hook
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 (
|
||||
<div
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
import React from 'react'
|
||||
import { useReactNodeView } from './useReactNodeView'
|
||||
|
||||
export const NodeViewWrapper: React.FC = props => {
|
||||
|
||||
// TODO
|
||||
const onDragStart = () => {
|
||||
console.log('drag start')
|
||||
}
|
||||
// @ts-ignore
|
||||
const { onDragStart } = useReactNodeView()
|
||||
|
||||
return (
|
||||
<div
|
||||
data-node-view-wrapper=""
|
||||
// contentEditable={false}
|
||||
style={{
|
||||
whiteSpace: 'normal'
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { Node, NodeViewRenderer, NodeViewRendererProps } from '@tiptap/core'
|
||||
import { Decoration, NodeView } from 'prosemirror-view'
|
||||
import { NodeSelection } from 'prosemirror-state'
|
||||
import { Node as ProseMirrorNode } from 'prosemirror-model'
|
||||
import { Editor } from './Editor'
|
||||
import { ReactRenderer } from './ReactRenderer'
|
||||
import { ReactNodeViewContext } from './useReactNodeView'
|
||||
|
||||
interface ReactNodeViewRendererOptions {
|
||||
stopEvent: ((event: Event) => 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 (
|
||||
<ReactNodeViewContext.Provider
|
||||
value={{
|
||||
onDragStart,
|
||||
isEditable,
|
||||
}}
|
||||
>
|
||||
<Component {...props} />
|
||||
</ReactNodeViewContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
this.renderer = new ReactRenderer(ReactNodeView, {
|
||||
editor: this.editor,
|
||||
props,
|
||||
})
|
||||
8
packages/react/src/useReactNodeView.ts
Normal file
8
packages/react/src/useReactNodeView.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import React, { useContext } from 'react'
|
||||
|
||||
export const ReactNodeViewContext = React.createContext<any>({
|
||||
isEditable: undefined,
|
||||
onDragStart: undefined,
|
||||
})
|
||||
|
||||
export const useReactNodeView = () => useContext(ReactNodeViewContext)
|
||||
Reference in New Issue
Block a user