tiptap-extension-trailing-node
Version:
The extension adds an actual node to the tiptap content.
61 lines (50 loc) • 1.57 kB
JavaScript
import { Extension } from "@tiptap/core";
import { Plugin, PluginKey } from "@tiptap/pm/state";
function nodeEqualsType({ types, node }) {
return (
(Array.isArray(types) && types.includes(node.type)) || node.type === types
);
}
export default Extension.create({
name: "trailingNode",
addOptions() {
return {
node: "paragraph",
notAfter: ["paragraph"],
};
},
addProseMirrorPlugins() {
const plugin = new PluginKey(this.name);
const disabledNodes = Object.entries(this.editor.schema.nodes)
.map(([, value]) => value)
.filter((node) => this.options.notAfter.includes(node.name));
return [
new Plugin({
key: plugin,
appendTransaction: (_, __, state) => {
const { doc, tr, schema } = state;
const shouldInsertNodeAtEnd = plugin.getState(state);
const endPosition = doc.content.size;
const type = schema.nodes[this.options.node];
if (!shouldInsertNodeAtEnd) {
return;
}
return tr.insert(endPosition, type.create());
},
state: {
init: (_, state) => {
const lastNode = state.tr.doc.lastChild;
return !nodeEqualsType({ node: lastNode, types: disabledNodes });
},
apply: (tr, value) => {
if (!tr.docChanged) {
return value;
}
const lastNode = tr.doc.lastChild;
return !nodeEqualsType({ node: lastNode, types: disabledNodes });
},
},
}),
];
},
});