diff --git a/core/README.md b/core/README.md index 75b1e2fa..9064c71a 100644 --- a/core/README.md +++ b/core/README.md @@ -180,6 +180,75 @@ export default function Demo() { Ignored content ``` +## Support Custom Mermaid Preview + +```jsx mdx:preview?background=#fff +import React, { useState, useRef, useId, useEffect, Fragment, useCallback } from "react"; +import MarkdownPreview from '@uiw/react-markdown-preview'; +import { getCodeString } from 'rehype-rewrite'; +import mermaid from "mermaid"; + +const randomid = () => parseInt(String(Math.random() * 1e15), 10).toString(36); +const Code = ({ inline, children = [], className, ...props }) => { + const demoid = useRef(`dome${randomid()}`); + const [container, setContainer] = useState(null); + const isMermaid = className && /^language-mermaid/.test(className.toLocaleLowerCase()); + const code = props.node && props.node.children ? getCodeString(props.node.children) : children[0] || ''; + + const reRender = async () => { + if (container && isMermaid) { + try { + const str = await mermaid.render(demoid.current, code); + container.innerHTML = str.svg; + } catch (error) { + container.innerHTML = error; + } + } + } + + useEffect(() => { + reRender() + }, [container, isMermaid, code, demoid]); + + const refElement = useCallback((node) => { + if (node !== null) { + setContainer(node); + } + }, []); + + if (isMermaid) { + return ( + + + + + ); + } + return {children}; +}; + +const source = ` +\`\`\`mermaid +graph TD; + A-->B; + A-->C; + B-->D; + C-->D; +\`\`\` +`; + +export default function Demo() { + return ( + + ); +} +``` + ### Options Props ```typescript diff --git a/website/package.json b/website/package.json index 4749cfd7..93716885 100644 --- a/website/package.json +++ b/website/package.json @@ -9,6 +9,7 @@ "dependencies": { "@uiw/react-markdown-preview-example": "^1.5.5", "@uiw/react-shields": "^1.1.3", + "mermaid": "^10.4.0", "react": "~18.2.0", "react-dom": "~18.2.0", "react-router-dom": "^6.8.1"