|
|
|
@@ -0,0 +1,82 @@
|
|
|
|
|
import ErrorBoundary from '@docusaurus/ErrorBoundary';
|
|
|
|
|
import { ErrorBoundaryErrorMessageFallback } from '@docusaurus/theme-common';
|
|
|
|
|
import { useColorMode } from '@docusaurus/theme-common';
|
|
|
|
|
import {
|
|
|
|
|
MermaidContainerClassName,
|
|
|
|
|
useMermaidConfig,
|
|
|
|
|
useMermaidRenderResult,
|
|
|
|
|
} from '@docusaurus/theme-mermaid/client';
|
|
|
|
|
import type { Props } from '@theme/Mermaid';
|
|
|
|
|
import type { RenderResult } from 'mermaid';
|
|
|
|
|
import React, { useRef, useEffect, useMemo, type ReactNode } from 'react';
|
|
|
|
|
|
|
|
|
|
import styles from './styles.module.css';
|
|
|
|
|
|
|
|
|
|
const NORD_THEME_VARIABLES = {
|
|
|
|
|
background: '#2e3440',
|
|
|
|
|
mainBkg: '#3b4252',
|
|
|
|
|
primaryColor: '#5e81ac',
|
|
|
|
|
primaryTextColor: '#eceff4',
|
|
|
|
|
primaryBorderColor: '#88c0d0',
|
|
|
|
|
secondaryColor: '#434c5e',
|
|
|
|
|
secondaryTextColor: '#d8dee9',
|
|
|
|
|
secondaryBorderColor: '#4c566a',
|
|
|
|
|
tertiaryColor: '#3b4252',
|
|
|
|
|
tertiaryTextColor: '#d8dee9',
|
|
|
|
|
tertiaryBorderColor: '#4c566a',
|
|
|
|
|
lineColor: '#88c0d0',
|
|
|
|
|
edgeLabelBackground: '#434c5e',
|
|
|
|
|
textColor: '#eceff4',
|
|
|
|
|
titleColor: '#88c0d0',
|
|
|
|
|
nodeBorder: '#4c566a',
|
|
|
|
|
clusterBkg: '#434c5e',
|
|
|
|
|
clusterBorder: '#4c566a',
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function MermaidRenderResult({ renderResult }: { renderResult: RenderResult }): ReactNode {
|
|
|
|
|
const ref = useRef<HTMLDivElement>(null);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const div = ref.current!;
|
|
|
|
|
|
|
|
|
|
renderResult.bindFunctions?.(div);
|
|
|
|
|
}, [renderResult]);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div
|
|
|
|
|
ref={ref}
|
|
|
|
|
className={`${MermaidContainerClassName} ${styles.container}`}
|
|
|
|
|
// eslint-disable-next-line react/no-danger -- mermaid renders trusted SVG
|
|
|
|
|
dangerouslySetInnerHTML={{ __html: renderResult.svg }}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function MermaidRenderer({ value }: Props): ReactNode {
|
|
|
|
|
const { colorMode } = useColorMode();
|
|
|
|
|
const baseConfig = useMermaidConfig();
|
|
|
|
|
|
|
|
|
|
const config = useMemo(
|
|
|
|
|
() =>
|
|
|
|
|
colorMode === 'dark'
|
|
|
|
|
? { ...baseConfig, themeVariables: NORD_THEME_VARIABLES }
|
|
|
|
|
: baseConfig,
|
|
|
|
|
[colorMode, baseConfig],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const renderResult = useMermaidRenderResult({ text: value, config });
|
|
|
|
|
|
|
|
|
|
if (renderResult === null) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return <MermaidRenderResult renderResult={renderResult} />;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default function Mermaid(props: Props): ReactNode {
|
|
|
|
|
return (
|
|
|
|
|
<ErrorBoundary fallback={(params) => <ErrorBoundaryErrorMessageFallback {...params} />}>
|
|
|
|
|
<MermaidRenderer {...props} />
|
|
|
|
|
</ErrorBoundary>
|
|
|
|
|
);
|
|
|
|
|
}
|