@@ -23,7 +23,7 @@ import {
23
23
NodeViewWrapper ,
24
24
ReactNodeViewRenderer ,
25
25
} from "@tiptap/react" ;
26
- import { FC } from "react" ;
26
+ import { FC , ReactNode } from "react" ;
27
27
import { renderToDOMSpec } from "./@util/ReactRenderUtil" ;
28
28
29
29
// this file is mostly analogoues to `customBlocks.ts`, but for React blocks
@@ -52,46 +52,48 @@ export type ReactCustomBlockImplementation<
52
52
// Function that wraps the React component returned from 'blockConfig.render' in
53
53
// a `NodeViewWrapper` which also acts as a `blockContent` div. It contains the
54
54
// block type and props as HTML attributes.
55
- export function reactWrapInBlockStructure <
55
+ export function BlockContentWrapper <
56
56
BType extends string ,
57
57
PSchema extends PropSchema
58
- > (
59
- element : JSX . Element ,
60
- blockType : BType ,
61
- blockProps : Props < PSchema > ,
62
- propSchema : PSchema ,
63
- domAttributes ?: Record < string , string >
64
- ) {
65
- return ( ) => (
58
+ > ( props : {
59
+ blockType : BType ;
60
+ blockProps : Props < PSchema > ;
61
+ propSchema : PSchema ;
62
+ domAttributes ?: Record < string , string > ;
63
+ children : ReactNode ;
64
+ } ) {
65
+ return (
66
66
// Creates `blockContent` element
67
67
< NodeViewWrapper
68
68
// Adds custom HTML attributes
69
69
{ ...Object . fromEntries (
70
- Object . entries ( domAttributes || { } ) . filter ( ( [ key ] ) => key !== "class" )
70
+ Object . entries ( props . domAttributes || { } ) . filter (
71
+ ( [ key ] ) => key !== "class"
72
+ )
71
73
) }
72
74
// Sets blockContent class
73
75
className = { mergeCSSClasses (
74
76
"bn-block-content" ,
75
- domAttributes ?. class || ""
77
+ props . domAttributes ?. class || ""
76
78
) }
77
79
// Sets content type attribute
78
- data-content-type = { blockType }
80
+ data-content-type = { props . blockType }
79
81
// Adds props as HTML attributes in kebab-case with "data-" prefix. Skips
80
82
// props which are already added as HTML attributes to the parent
81
83
// `blockContent` element (inheritedProps) and props set to their default
82
84
// values
83
85
{ ...Object . fromEntries (
84
- Object . entries ( blockProps )
86
+ Object . entries ( props . blockProps )
85
87
. filter (
86
88
( [ prop , value ] ) =>
87
89
! inheritedProps . includes ( prop ) &&
88
- value !== propSchema [ prop ] . default
90
+ value !== props . propSchema [ prop ] . default
89
91
)
90
92
. map ( ( [ prop , value ] ) => {
91
93
return [ camelToDataKebab ( prop ) , value ] ;
92
94
} )
93
95
) } >
94
- { element }
96
+ { props . children }
95
97
</ NodeViewWrapper >
96
98
) ;
97
99
}
@@ -153,16 +155,20 @@ export function createReactBlockSpec<
153
155
// hacky, should export `useReactNodeView` from tiptap to get access to ref
154
156
const ref = ( NodeViewContent ( { } ) as any ) . ref ;
155
157
156
- const Content = blockImplementation . render ;
157
- const BlockContent = reactWrapInBlockStructure (
158
- < Content block = { block } editor = { editor as any } contentRef = { ref } /> ,
159
- block . type ,
160
- block . props ,
161
- blockConfig . propSchema ,
162
- blockContentDOMAttributes
158
+ const BlockContent = blockImplementation . render ;
159
+ return (
160
+ < BlockContentWrapper
161
+ blockType = { block . type }
162
+ blockProps = { block . props }
163
+ propSchema = { blockConfig . propSchema }
164
+ domAttributes = { blockContentDOMAttributes } >
165
+ < BlockContent
166
+ block = { block as any }
167
+ editor = { editor as any }
168
+ contentRef = { ref }
169
+ />
170
+ </ BlockContentWrapper >
163
171
) ;
164
-
165
- return < BlockContent /> ;
166
172
} ,
167
173
{
168
174
className : "bn-react-node-view-renderer" ,
@@ -177,21 +183,20 @@ export function createReactBlockSpec<
177
183
const blockContentDOMAttributes =
178
184
node . options . domAttributes ?. blockContent || { } ;
179
185
180
- const Content = blockImplementation . render ;
181
- const output = renderToDOMSpec ( ( refCB ) => {
182
- const BlockContent = reactWrapInBlockStructure (
183
- < Content
186
+ const BlockContent = blockImplementation . render ;
187
+ const output = renderToDOMSpec ( ( refCB ) => (
188
+ < BlockContentWrapper
189
+ blockType = { block . type }
190
+ blockProps = { block . props }
191
+ propSchema = { blockConfig . propSchema }
192
+ domAttributes = { blockContentDOMAttributes } >
193
+ < BlockContent
184
194
block = { block as any }
185
195
editor = { editor as any }
186
196
contentRef = { refCB }
187
- /> ,
188
- block . type ,
189
- block . props ,
190
- blockConfig . propSchema ,
191
- blockContentDOMAttributes
192
- ) ;
193
- return < BlockContent /> ;
194
- } ) ;
197
+ />
198
+ </ BlockContentWrapper >
199
+ ) ) ;
195
200
output . contentDOM ?. setAttribute ( "data-editable" , "" ) ;
196
201
197
202
return output ;
@@ -200,21 +205,22 @@ export function createReactBlockSpec<
200
205
const blockContentDOMAttributes =
201
206
node . options . domAttributes ?. blockContent || { } ;
202
207
203
- const Content =
208
+ const BlockContent =
204
209
blockImplementation . toExternalHTML || blockImplementation . render ;
205
210
const output = renderToDOMSpec ( ( refCB ) => {
206
- const BlockContent = reactWrapInBlockStructure (
207
- < Content
208
- block = { block as any }
209
- editor = { editor as any }
210
- contentRef = { refCB }
211
- /> ,
212
- block . type ,
213
- block . props ,
214
- blockConfig . propSchema ,
215
- blockContentDOMAttributes
211
+ return (
212
+ < BlockContentWrapper
213
+ blockType = { block . type }
214
+ blockProps = { block . props }
215
+ propSchema = { blockConfig . propSchema }
216
+ domAttributes = { blockContentDOMAttributes } >
217
+ < BlockContent
218
+ block = { block as any }
219
+ editor = { editor as any }
220
+ contentRef = { refCB }
221
+ />
222
+ </ BlockContentWrapper >
216
223
) ;
217
- return < BlockContent /> ;
218
224
} ) ;
219
225
output . contentDOM ?. setAttribute ( "data-editable" , "" ) ;
220
226
0 commit comments