diff --git a/src/client/mermaid.tsx b/src/client/mermaid.tsx index ea9acef..d2d3b38 100644 --- a/src/client/mermaid.tsx +++ b/src/client/mermaid.tsx @@ -48,6 +48,10 @@ function configureMermaid(): void { // forcing pure SVG text keeps labels visible and the HTML label channel // closed (strict already escapes label content). htmlLabels: false, + // Mermaid 11 renders a large error SVG into document.body before rejecting + // invalid diagrams. The component already has its own error fallback, so + // suppress that global side effect to keep the DSH shell intact. + suppressErrorRendering: true, theme: isDarkScheme() ? 'dark' : 'default', }) } diff --git a/tests/mermaid-markdown.spec.tsx b/tests/mermaid-markdown.spec.tsx index 6d0082f..f5e3f37 100644 --- a/tests/mermaid-markdown.spec.tsx +++ b/tests/mermaid-markdown.spec.tsx @@ -16,13 +16,14 @@ import { act } from 'react-dom/test-utils' vi.mock('mermaid', () => ({ default: { - initialize: () => {}, + initialize: vi.fn(), render: async () => ({ svg: 'MOCK-DIAGRAM', }), }, })) +import mermaid from 'mermaid' import { MermaidMarkdown } from '../src/client/mermaid.tsx' const codeLabels = { copyLabel: 'Copy', copiedLabel: 'Copied' } @@ -56,6 +57,15 @@ describe('MermaidMarkdown', () => { await unmount(root) }) + it('suppresses Mermaid global error rendering', async () => { + vi.mocked(mermaid.initialize).mockClear() + const { root } = await renderMarkdown('```mermaid\ngraph TD\n A-->B\n```') + expect(mermaid.initialize).toHaveBeenCalledWith(expect.objectContaining({ + suppressErrorRendering: true, + })) + await unmount(root) + }) + it('resolves cross-fence reference-style links (single markdown parse)', async () => { const text = [ '[before][shared]',