Skip to content

Commit 9a741d7

Browse files
Added parameter for updating custom inline content in render (#1080)
1 parent 6f66926 commit 9a741d7

File tree

2 files changed

+84
-8
lines changed

2 files changed

+84
-8
lines changed

packages/core/src/schema/inlineContent/createSpec.ts

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { Node } from "@tiptap/core";
22
import { TagParseRule } from "@tiptap/pm/model";
3-
import { nodeToCustomInlineContent } from "../../api/nodeConversions/nodeConversions";
3+
import {
4+
inlineContentToNodes,
5+
nodeToCustomInlineContent,
6+
} from "../../api/nodeConversions/nodeConversions";
47
import { propsToAttributes } from "../blocks/internal";
58
import { Props } from "../propTypes";
69
import { StyleSchema } from "../styles/types";
@@ -11,15 +14,15 @@ import {
1114
} from "./internal";
1215
import {
1316
CustomInlineContentConfig,
14-
InlineContentConfig,
1517
InlineContentFromConfig,
1618
InlineContentSpec,
19+
PartialCustomInlineContentFromConfig,
1720
} from "./types";
1821

1922
// TODO: support serialization
2023

2124
export type CustomInlineContentImplementation<
22-
T extends InlineContentConfig,
25+
T extends CustomInlineContentConfig,
2326
// B extends BlockSchema,
2427
// I extends InlineContentSchema,
2528
S extends StyleSchema
@@ -28,7 +31,10 @@ export type CustomInlineContentImplementation<
2831
/**
2932
* The custom inline content to render
3033
*/
31-
inlineContent: InlineContentFromConfig<T, S>
34+
inlineContent: InlineContentFromConfig<T, S>,
35+
updateInlineContent: (
36+
update: PartialCustomInlineContentFromConfig<T, S>
37+
) => void
3238
/**
3339
* The BlockNote editor instance
3440
* This is typed generically. If you want an editor with your custom schema, you need to
@@ -100,7 +106,10 @@ export function createInlineContentSpec<
100106
node,
101107
editor.schema.inlineContentSchema,
102108
editor.schema.styleSchema
103-
) as any as InlineContentFromConfig<T, S> // TODO: fix cast
109+
) as any as InlineContentFromConfig<T, S>, // TODO: fix cast
110+
() => {
111+
// No-op
112+
}
104113
);
105114

106115
return addInlineContentAttributes(
@@ -110,6 +119,46 @@ export function createInlineContentSpec<
110119
inlineContentConfig.propSchema
111120
);
112121
},
122+
123+
addNodeView() {
124+
return ({ node, getPos }) => {
125+
const editor = this.options.editor;
126+
127+
const output = inlineContentImplementation.render(
128+
nodeToCustomInlineContent(
129+
node,
130+
editor.schema.inlineContentSchema,
131+
editor.schema.styleSchema
132+
) as any as InlineContentFromConfig<T, S>, // TODO: fix cast
133+
(update) => {
134+
if (typeof getPos === "boolean") {
135+
return;
136+
}
137+
138+
const content = inlineContentToNodes(
139+
[update],
140+
editor._tiptapEditor.schema,
141+
editor.schema.styleSchema
142+
);
143+
144+
editor._tiptapEditor.view.dispatch(
145+
editor._tiptapEditor.view.state.tr.replaceWith(
146+
getPos(),
147+
getPos() + node.nodeSize,
148+
content
149+
)
150+
);
151+
}
152+
);
153+
154+
return addInlineContentAttributes(
155+
output,
156+
inlineContentConfig.type,
157+
node.attrs as Props<T["propSchema"]>,
158+
inlineContentConfig.propSchema
159+
);
160+
};
161+
},
113162
});
114163

115164
return createInlineContentSpecFromTipTapNode(

packages/react/src/schema/ReactInlineContentSpec.tsx

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ import {
66
createStronglyTypedTiptapNode,
77
CustomInlineContentConfig,
88
getInlineContentParseRules,
9-
InlineContentConfig,
109
InlineContentFromConfig,
10+
inlineContentToNodes,
1111
nodeToCustomInlineContent,
12+
PartialCustomInlineContentFromConfig,
1213
Props,
1314
PropSchema,
1415
propsToAttributes,
@@ -28,12 +29,15 @@ import { renderToDOMSpec } from "./@util/ReactRenderUtil";
2829

2930
// extend BlockConfig but use a React render function
3031
export type ReactInlineContentImplementation<
31-
T extends InlineContentConfig,
32+
T extends CustomInlineContentConfig,
3233
// I extends InlineContentSchema,
3334
S extends StyleSchema
3435
> = {
3536
render: FC<{
3637
inlineContent: InlineContentFromConfig<T, S>;
38+
updateInlineContent: (
39+
update: PartialCustomInlineContentFromConfig<T, S>
40+
) => void;
3741
contentRef: (node: HTMLElement | null) => void;
3842
}>;
3943
// TODO?
@@ -119,7 +123,15 @@ export function createReactInlineContentSpec<
119123
) as any as InlineContentFromConfig<T, S>; // TODO: fix cast
120124
const Content = inlineContentImplementation.render;
121125
const output = renderToDOMSpec(
122-
(refCB) => <Content inlineContent={ic} contentRef={refCB} />,
126+
(refCB) => (
127+
<Content
128+
inlineContent={ic}
129+
updateInlineContent={() => {
130+
// No-op
131+
}}
132+
contentRef={refCB}
133+
/>
134+
),
123135
editor
124136
);
125137

@@ -155,6 +167,21 @@ export function createReactInlineContentSpec<
155167
editor.schema.styleSchema
156168
) as any as InlineContentFromConfig<T, S> // TODO: fix cast
157169
}
170+
updateInlineContent={(update) => {
171+
const content = inlineContentToNodes(
172+
[update],
173+
editor._tiptapEditor.schema,
174+
editor.schema.styleSchema
175+
);
176+
177+
editor._tiptapEditor.view.dispatch(
178+
editor._tiptapEditor.view.state.tr.replaceWith(
179+
props.getPos(),
180+
props.getPos() + props.node.nodeSize,
181+
content
182+
)
183+
);
184+
}}
158185
/>
159186
</InlineContentWrapper>
160187
);

0 commit comments

Comments
 (0)