diff --git a/app/editor/menus/code.tsx b/app/editor/menus/code.tsx index efcfbc8702..fd1979b66b 100644 --- a/app/editor/menus/code.tsx +++ b/app/editor/menus/code.tsx @@ -48,6 +48,9 @@ export default function codeMenuItems( ] : remainingLangMenuItems; + const isEditingMermaid = !!(mermaidPluginKey.getState(state) as MermaidState) + ?.editingId; + return [ { name: "copyToClipboard", @@ -64,10 +67,7 @@ export default function codeMenuItems( name: "edit_mermaid", icon: , tooltip: dictionary.editDiagram, - visible: - !(mermaidPluginKey.getState(state) as MermaidState)?.editingId && - isMermaid(node) && - !readOnly, + visible: isMermaid(node) && !isEditingMermaid && !readOnly, }, { name: "separator", @@ -77,7 +77,7 @@ export default function codeMenuItems( icon: , tooltip: dictionary.wrapText, active: () => node.attrs.wrap, - visible: !readOnly, + visible: !readOnly && (!isMermaid(node) || isEditingMermaid), }, { name: "separator", diff --git a/package.json b/package.json index 39769cb83b..6b7508df34 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "@hocuspocus/server": "1.1.2", "@juggle/resize-observer": "^3.4.0", "@linear/sdk": "^58.1.0", + "@mermaid-js/layout-elk": "^0.2.0", "@modelcontextprotocol/sdk": "^1.25.1", "@node-oauth/oauth2-server": "^5.2.0", "@notionhq/client": "^2.3.0", diff --git a/server/models/helpers/ProsemirrorHelper.tsx b/server/models/helpers/ProsemirrorHelper.tsx index b2a08b2e72..37e8576fbb 100644 --- a/server/models/helpers/ProsemirrorHelper.tsx +++ b/server/models/helpers/ProsemirrorHelper.tsx @@ -583,6 +583,8 @@ export class ProsemirrorHelper { if (mermaidElements.length) { element.innerHTML = ` import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs'; + import elkLayouts from 'https://cdn.jsdelivr.net/npm/@mermaid-js/layout-elk/dist/mermaid-layout-elk.esm.min.mjs'; + mermaid.registerLayoutLoaders(elkLayouts); mermaid.initialize({ startOnLoad: true, fontFamily: "inherit", diff --git a/shared/editor/extensions/Mermaid.ts b/shared/editor/extensions/Mermaid.ts index e3e9c53018..52c6a6640a 100644 --- a/shared/editor/extensions/Mermaid.ts +++ b/shared/editor/extensions/Mermaid.ts @@ -84,7 +84,25 @@ class MermaidRenderer { document.body.appendChild(renderElement); try { - mermaid ??= (await import("mermaid")).default; + if (!mermaid) { + mermaid = (await import("mermaid")).default; + mermaid.registerLayoutLoaders([ + { + name: "elk", + loader: async () => { + const { default: elkLayouts } = + await import("@mermaid-js/layout-elk"); + const elkDef = elkLayouts.find( + (d: { name: string }) => d.name === "elk" + ); + if (!elkDef) { + throw new Error("ELK layout not found"); + } + return elkDef.loader(); + }, + }, + ]); + } mermaid.initialize({ startOnLoad: true, suppressErrorRendering: true, diff --git a/vite.config.ts b/vite.config.ts index 93697d5569..c74789054b 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -190,6 +190,11 @@ export default () => test: /node_modules[\\/]styled-components/, priority: 20, }, + { + name: "vendor-mermaid-elk", + test: /node_modules[\\/](@mermaid-js[\\/]layout-elk|elkjs)/, + priority: 25, + }, { name: "vendor-mermaid", test: /node_modules[\\/](mermaid|cytoscape|cytoscape-fcose|layout-base|dagre-d3-es|langium|chevrotain|roughjs|@mermaid-js)/, diff --git a/yarn.lock b/yarn.lock index 9bd7c72697..3300d8e40a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4394,6 +4394,18 @@ __metadata: languageName: node linkType: hard +"@mermaid-js/layout-elk@npm:^0.2.0": + version: 0.2.0 + resolution: "@mermaid-js/layout-elk@npm:0.2.0" + dependencies: + d3: "npm:^7.9.0" + elkjs: "npm:^0.9.3" + peerDependencies: + mermaid: ^11.0.2 + checksum: 10c0/d4938770adc669dd7e271aa0688838c9c1ff47c75479ab0385dc51c7a4e5e5fc1df3ea9913c1493709b4640fd50064db181a42c1b36d005f20cb8e2537570b29 + languageName: node + linkType: hard + "@mermaid-js/parser@npm:^0.6.3": version: 0.6.3 resolution: "@mermaid-js/parser@npm:0.6.3" @@ -12009,6 +12021,13 @@ __metadata: languageName: node linkType: hard +"elkjs@npm:^0.9.3": + version: 0.9.3 + resolution: "elkjs@npm:0.9.3" + checksum: 10c0/caf544ff4fce8442d1d3dd6dface176c9b2fe26fc1e34f56122828e6eef7d2d7fe70d3202f9f3ecf0feb6287d4c8430949f483e63e450a7454bb39ccffab3808 + languageName: node + linkType: hard + "email-providers@npm:^1.14.0": version: 1.14.0 resolution: "email-providers@npm:1.14.0" @@ -17556,6 +17575,7 @@ __metadata: "@hocuspocus/server": "npm:1.1.2" "@juggle/resize-observer": "npm:^3.4.0" "@linear/sdk": "npm:^58.1.0" + "@mermaid-js/layout-elk": "npm:^0.2.0" "@modelcontextprotocol/sdk": "npm:^1.25.1" "@node-oauth/oauth2-server": "npm:^5.2.0" "@notionhq/client": "npm:^2.3.0"