Skip to content

Commit 9c243b1

Browse files
Converted reactWrapInBlockStructure function to BlockContentWrapper component (#466)
1 parent 1416417 commit 9c243b1

File tree

1 file changed

+55
-49
lines changed

1 file changed

+55
-49
lines changed

packages/react/src/schema/ReactBlockSpec.tsx

Lines changed: 55 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
NodeViewWrapper,
2424
ReactNodeViewRenderer,
2525
} from "@tiptap/react";
26-
import { FC } from "react";
26+
import { FC, ReactNode } from "react";
2727
import { renderToDOMSpec } from "./@util/ReactRenderUtil";
2828

2929
// this file is mostly analogoues to `customBlocks.ts`, but for React blocks
@@ -52,46 +52,48 @@ export type ReactCustomBlockImplementation<
5252
// Function that wraps the React component returned from 'blockConfig.render' in
5353
// a `NodeViewWrapper` which also acts as a `blockContent` div. It contains the
5454
// block type and props as HTML attributes.
55-
export function reactWrapInBlockStructure<
55+
export function BlockContentWrapper<
5656
BType extends string,
5757
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 (
6666
// Creates `blockContent` element
6767
<NodeViewWrapper
6868
// Adds custom HTML attributes
6969
{...Object.fromEntries(
70-
Object.entries(domAttributes || {}).filter(([key]) => key !== "class")
70+
Object.entries(props.domAttributes || {}).filter(
71+
([key]) => key !== "class"
72+
)
7173
)}
7274
// Sets blockContent class
7375
className={mergeCSSClasses(
7476
"bn-block-content",
75-
domAttributes?.class || ""
77+
props.domAttributes?.class || ""
7678
)}
7779
// Sets content type attribute
78-
data-content-type={blockType}
80+
data-content-type={props.blockType}
7981
// Adds props as HTML attributes in kebab-case with "data-" prefix. Skips
8082
// props which are already added as HTML attributes to the parent
8183
// `blockContent` element (inheritedProps) and props set to their default
8284
// values
8385
{...Object.fromEntries(
84-
Object.entries(blockProps)
86+
Object.entries(props.blockProps)
8587
.filter(
8688
([prop, value]) =>
8789
!inheritedProps.includes(prop) &&
88-
value !== propSchema[prop].default
90+
value !== props.propSchema[prop].default
8991
)
9092
.map(([prop, value]) => {
9193
return [camelToDataKebab(prop), value];
9294
})
9395
)}>
94-
{element}
96+
{props.children}
9597
</NodeViewWrapper>
9698
);
9799
}
@@ -153,16 +155,20 @@ export function createReactBlockSpec<
153155
// hacky, should export `useReactNodeView` from tiptap to get access to ref
154156
const ref = (NodeViewContent({}) as any).ref;
155157

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>
163171
);
164-
165-
return <BlockContent />;
166172
},
167173
{
168174
className: "bn-react-node-view-renderer",
@@ -177,21 +183,20 @@ export function createReactBlockSpec<
177183
const blockContentDOMAttributes =
178184
node.options.domAttributes?.blockContent || {};
179185

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
184194
block={block as any}
185195
editor={editor as any}
186196
contentRef={refCB}
187-
/>,
188-
block.type,
189-
block.props,
190-
blockConfig.propSchema,
191-
blockContentDOMAttributes
192-
);
193-
return <BlockContent />;
194-
});
197+
/>
198+
</BlockContentWrapper>
199+
));
195200
output.contentDOM?.setAttribute("data-editable", "");
196201

197202
return output;
@@ -200,21 +205,22 @@ export function createReactBlockSpec<
200205
const blockContentDOMAttributes =
201206
node.options.domAttributes?.blockContent || {};
202207

203-
const Content =
208+
const BlockContent =
204209
blockImplementation.toExternalHTML || blockImplementation.render;
205210
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>
216223
);
217-
return <BlockContent />;
218224
});
219225
output.contentDOM?.setAttribute("data-editable", "");
220226

0 commit comments

Comments
 (0)