feat: draw.io (diagrams.net) integration (#215)

* draw.io init

* updates
This commit is contained in:
Philip Okugbe
2024-09-01 12:26:20 +01:00
committed by GitHub
parent 38e9eef2dc
commit 87b99f8646
14 changed files with 555 additions and 110 deletions

View File

@ -11,5 +11,7 @@ export * from "./lib/media-utils";
export * from "./lib/link";
export * from "./lib/selection";
export * from "./lib/attachment";
export * from "./lib/custom-code-block";
export * from "./lib/custom-code-block"
export * from "./lib/drawio";
export * from "./lib/excalidraw";

View File

@ -0,0 +1,124 @@
import { Node, mergeAttributes } from "@tiptap/core";
import { ReactNodeViewRenderer } from "@tiptap/react";
export interface DrawioOptions {
HTMLAttributes: Record<string, any>;
view: any;
}
export interface DrawioAttributes {
src?: string;
title?: string;
size?: number;
width?: string;
align?: string;
attachmentId?: string;
}
declare module "@tiptap/core" {
interface Commands<ReturnType> {
drawio: {
setDrawio: (attributes?: DrawioAttributes) => ReturnType;
};
}
}
export const Drawio = Node.create<DrawioOptions>({
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);
},
});