import { Node, mergeAttributes } from "@tiptap/core"; import { ReactNodeViewRenderer } from "@tiptap/react"; export interface DrawioOptions { HTMLAttributes: Record; view: any; } export interface DrawioAttributes { src?: string; title?: string; size?: number; width?: string; align?: string; attachmentId?: string; } declare module "@tiptap/core" { interface Commands { drawio: { setDrawio: (attributes?: DrawioAttributes) => ReturnType; }; } } export const Drawio = Node.create({ name: "drawio", inline: false, group: "block", isolating: true, atom: true, defining: true, draggable: true, addOptions() { return { HTMLAttributes: {}, view: null, }; }, addAttributes() { return { src: { default: '', parseHTML: (element) => element.getAttribute('data-src'), renderHTML: (attributes) => ({ 'data-src': attributes.src, }), }, title: { default: undefined, parseHTML: (element) => element.getAttribute('data-title'), renderHTML: (attributes: DrawioAttributes) => ({ 'data-title': attributes.title, }), }, width: { default: '100%', parseHTML: (element) => element.getAttribute('data-width'), renderHTML: (attributes: DrawioAttributes) => ({ 'data-width': attributes.width, }), }, size: { default: null, parseHTML: (element) => element.getAttribute('data-size'), renderHTML: (attributes: DrawioAttributes) => ({ 'data-size': attributes.size, }), }, align: { default: 'center', parseHTML: (element) => element.getAttribute('data-align'), renderHTML: (attributes: DrawioAttributes) => ({ 'data-align': attributes.align, }), }, attachmentId: { default: undefined, parseHTML: (element) => element.getAttribute('data-attachment-id'), renderHTML: (attributes: DrawioAttributes) => ({ 'data-attachment-id': attributes.attachmentId, }), }, }; }, parseHTML() { return [ { tag: `div[data-type="${this.name}"]`, }, ]; }, renderHTML({ HTMLAttributes }) { return [ 'div', mergeAttributes( { 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes ), ['img', { src: HTMLAttributes['data-src'], alt: HTMLAttributes['data-title'], width: HTMLAttributes['data-width'] }], ]; }, addCommands() { return { setDrawio: (attrs: DrawioAttributes) => ({ commands }) => { return commands.insertContent({ type: "drawio", attrs: attrs, }); }, }; }, addNodeView() { return ReactNodeViewRenderer(this.options.view); }, });