Insert custom node inline in current paragraph or header #4999
-
With the following Node import { mergeAttributes, Node } from '@tiptap/core';
import { ReactNodeViewRenderer } from '@tiptap/react';
import { EmbeddedPromptContainer } from './embedded-prompt-container';
export const EmbeddedPrompt = Node.create({
name: 'embeddedPrompt',
group: 'block',
content: 'inline*',
selectable: true,
parseHTML() {
return [
{
tag: 'react-component',
},
];
},
addKeyboardShortcuts() {
return {
'Mod-Enter': () => {
const { head } = this.editor.state.selection;
return this.editor
.chain()
.insertContent({
type: this.name,
})
.focus()
.run();
},
};
},
renderHTML({ HTMLAttributes }) {
return ['react-component', mergeAttributes(HTMLAttributes), 0];
},
addNodeView() {
return ReactNodeViewRenderer(EmbeddedPromptContainer, {
contentDOMElementTag: 'span',
className: 'inline-block',
});
},
}); But as you can see the react component is not being inserted inside the I would like something like this <p>I want <div class="custom-react-component"> this prompt to be inserted here </div> </p> EditSo I tried setting Edit 2I experimented with Marks too, this almost works but i don't want the user to have to highlight text in order to insert a prompt, they should be able to just hit a keyboard shortcut and have a prompt inserted |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Final updateI think a Mark is definetly what I was looking for. My one issue of
Can be resolved by having UI that is displayed when the mark is active, so its clear when they are inserting a prompt In other words a prompt is nothing different than regular text, just with a bit of different styling Perfect! Heres my draft implementation for those interested export const EmbeddedPrompt = Mark.create({
name: 'embeddedPrompt',
group: 'inline',
inclusive: true,
content: 'text*',
addOptions() {
return {
HTMLAttributes: {},
};
},
addKeyboardShortcuts() {
return {
'Mod-Enter': () => {
const { head } = this.editor.state.selection;
return this.editor.chain().toggleMark(this.name).run();
},
};
},
renderHTML({ HTMLAttributes }) {
return ['span', mergeAttributes(HTMLAttributes, { class: 'ai-prompt' }), 0];
},
parseHTML() {
return [{ tag: 'span.ai-prompt' }];
},
}); |
Beta Was this translation helpful? Give feedback.
Final update
I think a Mark is definetly what I was looking for. My one issue of
Can be resolved by having UI that is displayed when the mark is active, so its clear when they are inserting a prompt
In other words a prompt is nothing different than regular text, just with a bit of different styling
Perfect!
Heres my draft implementation for those interested