From 54ee20f74c466fbda18e08e47c7fd2048df563db Mon Sep 17 00:00:00 2001 From: Samuel Wall Date: Tue, 24 May 2022 15:23:36 +0000 Subject: [PATCH 01/28] feat: add mermaid diagram support ootb #1258 --- packages/docusaurus-mdx-loader/package.json | 1 + packages/docusaurus-mdx-loader/src/loader.ts | 3 +- .../remark/mermaid/__tests__/index.test.ts | 62 ++ .../src/remark/mermaid/index.ts | 48 ++ .../docusaurus-theme-classic/package.json | 2 + .../src/theme-classic.d.ts | 22 + .../src/theme/Layout/index.tsx | 2 + .../src/theme/MDXComponents/Mermaid.tsx | 14 + .../src/theme/MDXComponents/index.tsx | 2 + .../src/theme/Mermaid/index.tsx | 64 ++ .../src/theme/useMermaid.tsx | 95 +++ .../src/utils/useThemeConfig.ts | 11 + project-words.txt | 4 + .../_dogfooding/_docs tests/tests/diagrams.md | 256 ++++++++ website/community/2-resources.md | 1 - .../markdown-features-diagrams.mdx | 68 ++ website/sidebars.js | 1 + yarn.lock | 600 +++++++++++++++++- 18 files changed, 1246 insertions(+), 10 deletions(-) create mode 100644 packages/docusaurus-mdx-loader/src/remark/mermaid/__tests__/index.test.ts create mode 100644 packages/docusaurus-mdx-loader/src/remark/mermaid/index.ts create mode 100644 packages/docusaurus-theme-classic/src/theme/MDXComponents/Mermaid.tsx create mode 100644 packages/docusaurus-theme-classic/src/theme/Mermaid/index.tsx create mode 100644 packages/docusaurus-theme-classic/src/theme/useMermaid.tsx create mode 100644 website/_dogfooding/_docs tests/tests/diagrams.md create mode 100644 website/docs/guides/markdown-features/markdown-features-diagrams.mdx diff --git a/packages/docusaurus-mdx-loader/package.json b/packages/docusaurus-mdx-loader/package.json index b071b9732ba3..5c08ef02f042 100644 --- a/packages/docusaurus-mdx-loader/package.json +++ b/packages/docusaurus-mdx-loader/package.json @@ -39,6 +39,7 @@ "@docusaurus/types": "2.0.0-beta.20", "@types/escape-html": "^1.0.2", "@types/mdast": "^3.0.10", + "@types/mermaid": "^8.2.9", "@types/stringify-object": "^3.3.1", "@types/unist": "^2.0.6", "remark": "^12.0.1", diff --git a/packages/docusaurus-mdx-loader/src/loader.ts b/packages/docusaurus-mdx-loader/src/loader.ts index 638a62566724..6b0fe69b46e0 100644 --- a/packages/docusaurus-mdx-loader/src/loader.ts +++ b/packages/docusaurus-mdx-loader/src/loader.ts @@ -22,6 +22,7 @@ import toc from './remark/toc'; import unwrapMdxCodeBlocks from './remark/unwrapMdxCodeBlocks'; import transformImage from './remark/transformImage'; import transformLinks from './remark/transformLinks'; +import mermaid from './remark/mermaid'; import type {LoaderContext} from 'webpack'; import type {Processor, Plugin} from 'unified'; @@ -38,7 +39,7 @@ const pragma = ` const DEFAULT_OPTIONS: MDXOptions = { rehypePlugins: [], - remarkPlugins: [unwrapMdxCodeBlocks, emoji, headings, toc], + remarkPlugins: [unwrapMdxCodeBlocks, emoji, headings, toc, mermaid], beforeDefaultRemarkPlugins: [], beforeDefaultRehypePlugins: [], }; diff --git a/packages/docusaurus-mdx-loader/src/remark/mermaid/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/mermaid/__tests__/index.test.ts new file mode 100644 index 000000000000..abadf6e6445c --- /dev/null +++ b/packages/docusaurus-mdx-loader/src/remark/mermaid/__tests__/index.test.ts @@ -0,0 +1,62 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {createCompiler} from '@mdx-js/mdx'; +import mermaid from '..'; + +describe('mermaid remark plugin', () => { + function createTestCompiler() { + return createCompiler({ + remarkPlugins: [mermaid], + }); + } + + it('no mermaid', async () => { + const mdxCompiler = createTestCompiler(); + const result = await mdxCompiler.process( + '# Heading 1\n\nNo Mermaid diagram :(', + ); + expect(result.contents).toBe( + '\n\n\nconst layoutProps = {\n \n};\nconst MDXLayout = "wrapper"\nexport default function MDXContent({\n components,\n ...props\n}) {\n return \n

{`Heading 1`}

\n

{`No Mermaid diagram :(`}

\n
;\n}\n\n;\nMDXContent.isMDXComponent = true;', + ); + }); + + it('basic', async () => { + const mdxCompiler = createTestCompiler(); + const result = await mdxCompiler.process(`# Heading 1\n +\`\`\`mermaid +graph TD; + A-->B; + A-->C; + B-->D; + C-->D; +\`\`\``); + expect(result.contents).toBe(` + + +const layoutProps = { +${' '} +}; +const MDXLayout = "wrapper" +export default function MDXContent({ + components, + ...props +}) { + return +

{\`Heading 1\`}

+ B; + A-->C; + B-->D; + C-->D;\`} /> +
; +} + +; +MDXContent.isMDXComponent = true;`); + }); +}); diff --git a/packages/docusaurus-mdx-loader/src/remark/mermaid/index.ts b/packages/docusaurus-mdx-loader/src/remark/mermaid/index.ts new file mode 100644 index 000000000000..9d1a0588f7bc --- /dev/null +++ b/packages/docusaurus-mdx-loader/src/remark/mermaid/index.ts @@ -0,0 +1,48 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import visit from 'unist-util-visit'; +import type {Transformer} from 'unified'; +import type {Data, Literal, Node, Parent} from 'unist'; + +type CodeMermaid = Literal & { + type: 'code'; + lang: 'mermaid'; +}; + +function processMermaidNode( + node: CodeMermaid, + index: number, + parent: Parent | Literal, Data>, +) { + parent.children.splice(index, 1, { + type: 'jsx', + value: ``, + position: node.position, + }); +} + +export default function plugin(): Transformer { + return async (root) => { + // Find all the mermaid diagram code blocks. i.e. ```mermaid + const instances: [CodeMermaid, number, Parent, Data>][] = []; + visit( + root, + {type: 'code', lang: 'mermaid'}, + (node: CodeMermaid, index, parent) => { + if (parent) { + instances.push([node, index, parent]); + } + }, + ); + + // Replace each Mermaid code block with the Mermaid component + instances.forEach(([node, index, parent]) => { + processMermaidNode(node, index, parent); + }); + }; +} diff --git a/packages/docusaurus-theme-classic/package.json b/packages/docusaurus-theme-classic/package.json index 577babee2892..38ff68c427f4 100644 --- a/packages/docusaurus-theme-classic/package.json +++ b/packages/docusaurus-theme-classic/package.json @@ -34,6 +34,7 @@ "copy-text-to-clipboard": "^3.0.1", "infima": "0.2.0-alpha.39", "lodash": "^4.17.21", + "mermaid": "^9.1.1", "nprogress": "^0.2.0", "postcss": "^8.4.14", "prism-react-renderer": "^1.3.3", @@ -46,6 +47,7 @@ "@docusaurus/module-type-aliases": "2.0.0-beta.20", "@docusaurus/types": "2.0.0-beta.20", "@types/mdx-js__react": "^1.5.5", + "@types/mermaid": "^8.2.9", "@types/nprogress": "^0.2.0", "@types/prismjs": "^1.26.0", "@types/rtlcss": "^3.5.0", diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index bc9b9c9bbaf3..2b89a1e4be5e 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -552,6 +552,14 @@ declare module '@theme/Heading' { export default function Heading(props: Props): JSX.Element; } +declare module '@theme/Mermaid' { + export interface Props { + value: string; + } + + export default function Mermaid(props: Props): JSX.Element; +} + declare module '@theme/Layout' { import type {ReactNode} from 'react'; @@ -667,6 +675,14 @@ declare module '@theme/MDXComponents/Pre' { export default function MDXPre(props: Props): JSX.Element; } +declare module '@theme/MDXComponents/Mermaid' { + export interface Props { + value: string; + } + + export default function MDXMermaid(props: Props): JSX.Element; +} + declare module '@theme/MDXComponents' { import type {ComponentType, ComponentProps} from 'react'; @@ -677,6 +693,7 @@ declare module '@theme/MDXComponents' { import type MDXDetails from '@theme/MDXComponents/Details'; import type MDXUl from '@theme/MDXComponents/Ul'; import type MDXImg from '@theme/MDXComponents/Img'; + import type MDXMermaid from '@theme/MDXComponents/Mermaid'; export type MDXComponentsObject = { readonly head: typeof MDXHead; @@ -692,6 +709,7 @@ declare module '@theme/MDXComponents' { readonly h4: (props: ComponentProps<'h4'>) => JSX.Element; readonly h5: (props: ComponentProps<'h5'>) => JSX.Element; readonly h6: (props: ComponentProps<'h6'>) => JSX.Element; + readonly mermaid: typeof MDXMermaid; // eslint-disable-next-line @typescript-eslint/no-explicit-any [tagName: string]: ComponentType; }; @@ -1278,3 +1296,7 @@ declare module '@theme/prism-include-languages' { PrismObject: typeof PrismNamespace, ): void; } + +declare module '@theme/useMermaid' { + export default function useMermaid(): void; +} diff --git a/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx b/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx index c5503edcaaa2..b9aae88c4051 100644 --- a/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx @@ -21,6 +21,7 @@ import LayoutProviders from '@theme/LayoutProviders'; import ErrorPageContent from '@theme/ErrorPageContent'; import './styles.css'; import type {Props} from '@theme/Layout'; +import useMermaid from '@theme/useMermaid'; export default function Layout(props: Props): JSX.Element { const { @@ -33,6 +34,7 @@ export default function Layout(props: Props): JSX.Element { } = props; useKeyboardNavigation(); + useMermaid(); return ( diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Mermaid.tsx b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Mermaid.tsx new file mode 100644 index 000000000000..1d9c77d2c51d --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Mermaid.tsx @@ -0,0 +1,14 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import Mermaid from '@theme/Mermaid'; +import type {Props} from '@theme/MDXComponents/Mermaid'; + +export default function MDXMermaid(props: Props): JSX.Element { + return ; +} diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx b/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx index 82e7c5ac6b12..b6e406b071da 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx @@ -14,6 +14,7 @@ import MDXDetails from '@theme/MDXComponents/Details'; import MDXHeading from '@theme/MDXComponents/Heading'; import MDXUl from '@theme/MDXComponents/Ul'; import MDXImg from '@theme/MDXComponents/Img'; +import MDXMermaid from '@theme/MDXComponents/Mermaid'; import type {MDXComponentsObject} from '@theme/MDXComponents'; @@ -31,6 +32,7 @@ const MDXComponents: MDXComponentsObject = { h4: (props) => , h5: (props) => , h6: (props) => , + mermaid: MDXMermaid, }; export default MDXComponents; diff --git a/packages/docusaurus-theme-classic/src/theme/Mermaid/index.tsx b/packages/docusaurus-theme-classic/src/theme/Mermaid/index.tsx new file mode 100644 index 000000000000..3cda5dc631a1 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/Mermaid/index.tsx @@ -0,0 +1,64 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React, {useEffect, useState} from 'react'; +import useIsBrowser from '@docusaurus/useIsBrowser'; +import mermaid from 'mermaid'; +import type {Props} from '@theme/Mermaid'; + +/** + * Assign a unique ID to each mermaid svg as per requirements + * of `mermaid.render`. + */ +let id = 0; + +export default function Mermaid({value}: Props): JSX.Element { + // When theme updates, rerender the SVG. + const [svg, setSvg] = useState(''); + const isBrowser = useIsBrowser(); + + useEffect(() => { + const render = () => { + mermaid.render(`mermaid-svg-${id.toString()}`, value, (renderedSvg) => + setSvg(renderedSvg), + ); + id += 1; + }; + + render(); + + if (isBrowser) { + const html: HTMLHtmlElement = document.querySelector('html')!; + + const observer = new MutationObserver((mutations) => { + for (const mutation of mutations) { + if ( + mutation.type !== 'attributes' || + mutation.attributeName !== 'data-mermaid' + ) { + continue; + } + render(); + break; + } + }); + + observer.observe(html, {attributes: true}); + return () => { + try { + observer.disconnect(); + } catch { + // Do nothing + } + }; + } + return undefined; + }, [isBrowser, value]); + + // eslint-disable-next-line react/no-danger + return
; +} diff --git a/packages/docusaurus-theme-classic/src/theme/useMermaid.tsx b/packages/docusaurus-theme-classic/src/theme/useMermaid.tsx new file mode 100644 index 000000000000..3394673c10d0 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/useMermaid.tsx @@ -0,0 +1,95 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {useEffect} from 'react'; +import mermaid from 'mermaid'; +import {useThemeConfig} from '@docusaurus/theme-common'; +import useIsBrowser from '@docusaurus/useIsBrowser'; +import type mermaidAPI from 'mermaid/mermaidAPI'; +import type {ThemeConfig} from '@docusaurus/theme-common'; + +const DEFAULT_DARK_THEME = 'dark' as mermaidAPI.Theme.Dark; +const DEFAULT_LIGHT_THEME = 'default' as mermaidAPI.Theme.Default; + +const DARK_THEME_KEY = 'dark'; +const LIGHT_THEME_KEY = 'light'; + +const HTML_THEME_ATTRIBUTE = 'data-theme'; + +/** + * Gets the theme based on config and current data-theme of the HTML. + * + * @param html The HTML element of the page. + * @param config The configuration for this chart. + */ +function getTheme( + html: HTMLHtmlElement, + options?: ThemeConfig['mermaid'], +): mermaidAPI.Theme { + let htmlTheme = html.getAttribute(HTML_THEME_ATTRIBUTE) ?? LIGHT_THEME_KEY; + + if (!(htmlTheme === LIGHT_THEME_KEY || htmlTheme === DARK_THEME_KEY)) { + htmlTheme = LIGHT_THEME_KEY; + } + + const defaultTheme = + htmlTheme === LIGHT_THEME_KEY ? DEFAULT_LIGHT_THEME : DEFAULT_DARK_THEME; + + return options?.theme?.[htmlTheme] ?? options?.config?.theme ?? defaultTheme; +} + +export default function useMermaid(): void { + const themeConfig = useThemeConfig(); + const isBrowser = useIsBrowser(); + + // Watch for changes in theme in the HTML attribute `data-theme`. + useEffect(() => { + if (isBrowser) { + const html: HTMLHtmlElement = document.querySelector('html')!; + const init = (target: HTMLHtmlElement): void => { + const theme = getTheme(target, themeConfig.mermaid); + + if (themeConfig.mermaid?.config) { + mermaid.initialize({ + startOnLoad: true, + ...themeConfig.mermaid.config, + theme, + }); + } else { + mermaid.initialize({startOnLoad: true, theme}); + } + + html.setAttribute('data-mermaid', theme); + }; + + const observer = new MutationObserver((mutations) => { + for (const mutation of mutations) { + if ( + mutation.type !== 'attributes' || + mutation.attributeName !== 'data-theme' + ) { + continue; + } + init(mutation.target as HTMLHtmlElement); + break; + } + }); + + init(html); + + observer.observe(html, {attributes: true}); + return () => { + try { + observer.disconnect(); + } catch { + // Do nothing + } + }; + } + return undefined; + }, [isBrowser, themeConfig.mermaid]); +} diff --git a/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts b/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts index b160bf307c84..aa3237906a66 100644 --- a/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts +++ b/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts @@ -6,6 +6,7 @@ */ import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import type mermaidAPI from 'mermaid/mermaidAPI'; import type {PrismTheme} from 'prism-react-renderer'; import type {DeepPartial} from 'utility-types'; import type {MagicCommentConfig} from './codeBlockUtils'; @@ -102,6 +103,15 @@ export type TableOfContents = { maxHeadingLevel: number; }; +export type MermaidConfig = { + theme?: { + light: mermaidAPI.Theme; + dark: mermaidAPI.Theme; + [htmlTheme: string]: mermaidAPI.Theme; + }; + config?: mermaidAPI.Config; +}; + // Theme config after validation/normalization export type ThemeConfig = { docs: { @@ -125,6 +135,7 @@ export type ThemeConfig = { image?: string; metadata: {[key: string]: string}[]; tableOfContents: TableOfContents; + mermaid?: MermaidConfig; }; // User-provided theme config, unnormalized diff --git a/project-words.txt b/project-words.txt index 2e029e7f7c3f..f74714c5217b 100644 --- a/project-words.txt +++ b/project-words.txt @@ -97,7 +97,9 @@ formik fouc froms funboxteam +gantt getopts +gitgraph gitpod globbing globby @@ -253,6 +255,7 @@ refactorings regexes rehype reponame +reqs requireindex retrocompatibility retrocompatible @@ -332,6 +335,7 @@ urlset userland vannicatte vercel +verifymethod vetter vfile vicenti diff --git a/website/_dogfooding/_docs tests/tests/diagrams.md b/website/_dogfooding/_docs tests/tests/diagrams.md new file mode 100644 index 000000000000..01a413267bb1 --- /dev/null +++ b/website/_dogfooding/_docs tests/tests/diagrams.md @@ -0,0 +1,256 @@ +--- +--- + +# Diagram Examples + +## Sequence Diagram + +```mermaid +sequenceDiagram + participant Alice + participant Bob + Alice->>John: Hello John, how are you? + loop Health check + John->>John: Fight against hypochondria + end + Note right of John: Rational thoughts
prevail! + John-->>Alice: Great! + John->>Bob: How about you? + Bob-->>John: Jolly good! +``` + +## Gantt Chart + +```mermaid +gantt +dateFormat YYYY-MM-DD +title Adding GANTT diagram to mermaid +excludes weekdays 2014-01-10 + +section A section +Completed task :done, des1, 2014-01-06,2014-01-08 +Active task :active, des2, 2014-01-09, 3d +Future task : des3, after des2, 5d +Future task2 : des4, after des3, 5d +``` + +## Flow Chart + +```mermaid +flowchart TD + A[Start] --> B{Is it?} + B -->|Yes| C[OK] + C --> D[Rethink] + D --> B + B ---->|No| E[End] +``` + +## Class Diagram + +```mermaid + classDiagram + Animal <|-- Duck + Animal <|-- Fish + Animal <|-- Zebra + Animal : +int age + Animal : +String gender + Animal: +isMammal() + Animal: +mate() + class Duck{ + +String beakColor + +swim() + +quack() + } + class Fish{ + -int sizeInFeet + -canEat() + } + class Zebra{ + +bool is_wild + +run() + } +``` + +## State Diagram + +```mermaid +stateDiagram-v2 + [*] --> Active + + state Active { + [*] --> NumLockOff + NumLockOff --> NumLockOn : EvNumLockPressed + NumLockOn --> NumLockOff : EvNumLockPressed + -- + [*] --> CapsLockOff + CapsLockOff --> CapsLockOn : EvCapsLockPressed + CapsLockOn --> CapsLockOff : EvCapsLockPressed + -- + [*] --> ScrollLockOff + ScrollLockOff --> ScrollLockOn : EvScrollLockPressed + ScrollLockOn --> ScrollLockOff : EvScrollLockPressed + } +``` + +## Entity Relationship Diagram + +```mermaid +erDiagram + CAR ||--o{ NAMED-DRIVER : allows + CAR { + string registrationNumber + string make + string model + } + PERSON ||--o{ NAMED-DRIVER : is + PERSON { + string firstName + string lastName + int age + } +``` + +## User Journey + +```mermaid +journey + title My working day + section Go to work + Make tea: 5: Me + Go upstairs: 3: Me + Do work: 1: Me, Cat + section Go home + Go downstairs: 5: Me + Sit down: 5: Me +``` + +## Pie Chart + +```mermaid +pie showData + title Key elements in Product X + "Calcium" : 42.96 + "Potassium" : 50.05 + "Magnesium" : 10.01 + "Iron" : 5 +``` + +## Requirement Diagram + +```mermaid + requirementDiagram + + requirement test_req { + id: 1 + text: the test text. + risk: high + verifymethod: test + } + + functionalRequirement test_req2 { + id: 1.1 + text: the second test text. + risk: low + verifymethod: inspection + } + + performanceRequirement test_req3 { + id: 1.2 + text: the third test text. + risk: medium + verifymethod: demonstration + } + + interfaceRequirement test_req4 { + id: 1.2.1 + text: the fourth test text. + risk: medium + verifymethod: analysis + } + + physicalRequirement test_req5 { + id: 1.2.2 + text: the fifth test text. + risk: medium + verifymethod: analysis + } + + designConstraint test_req6 { + id: 1.2.3 + text: the sixth test text. + risk: medium + verifymethod: analysis + } + + element test_entity { + type: simulation + } + + element test_entity2 { + type: word doc + docRef: reqs/test_entity + } + + element test_entity3 { + type: "test suite" + docRef: github.com/all_the_tests + } + + + test_entity - satisfies -> test_req2 + test_req - traces -> test_req2 + test_req - contains -> test_req3 + test_req3 - contains -> test_req4 + test_req4 - derives -> test_req5 + test_req5 - refines -> test_req6 + test_entity3 - verifies -> test_req5 + test_req <- copies - test_entity2 +``` + +## Gitgraph (Git) Diagram + +```mermaid +%%{init: { 'logLevel': 'debug', 'theme': 'base' } }%% + gitGraph + commit + branch hotfix + checkout hotfix + commit + branch develop + checkout develop + commit id:"ash" tag:"abc" + branch featureB + checkout featureB + commit type:HIGHLIGHT + checkout main + checkout hotfix + commit type:NORMAL + checkout develop + commit type:REVERSE + checkout featureB + commit + checkout main + merge hotfix + checkout featureB + commit + checkout develop + branch featureA + commit + checkout develop + merge hotfix + checkout featureA + commit + checkout featureB + commit + checkout develop + merge featureA + branch release + checkout release + commit + checkout main + commit + checkout release + merge main + checkout develop + merge release +``` diff --git a/website/community/2-resources.md b/website/community/2-resources.md index fb0507049eed..fe4a7511f216 100644 --- a/website/community/2-resources.md +++ b/website/community/2-resources.md @@ -44,7 +44,6 @@ See the showcase - [docusaurus-plugin-module-alias](https://github.com/atomicpages/docusaurus-plugin-module-alias) - A Docusaurus v2 plugin for quickly aliasing local modules - [docusaurus-protobuffet](https://github.com/protobuffet/docusaurus-protobuffet) - Docusaurus toolset for Protobuf contract documentation - [docusaurus-prince-pdf](https://github.com/signcl/docusaurus-prince-pdf) - Generate PDF with PrinceXML for better font subsetting and ToC features. Support Docusaurus v2 sites -- [mdx-mermaid](https://github.com/sjwall/mdx-mermaid) - A Docusaurus v2 compatible MDX plugin for displaying [Mermaid](https://mermaid-js.github.io/mermaid) diagrams - [redocusaurus](https://github.com/rohit-gohri/redocusaurus) - A Docusaurus preset for integrating OpenAPI documentation into your docs with [Redoc](https://github.com/redocly/redoc) - [plugin-image-zoom](https://github.com/flexanalytics/plugin-image-zoom) - An Image Zoom plugin for Docusaurus 2 - [docusaurus-plugin-typedoc](https://github.com/tgreyuk/typedoc-plugin-markdown/tree/master/packages/docusaurus-plugin-typedoc) - A Docusaurus 2 plugin to build documentation with [TypeDoc](https://typedoc.org/) diff --git a/website/docs/guides/markdown-features/markdown-features-diagrams.mdx b/website/docs/guides/markdown-features/markdown-features-diagrams.mdx new file mode 100644 index 000000000000..2baabd280b79 --- /dev/null +++ b/website/docs/guides/markdown-features/markdown-features-diagrams.mdx @@ -0,0 +1,68 @@ +--- +id: diagrams +title: Diagrams +description: Writing diagrams with Mermaid +slug: /markdown-features/diagrams +--- + +# Diagrams + +Diagrams can be rendered using [Mermaid](https://mermaid-js.github.io/mermaid/) in a code block. + +## Usage + +Add a code block with language `mermaid`: + +````md title="Example Mermaid diagram" +```mermaid +graph TD; + A-->B; + A-->C; + B-->D; + C-->D; +``` +```` + +```mermaid +graph TD; + A-->B; + A-->C; + B-->D; + C-->D; +``` + +See the [Mermaid syntax documentation](https://mermaid-js.github.io/mermaid/#/./n00b-syntaxReference) for more information on the Mermaid syntax. + +## Theming + +The diagram dark and light themes can be changed by setting `theme` values in the `themeConfig` in your `docusaurus.config.js`. + +```js title=docusaurus.config.js +themeConfig: + /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ + ({ + mermaid: { + theme: { light: 'neutral', dark: 'forest' } + } + }), +``` + +See the [Mermaid theme documentation](https://mermaid-js.github.io/mermaid/#/theming) for more information on theming Mermaid diagrams. + +## Mermaid Config + +Mermaid config can be configured through the `config` object in `themeConfig` in your `docusaurus.config.js`: + +```js title=docusaurus.config.js +themeConfig: + /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ + ({ + mermaid: { + config: { + maxTextSize: 50, + } + } + }), +``` + +See the [Mermaid configuration documentation](https://mermaid-js.github.io/mermaid/#/./Setup?id=configuration) for the available config options. diff --git a/website/sidebars.js b/website/sidebars.js index aa139632d171..a5be9b42a915 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -82,6 +82,7 @@ const sidebars = { 'guides/markdown-features/links', 'guides/markdown-features/plugins', 'guides/markdown-features/math-equations', + 'guides/markdown-features/diagrams', 'guides/markdown-features/head-metadata', ], }, diff --git a/yarn.lock b/yarn.lock index 4c52edca54a9..d4bb98d757ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1238,6 +1238,11 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@braintree/sanitize-url@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-6.0.0.tgz#fe364f025ba74f6de6c837a84ef44bdb1d61e68f" + integrity sha512-mgmE7XBYY/21erpzhexk4Cj1cyTQ9LzvnTxtzM17BJ7ERMNE6W72mQRo0I1Ud8eFJ+RVVIcBNhLFZ3GX4XFz5w== + "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" @@ -3467,6 +3472,11 @@ dependencies: "@types/react" "*" +"@types/mermaid@^8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@types/mermaid/-/mermaid-8.2.9.tgz#1844505dcffcd47703e94628a6200583d35c2c76" + integrity sha512-f1i8fNoVFVJXedk+R7GcEk4KoOWzWAU3CzFqlVw1qWKktfsataBERezCz1pOdKy8Ec02ZdPQXGM7NU2lPHABYQ== + "@types/micromatch@^4.0.2": version "4.0.2" resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-4.0.2.tgz#ce29c8b166a73bf980a5727b1e4a4d099965151d" @@ -5515,21 +5525,21 @@ command-exists-promise@^2.0.2: resolved "https://registry.yarnpkg.com/command-exists-promise/-/command-exists-promise-2.0.2.tgz#7beecc4b218299f3c61fa69a4047aa0b36a64a99" integrity sha512-T6PB6vdFrwnHXg/I0kivM3DqaCGZLjjYSOe0a5WgFKcz1sOnmOeIjnhQPXVXX3QjVbLyTJ85lJkX6lUpukTzaA== -commander@^2.20.0: +commander@2, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +commander@7, commander@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + commander@^5.0.0, commander@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== -commander@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - commander@^8.0.0, commander@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" @@ -6157,6 +6167,516 @@ csstype@^3.0.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.0.tgz#4ddcac3718d787cf9df0d1b7d15033925c8f29f2" integrity sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA== +d3-array@1, d3-array@^1.1.1, d3-array@^1.2.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" + integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw== + +"d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3: + version "3.1.6" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.1.6.tgz#0342c835925826f49b4d16eb7027aec334ffc97d" + integrity sha512-DCbBBNuKOeiR9h04ySRBMW52TFVc91O9wJziuyXw6Ztmy8D3oZbmCkOO3UHKC7ceNJsN2Mavo9+vwV8EAEUXzA== + dependencies: + internmap "1 - 2" + +d3-axis@1: + version "1.0.12" + resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-1.0.12.tgz#cdf20ba210cfbb43795af33756886fb3638daac9" + integrity sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ== + +d3-axis@3: + version "3.0.0" + resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-3.0.0.tgz#c42a4a13e8131d637b745fc2973824cfeaf93322" + integrity sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw== + +d3-brush@1: + version "1.1.6" + resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-1.1.6.tgz#b0a22c7372cabec128bdddf9bddc058592f89e9b" + integrity sha512-7RW+w7HfMCPyZLifTz/UnJmI5kdkXtpCbombUSs8xniAyo0vIbrDzDwUJB6eJOgl9u5DQOt2TQlYumxzD1SvYA== + dependencies: + d3-dispatch "1" + d3-drag "1" + d3-interpolate "1" + d3-selection "1" + d3-transition "1" + +d3-brush@3: + version "3.0.0" + resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-3.0.0.tgz#6f767c4ed8dcb79de7ede3e1c0f89e63ef64d31c" + integrity sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ== + dependencies: + d3-dispatch "1 - 3" + d3-drag "2 - 3" + d3-interpolate "1 - 3" + d3-selection "3" + d3-transition "3" + +d3-chord@1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/d3-chord/-/d3-chord-1.0.6.tgz#309157e3f2db2c752f0280fedd35f2067ccbb15f" + integrity sha512-JXA2Dro1Fxw9rJe33Uv+Ckr5IrAa74TlfDEhE/jfLOaXegMQFQTAgAw9WnZL8+HxVBRXaRGCkrNU7pJeylRIuA== + dependencies: + d3-array "1" + d3-path "1" + +d3-chord@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-chord/-/d3-chord-3.0.1.tgz#d156d61f485fce8327e6abf339cb41d8cbba6966" + integrity sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g== + dependencies: + d3-path "1 - 3" + +d3-collection@1: + version "1.0.7" + resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.7.tgz#349bd2aa9977db071091c13144d5e4f16b5b310e" + integrity sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A== + +d3-color@1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.4.1.tgz#c52002bf8846ada4424d55d97982fef26eb3bc8a" + integrity sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q== + +"d3-color@1 - 3", d3-color@3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2" + integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== + +d3-contour@1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/d3-contour/-/d3-contour-1.3.2.tgz#652aacd500d2264cb3423cee10db69f6f59bead3" + integrity sha512-hoPp4K/rJCu0ladiH6zmJUEz6+u3lgR+GSm/QdM2BBvDraU39Vr7YdDCicJcxP1z8i9B/2dJLgDC1NcvlF8WCg== + dependencies: + d3-array "^1.1.1" + +d3-contour@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-contour/-/d3-contour-3.0.1.tgz#2c64255d43059599cd0dba8fe4cc3d51ccdd9bbd" + integrity sha512-0Oc4D0KyhwhM7ZL0RMnfGycLN7hxHB8CMmwZ3+H26PWAG0ozNuYG5hXSDNgmP1SgJkQMrlG6cP20HoaSbvcJTQ== + dependencies: + d3-array "2 - 3" + +d3-delaunay@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/d3-delaunay/-/d3-delaunay-6.0.2.tgz#7fd3717ad0eade2fc9939f4260acfb503f984e92" + integrity sha512-IMLNldruDQScrcfT+MWnazhHbDJhcRJyOEBAJfwQnHle1RPh6WDuLvxNArUju2VSMSUuKlY5BGHRJ2cYyoFLQQ== + dependencies: + delaunator "5" + +d3-dispatch@1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-1.0.6.tgz#00d37bcee4dd8cd97729dd893a0ac29caaba5d58" + integrity sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA== + +"d3-dispatch@1 - 3", d3-dispatch@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-3.0.1.tgz#5fc75284e9c2375c36c839411a0cf550cbfc4d5e" + integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg== + +d3-drag@1: + version "1.2.5" + resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-1.2.5.tgz#2537f451acd39d31406677b7dc77c82f7d988f70" + integrity sha512-rD1ohlkKQwMZYkQlYVCrSFxsWPzI97+W+PaEIBNTMxRuxz9RF0Hi5nJWHGVJ3Om9d2fRTe1yOBINJyy/ahV95w== + dependencies: + d3-dispatch "1" + d3-selection "1" + +"d3-drag@2 - 3", d3-drag@3: + version "3.0.0" + resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-3.0.0.tgz#994aae9cd23c719f53b5e10e3a0a6108c69607ba" + integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg== + dependencies: + d3-dispatch "1 - 3" + d3-selection "3" + +d3-dsv@1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-1.2.0.tgz#9d5f75c3a5f8abd611f74d3f5847b0d4338b885c" + integrity sha512-9yVlqvZcSOMhCYzniHE7EVUws7Fa1zgw+/EAV2BxJoG3ME19V6BQFBwI855XQDsxyOuG7NibqRMTtiF/Qup46g== + dependencies: + commander "2" + iconv-lite "0.4" + rw "1" + +"d3-dsv@1 - 3", d3-dsv@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-3.0.1.tgz#c63af978f4d6a0d084a52a673922be2160789b73" + integrity sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q== + dependencies: + commander "7" + iconv-lite "0.6" + rw "1" + +d3-ease@1: + version "1.0.7" + resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-1.0.7.tgz#9a834890ef8b8ae8c558b2fe55bd57f5993b85e2" + integrity sha512-lx14ZPYkhNx0s/2HX5sLFUI3mbasHjSSpwO/KaaNACweVwxUruKyWVcb293wMv1RqTPZyZ8kSZ2NogUZNcLOFQ== + +"d3-ease@1 - 3", d3-ease@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4" + integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== + +d3-fetch@1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/d3-fetch/-/d3-fetch-1.2.0.tgz#15ce2ecfc41b092b1db50abd2c552c2316cf7fc7" + integrity sha512-yC78NBVcd2zFAyR/HnUiBS7Lf6inSCoWcSxFfw8FYL7ydiqe80SazNwoffcqOfs95XaLo7yebsmQqDKSsXUtvA== + dependencies: + d3-dsv "1" + +d3-fetch@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-fetch/-/d3-fetch-3.0.1.tgz#83141bff9856a0edb5e38de89cdcfe63d0a60a22" + integrity sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw== + dependencies: + d3-dsv "1 - 3" + +d3-force@1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-1.2.1.tgz#fd29a5d1ff181c9e7f0669e4bd72bdb0e914ec0b" + integrity sha512-HHvehyaiUlVo5CxBJ0yF/xny4xoaxFxDnBXNvNcfW9adORGZfyNF1dj6DGLKyk4Yh3brP/1h3rnDzdIAwL08zg== + dependencies: + d3-collection "1" + d3-dispatch "1" + d3-quadtree "1" + d3-timer "1" + +d3-force@3: + version "3.0.0" + resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-3.0.0.tgz#3e2ba1a61e70888fe3d9194e30d6d14eece155c4" + integrity sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg== + dependencies: + d3-dispatch "1 - 3" + d3-quadtree "1 - 3" + d3-timer "1 - 3" + +d3-format@1: + version "1.4.5" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.4.5.tgz#374f2ba1320e3717eb74a9356c67daee17a7edb4" + integrity sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ== + +"d3-format@1 - 3", d3-format@3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641" + integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== + +d3-geo@1: + version "1.12.1" + resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.12.1.tgz#7fc2ab7414b72e59fbcbd603e80d9adc029b035f" + integrity sha512-XG4d1c/UJSEX9NfU02KwBL6BYPj8YKHxgBEw5om2ZnTRSbIcego6dhHwcxuSR3clxh0EpE38os1DVPOmnYtTPg== + dependencies: + d3-array "1" + +d3-geo@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-3.0.1.tgz#4f92362fd8685d93e3b1fae0fd97dc8980b1ed7e" + integrity sha512-Wt23xBych5tSy9IYAM1FR2rWIBFWa52B/oF/GYe5zbdHrg08FU8+BuI6X4PvTwPDdqdAdq04fuWJpELtsaEjeA== + dependencies: + d3-array "2.5.0 - 3" + +d3-hierarchy@1: + version "1.1.9" + resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz#2f6bee24caaea43f8dc37545fa01628559647a83" + integrity sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ== + +d3-hierarchy@3: + version "3.1.2" + resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz#b01cd42c1eed3d46db77a5966cf726f8c09160c6" + integrity sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA== + +d3-interpolate@1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.4.0.tgz#526e79e2d80daa383f9e0c1c1c7dcc0f0583e987" + integrity sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA== + dependencies: + d3-color "1" + +"d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 3", d3-interpolate@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d" + integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== + dependencies: + d3-color "1 - 3" + +d3-path@1: + version "1.0.9" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf" + integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== + +"d3-path@1 - 3", d3-path@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.0.1.tgz#f09dec0aaffd770b7995f1a399152bf93052321e" + integrity sha512-gq6gZom9AFZby0YLduxT1qmrp4xpBA1YZr19OI717WIdKE2OM5ETq5qrHLb301IgxhLwcuxvGZVLeeWc/k1I6w== + +d3-polygon@1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-1.0.6.tgz#0bf8cb8180a6dc107f518ddf7975e12abbfbd38e" + integrity sha512-k+RF7WvI08PC8reEoXa/w2nSg5AUMTi+peBD9cmFc+0ixHfbs4QmxxkarVal1IkVkgxVuk9JSHhJURHiyHKAuQ== + +d3-polygon@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-3.0.1.tgz#0b45d3dd1c48a29c8e057e6135693ec80bf16398" + integrity sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg== + +d3-quadtree@1: + version "1.0.7" + resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-1.0.7.tgz#ca8b84df7bb53763fe3c2f24bd435137f4e53135" + integrity sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA== + +"d3-quadtree@1 - 3", d3-quadtree@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-3.0.1.tgz#6dca3e8be2b393c9a9d514dabbd80a92deef1a4f" + integrity sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw== + +d3-random@1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-1.1.2.tgz#2833be7c124360bf9e2d3fd4f33847cfe6cab291" + integrity sha512-6AK5BNpIFqP+cx/sreKzNjWbwZQCSUatxq+pPRmFIQaWuoD+NrbVWw7YWpHiXpCQ/NanKdtGDuB+VQcZDaEmYQ== + +d3-random@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-3.0.1.tgz#d4926378d333d9c0bfd1e6fa0194d30aebaa20f4" + integrity sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ== + +d3-scale-chromatic@1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-1.5.0.tgz#54e333fc78212f439b14641fb55801dd81135a98" + integrity sha512-ACcL46DYImpRFMBcpk9HhtIyC7bTBR4fNOPxwVSl0LfulDAwyiHyPOTqcDG1+t5d4P9W7t/2NAuWu59aKko/cg== + dependencies: + d3-color "1" + d3-interpolate "1" + +d3-scale-chromatic@3: + version "3.0.0" + resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz#15b4ceb8ca2bb0dcb6d1a641ee03d59c3b62376a" + integrity sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g== + dependencies: + d3-color "1 - 3" + d3-interpolate "1 - 3" + +d3-scale@2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-2.2.2.tgz#4e880e0b2745acaaddd3ede26a9e908a9e17b81f" + integrity sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw== + dependencies: + d3-array "^1.2.0" + d3-collection "1" + d3-format "1" + d3-interpolate "1" + d3-time "1" + d3-time-format "2" + +d3-scale@4: + version "4.0.2" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396" + integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ== + dependencies: + d3-array "2.10.0 - 3" + d3-format "1 - 3" + d3-interpolate "1.2.0 - 3" + d3-time "2.1.1 - 3" + d3-time-format "2 - 4" + +d3-selection@1, d3-selection@^1.1.0: + version "1.4.2" + resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.4.2.tgz#dcaa49522c0dbf32d6c1858afc26b6094555bc5c" + integrity sha512-SJ0BqYihzOjDnnlfyeHT0e30k0K1+5sR3d5fNueCNeuhZTnGw4M4o8mqJchSwgKMXCNFo+e2VTChiSJ0vYtXkg== + +"d3-selection@2 - 3", d3-selection@3: + version "3.0.0" + resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-3.0.0.tgz#c25338207efa72cc5b9bd1458a1a41901f1e1b31" + integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ== + +d3-shape@1: + version "1.3.7" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7" + integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== + dependencies: + d3-path "1" + +d3-shape@3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.1.0.tgz#c8a495652d83ea6f524e482fca57aa3f8bc32556" + integrity sha512-tGDh1Muf8kWjEDT/LswZJ8WF85yDZLvVJpYU9Nq+8+yW1Z5enxrmXOhTArlkaElU+CTn0OTVNli+/i+HP45QEQ== + dependencies: + d3-path "1 - 3" + +d3-time-format@2: + version "2.3.0" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-2.3.0.tgz#107bdc028667788a8924ba040faf1fbccd5a7850" + integrity sha512-guv6b2H37s2Uq/GefleCDtbe0XZAuy7Wa49VGkPVPMfLL9qObgBST3lEHJBMUp8S7NdLQAGIvr2KXk8Hc98iKQ== + dependencies: + d3-time "1" + +"d3-time-format@2 - 4", d3-time-format@4: + version "4.1.0" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a" + integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg== + dependencies: + d3-time "1 - 3" + +d3-time@1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.1.0.tgz#b1e19d307dae9c900b7e5b25ffc5dcc249a8a0f1" + integrity sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA== + +"d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@3: + version "3.0.0" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.0.0.tgz#65972cb98ae2d4954ef5c932e8704061335d4975" + integrity sha512-zmV3lRnlaLI08y9IMRXSDshQb5Nj77smnfpnd2LrBa/2K281Jijactokeak14QacHs/kKq0AQ121nidNYlarbQ== + dependencies: + d3-array "2 - 3" + +d3-timer@1: + version "1.0.10" + resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.10.tgz#dfe76b8a91748831b13b6d9c793ffbd508dd9de5" + integrity sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw== + +"d3-timer@1 - 3", d3-timer@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0" + integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== + +d3-transition@1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-1.3.2.tgz#a98ef2151be8d8600543434c1ca80140ae23b398" + integrity sha512-sc0gRU4PFqZ47lPVHloMn9tlPcv8jxgOQg+0zjhfZXMQuvppjG6YuwdMBE0TuqCZjeJkLecku/l9R0JPcRhaDA== + dependencies: + d3-color "1" + d3-dispatch "1" + d3-ease "1" + d3-interpolate "1" + d3-selection "^1.1.0" + d3-timer "1" + +"d3-transition@2 - 3", d3-transition@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-3.0.1.tgz#6869fdde1448868077fdd5989200cb61b2a1645f" + integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w== + dependencies: + d3-color "1 - 3" + d3-dispatch "1 - 3" + d3-ease "1 - 3" + d3-interpolate "1 - 3" + d3-timer "1 - 3" + +d3-voronoi@1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.4.tgz#dd3c78d7653d2bb359284ae478645d95944c8297" + integrity sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg== + +d3-zoom@1: + version "1.8.3" + resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-1.8.3.tgz#b6a3dbe738c7763121cd05b8a7795ffe17f4fc0a" + integrity sha512-VoLXTK4wvy1a0JpH2Il+F2CiOhVu7VRXWF5M/LroMIh3/zBAC3WAt7QoIvPibOavVo20hN6/37vwAsdBejLyKQ== + dependencies: + d3-dispatch "1" + d3-drag "1" + d3-interpolate "1" + d3-selection "1" + d3-transition "1" + +d3-zoom@3: + version "3.0.0" + resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-3.0.0.tgz#d13f4165c73217ffeaa54295cd6969b3e7aee8f3" + integrity sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw== + dependencies: + d3-dispatch "1 - 3" + d3-drag "2 - 3" + d3-interpolate "1 - 3" + d3-selection "2 - 3" + d3-transition "2 - 3" + +d3@^5.14: + version "5.16.0" + resolved "https://registry.yarnpkg.com/d3/-/d3-5.16.0.tgz#9c5e8d3b56403c79d4ed42fbd62f6113f199c877" + integrity sha512-4PL5hHaHwX4m7Zr1UapXW23apo6pexCgdetdJ5kTmADpG/7T9Gkxw0M0tf/pjoB63ezCCm0u5UaFYy2aMt0Mcw== + dependencies: + d3-array "1" + d3-axis "1" + d3-brush "1" + d3-chord "1" + d3-collection "1" + d3-color "1" + d3-contour "1" + d3-dispatch "1" + d3-drag "1" + d3-dsv "1" + d3-ease "1" + d3-fetch "1" + d3-force "1" + d3-format "1" + d3-geo "1" + d3-hierarchy "1" + d3-interpolate "1" + d3-path "1" + d3-polygon "1" + d3-quadtree "1" + d3-random "1" + d3-scale "2" + d3-scale-chromatic "1" + d3-selection "1" + d3-shape "1" + d3-time "1" + d3-time-format "2" + d3-timer "1" + d3-transition "1" + d3-voronoi "1" + d3-zoom "1" + +d3@^7.0.0: + version "7.4.4" + resolved "https://registry.yarnpkg.com/d3/-/d3-7.4.4.tgz#bfbf87487c37d3196efebd5a63e3a0ed8299d8ff" + integrity sha512-97FE+MYdAlV3R9P74+R3Uar7wUKkIFu89UWMjEaDhiJ9VxKvqaMxauImy8PC2DdBkdM2BxJOIoLxPrcZUyrKoQ== + dependencies: + d3-array "3" + d3-axis "3" + d3-brush "3" + d3-chord "3" + d3-color "3" + d3-contour "3" + d3-delaunay "6" + d3-dispatch "3" + d3-drag "3" + d3-dsv "3" + d3-ease "3" + d3-fetch "3" + d3-force "3" + d3-format "3" + d3-geo "3" + d3-hierarchy "3" + d3-interpolate "3" + d3-path "3" + d3-polygon "3" + d3-quadtree "3" + d3-random "3" + d3-scale "4" + d3-scale-chromatic "3" + d3-selection "3" + d3-shape "3" + d3-time "3" + d3-time-format "4" + d3-timer "3" + d3-transition "3" + d3-zoom "3" + +dagre-d3@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/dagre-d3/-/dagre-d3-0.6.4.tgz#0728d5ce7f177ca2337df141ceb60fbe6eeb7b29" + integrity sha512-e/6jXeCP7/ptlAM48clmX4xTZc5Ek6T6kagS7Oz2HrYSdqcLZFLqpAfh7ldbZRFfxCZVyh61NEPR08UQRVxJzQ== + dependencies: + d3 "^5.14" + dagre "^0.8.5" + graphlib "^2.1.8" + lodash "^4.17.15" + +dagre@^0.8.5: + version "0.8.5" + resolved "https://registry.yarnpkg.com/dagre/-/dagre-0.8.5.tgz#ba30b0055dac12b6c1fcc247817442777d06afee" + integrity sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw== + dependencies: + graphlib "^2.1.8" + lodash "^4.17.15" + damerau-levenshtein@^1.0.7: version "1.0.8" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" @@ -6339,6 +6859,13 @@ del@^6.1.0: rimraf "^3.0.2" slash "^3.0.0" +delaunator@5: + version "5.0.0" + resolved "https://registry.yarnpkg.com/delaunator/-/delaunator-5.0.0.tgz#60f052b28bd91c9b4566850ebf7756efe821d81b" + integrity sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw== + dependencies: + robust-predicates "^3.0.0" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -6555,6 +7082,11 @@ domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3: dependencies: domelementtype "^2.3.0" +dompurify@2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.6.tgz#2e019d7d7617aacac07cbbe3d88ae3ad354cf875" + integrity sha512-OFP2u/3T1R5CEgWCEONuJ1a5+MFKnOYpkywpUSxv/dj1LeBT1erK+JwM7zK0ROy2BRhqVCf0LRw/kHqKuMkVGg== + domutils@1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" @@ -8007,6 +8539,13 @@ grapheme-splitter@^1.0.4: resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== +graphlib@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.8.tgz#5761d414737870084c92ec7b5dbcb0592c9d35da" + integrity sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A== + dependencies: + lodash "^4.17.15" + gray-matter@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-4.0.3.tgz#e893c064825de73ea1f5f7d88c7a9f7274288798" @@ -8542,14 +9081,14 @@ husky@^8.0.1: resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.1.tgz#511cb3e57de3e3190514ae49ed50f6bc3f50b3e9" integrity sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw== -iconv-lite@0.4.24, iconv-lite@^0.4.24: +iconv-lite@0.4, iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@0.6.3, iconv-lite@^0.6.2: +iconv-lite@0.6, iconv-lite@0.6.3, iconv-lite@^0.6.2: version "0.6.3" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== @@ -8715,6 +9254,11 @@ internal-slot@^1.0.3: has "^1.0.3" side-channel "^1.0.4" +"internmap@1 - 2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009" + integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== + interpret@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" @@ -9866,6 +10410,11 @@ keyv@^3.0.0: dependencies: json-buffer "3.0.0" +khroma@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/khroma/-/khroma-2.0.0.tgz#7577de98aed9f36c7a474c4d453d94c0d6c6588b" + integrity sha512-2J8rDNlQWbtiNYThZRvmMv5yt44ZakX+Tz5ZIp/mN1pt4snn+m030Va5Z4v8xA0cQFDXBwO/8i42xL4QPsVk3g== + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -10526,6 +11075,21 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== +mermaid@^9.1.1: + version "9.1.1" + resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-9.1.1.tgz#5d3d330ca4adf7f3c8ca51095f8bb2f0fb1a93bb" + integrity sha512-2RVD+WkzZ4VDyO9gQvQAuQ/ux2gLigJtKDTlbwjYqOR/NwsVzTSfGm/kx648/qWJsg6Sv04tE9BWCO8s6a+pFA== + dependencies: + "@braintree/sanitize-url" "^6.0.0" + d3 "^7.0.0" + dagre "^0.8.5" + dagre-d3 "^0.6.4" + dompurify "2.3.6" + graphlib "^2.1.8" + khroma "^2.0.0" + moment-mini "^2.24.0" + stylis "^4.0.10" + methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -10778,6 +11342,11 @@ modify-values@^1.0.0: resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== +moment-mini@^2.24.0: + version "2.24.0" + resolved "https://registry.yarnpkg.com/moment-mini/-/moment-mini-2.24.0.tgz#fa68d98f7fe93ae65bf1262f6abb5fb6983d8d18" + integrity sha512-9ARkWHBs+6YJIvrIp0Ik5tyTTtP9PoV0Ssu2Ocq5y9v8+NOOpWiRshAp8c4rZVWTOe+157on/5G+zj5pwIQFEQ== + mrmime@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-1.0.0.tgz#14d387f0585a5233d291baba339b063752a2398b" @@ -13309,6 +13878,11 @@ rimraf@~2.6.2: dependencies: glob "^7.1.3" +robust-predicates@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/robust-predicates/-/robust-predicates-3.0.1.tgz#ecde075044f7f30118682bd9fb3f123109577f9a" + integrity sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g== + rollup-plugin-terser@^7.0.0: version "7.0.2" resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" @@ -13353,6 +13927,11 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +rw@1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" + integrity sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q= + rxjs@^6.6.0: version "6.6.7" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" @@ -14356,6 +14935,11 @@ stylelint@^14.8.3: v8-compile-cache "^2.3.0" write-file-atomic "^4.0.1" +stylis@^4.0.10: + version "4.1.1" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.1.tgz#e46c6a9bbf7c58db1e65bb730be157311ae1fe12" + integrity sha512-lVrM/bNdhVX2OgBFNa2YJ9Lxj7kPzylieHd3TNjuGE0Re9JB7joL5VUKOVH1kdNNJTgGPpT8hmwIAPLaSyEVFQ== + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" From a003697a77a27fae9e0af064b6cc167499211f32 Mon Sep 17 00:00:00 2001 From: Samuel Wall Date: Thu, 26 May 2022 07:07:12 +0000 Subject: [PATCH 02/28] feat(mdx-loader): mermaid rendering optional --- packages/docusaurus-mdx-loader/src/loader.ts | 5 ++++- .../docusaurus-plugin-content-blog/src/index.ts | 1 + .../docusaurus-plugin-content-docs/src/index.ts | 1 + .../docusaurus-plugin-content-pages/src/index.ts | 1 + .../src/theme/useMermaid.tsx | 6 ++++-- packages/docusaurus-types/src/index.d.ts | 14 ++++++++++++++ packages/docusaurus/src/server/configValidation.ts | 3 +++ .../docusaurus/src/server/plugins/synthetic.ts | 1 + .../markdown-features-diagrams.mdx | 13 +++++++++++++ website/docusaurus.config.js | 3 +++ 10 files changed, 45 insertions(+), 3 deletions(-) diff --git a/packages/docusaurus-mdx-loader/src/loader.ts b/packages/docusaurus-mdx-loader/src/loader.ts index 6b0fe69b46e0..12d1500dc989 100644 --- a/packages/docusaurus-mdx-loader/src/loader.ts +++ b/packages/docusaurus-mdx-loader/src/loader.ts @@ -39,7 +39,7 @@ const pragma = ` const DEFAULT_OPTIONS: MDXOptions = { rehypePlugins: [], - remarkPlugins: [unwrapMdxCodeBlocks, emoji, headings, toc, mermaid], + remarkPlugins: [unwrapMdxCodeBlocks, emoji, headings, toc], beforeDefaultRemarkPlugins: [], beforeDefaultRehypePlugins: [], }; @@ -68,6 +68,7 @@ export type Options = Partial & { metadata: {[key: string]: unknown}; }) => {[key: string]: unknown}; filepath: string; + mermaid?: boolean; }; /** @@ -150,11 +151,13 @@ export async function mdxLoader( const hasFrontMatter = Object.keys(frontMatter).length > 0; if (!compilerCache.has(this.query)) { + const mermaidOptions = reqOptions.mermaid === true ? [mermaid] : []; const options: Options = { ...reqOptions, remarkPlugins: [ ...(reqOptions.beforeDefaultRemarkPlugins ?? []), ...DEFAULT_OPTIONS.remarkPlugins, + ...mermaidOptions, [ transformImage, { diff --git a/packages/docusaurus-plugin-content-blog/src/index.ts b/packages/docusaurus-plugin-content-blog/src/index.ts index 2b0355a0f3f1..629d2c6b7f87 100644 --- a/packages/docusaurus-plugin-content-blog/src/index.ts +++ b/packages/docusaurus-plugin-content-blog/src/index.ts @@ -465,6 +465,7 @@ export default async function pluginContentBlog( (author) => author.imageURL, ), }), + mermaid: siteConfig.markdown?.mermaid, }, }, { diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index afbb809fb718..2db423f93bbb 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -379,6 +379,7 @@ export default async function pluginContentDocs( }) => ({ image: frontMatter.image, }), + mermaid: siteConfig.markdown?.mermaid, }, }, { diff --git a/packages/docusaurus-plugin-content-pages/src/index.ts b/packages/docusaurus-plugin-content-pages/src/index.ts index a9051e4545e6..5a96e7dc92a9 100644 --- a/packages/docusaurus-plugin-content-pages/src/index.ts +++ b/packages/docusaurus-plugin-content-pages/src/index.ts @@ -221,6 +221,7 @@ export default function pluginContentPages( `${docuHash(aliasedSource)}.json`, ); }, + mermaid: siteConfig.markdown?.mermaid, }, }, { diff --git a/packages/docusaurus-theme-classic/src/theme/useMermaid.tsx b/packages/docusaurus-theme-classic/src/theme/useMermaid.tsx index 3394673c10d0..a3927d3a9093 100644 --- a/packages/docusaurus-theme-classic/src/theme/useMermaid.tsx +++ b/packages/docusaurus-theme-classic/src/theme/useMermaid.tsx @@ -9,6 +9,7 @@ import {useEffect} from 'react'; import mermaid from 'mermaid'; import {useThemeConfig} from '@docusaurus/theme-common'; import useIsBrowser from '@docusaurus/useIsBrowser'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import type mermaidAPI from 'mermaid/mermaidAPI'; import type {ThemeConfig} from '@docusaurus/theme-common'; @@ -43,12 +44,13 @@ function getTheme( } export default function useMermaid(): void { + const {siteConfig} = useDocusaurusContext(); const themeConfig = useThemeConfig(); const isBrowser = useIsBrowser(); // Watch for changes in theme in the HTML attribute `data-theme`. useEffect(() => { - if (isBrowser) { + if (siteConfig.markdown?.mermaid === true && isBrowser) { const html: HTMLHtmlElement = document.querySelector('html')!; const init = (target: HTMLHtmlElement): void => { const theme = getTheme(target, themeConfig.mermaid); @@ -91,5 +93,5 @@ export default function useMermaid(): void { }; } return undefined; - }, [isBrowser, themeConfig.mermaid]); + }, [isBrowser, siteConfig.markdown?.mermaid, themeConfig.mermaid]); } diff --git a/packages/docusaurus-types/src/index.d.ts b/packages/docusaurus-types/src/index.d.ts index ee4151930eee..1ef3b078d787 100644 --- a/packages/docusaurus-types/src/index.d.ts +++ b/packages/docusaurus-types/src/index.d.ts @@ -330,6 +330,20 @@ export type DocusaurusConfig = { */ jsLoader: 'babel' | ((isServer: boolean) => RuleSetRule); }; + /** Markdown-related options. */ + markdown?: { + /** + * Allow mermaid language code blocks to be rendered into Mermaid diagrams: + * + * - `true`: code blocks with language mermaid will be rendered. + * - `false` | `undefined` (default): code blocks with language mermaid + * will be left as code blocks. + * + * @see https://docusaurus.io/docs/markdown-features/diagrams/ + * @default false + */ + mermaid?: boolean; + }; }; /** diff --git a/packages/docusaurus/src/server/configValidation.ts b/packages/docusaurus/src/server/configValidation.ts index f5ef6a3cc9a4..2d28ff3f9d7a 100644 --- a/packages/docusaurus/src/server/configValidation.ts +++ b/packages/docusaurus/src/server/configValidation.ts @@ -233,6 +233,9 @@ export const ConfigSchema = Joi.object({ .try(Joi.string().equal('babel'), Joi.function()) .optional(), }).optional(), + markdown: Joi.object({ + mermaid: Joi.boolean().optional(), + }).optional(), }).messages({ 'docusaurus.configValidationWarning': 'Docusaurus config validation warning. Field {#label}: {#warningMessage}', diff --git a/packages/docusaurus/src/server/plugins/synthetic.ts b/packages/docusaurus/src/server/plugins/synthetic.ts index 5d4fe38b4d01..4240a7627813 100644 --- a/packages/docusaurus/src/server/plugins/synthetic.ts +++ b/packages/docusaurus/src/server/plugins/synthetic.ts @@ -106,6 +106,7 @@ export function createMDXFallbackPlugin({ // External MDX files might have front matter, just disable the warning isMDXPartialFrontMatterWarningDisabled: true, remarkPlugins: [admonitions], + mermaid: siteConfig.markdown?.mermaid, }; return { diff --git a/website/docs/guides/markdown-features/markdown-features-diagrams.mdx b/website/docs/guides/markdown-features/markdown-features-diagrams.mdx index 2baabd280b79..295fa311fdcd 100644 --- a/website/docs/guides/markdown-features/markdown-features-diagrams.mdx +++ b/website/docs/guides/markdown-features/markdown-features-diagrams.mdx @@ -9,6 +9,19 @@ slug: /markdown-features/diagrams Diagrams can be rendered using [Mermaid](https://mermaid-js.github.io/mermaid/) in a code block. +## Setup + +Enable Mermaid functionality by setting `markdown.mermaid` to true in your `docusaurus.config.js`. + +```js title=docusaurus.config.js +/** @type {import('@docusaurus/types').Config} */ +const config = { + markdown: { + mermaid: true, + }, +}; +``` + ## Usage Add a code block with language `mermaid`: diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 6885a87f8667..a56ffe1e9ed6 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -109,6 +109,9 @@ const config = { }, }), }, + markdown: { + mermaid: true, + }, onBrokenLinks: 'throw', onBrokenMarkdownLinks: 'warn', favicon: 'img/docusaurus.ico', From ed1f0443ba3beda212364c144c902bc871e6289a Mon Sep 17 00:00:00 2001 From: Samuel Wall Date: Fri, 27 May 2022 07:49:20 +0000 Subject: [PATCH 03/28] refactor: move mermaid components to own package --- .../docusaurus-theme-classic/package.json | 3 +- .../src/theme-classic.d.ts | 23 +----- .../src/theme/Layout/index.tsx | 2 +- .../src/theme/MDXComponents/index.tsx | 2 +- .../src/utils/useThemeConfig.ts | 11 --- packages/docusaurus-theme-mermaid/.npmignore | 3 + packages/docusaurus-theme-mermaid/README.md | 21 ++++++ .../docusaurus-theme-mermaid/package.json | 53 ++++++++++++++ .../src/__tests__/validateThemeConfig.test.ts | 71 +++++++++++++++++++ .../docusaurus-theme-mermaid/src/index.ts | 43 +++++++++++ .../src/theme-mermaid.d.ts | 45 ++++++++++++ .../src/theme/MDXComponents/Mermaid.tsx | 4 +- .../src/theme/Mermaid/index.tsx | 2 +- .../src/theme/useMermaid.tsx | 5 +- .../src/validateThemeConfig.ts | 31 ++++++++ .../tsconfig.client.json | 15 ++++ .../docusaurus-theme-mermaid/tsconfig.json | 14 ++++ 17 files changed, 305 insertions(+), 43 deletions(-) create mode 100644 packages/docusaurus-theme-mermaid/.npmignore create mode 100644 packages/docusaurus-theme-mermaid/README.md create mode 100644 packages/docusaurus-theme-mermaid/package.json create mode 100644 packages/docusaurus-theme-mermaid/src/__tests__/validateThemeConfig.test.ts create mode 100644 packages/docusaurus-theme-mermaid/src/index.ts create mode 100644 packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts rename packages/{docusaurus-theme-classic => docusaurus-theme-mermaid}/src/theme/MDXComponents/Mermaid.tsx (68%) rename packages/{docusaurus-theme-classic => docusaurus-theme-mermaid}/src/theme/Mermaid/index.tsx (95%) rename packages/{docusaurus-theme-classic => docusaurus-theme-mermaid}/src/theme/useMermaid.tsx (94%) create mode 100644 packages/docusaurus-theme-mermaid/src/validateThemeConfig.ts create mode 100644 packages/docusaurus-theme-mermaid/tsconfig.client.json create mode 100644 packages/docusaurus-theme-mermaid/tsconfig.json diff --git a/packages/docusaurus-theme-classic/package.json b/packages/docusaurus-theme-classic/package.json index 38ff68c427f4..f1cec82b4166 100644 --- a/packages/docusaurus-theme-classic/package.json +++ b/packages/docusaurus-theme-classic/package.json @@ -25,6 +25,7 @@ "@docusaurus/plugin-content-docs": "2.0.0-beta.20", "@docusaurus/plugin-content-pages": "2.0.0-beta.20", "@docusaurus/theme-common": "2.0.0-beta.20", + "@docusaurus/theme-mermaid": "2.0.0-beta.20", "@docusaurus/theme-translations": "2.0.0-beta.20", "@docusaurus/utils": "2.0.0-beta.20", "@docusaurus/utils-common": "2.0.0-beta.20", @@ -34,7 +35,6 @@ "copy-text-to-clipboard": "^3.0.1", "infima": "0.2.0-alpha.39", "lodash": "^4.17.21", - "mermaid": "^9.1.1", "nprogress": "^0.2.0", "postcss": "^8.4.14", "prism-react-renderer": "^1.3.3", @@ -47,7 +47,6 @@ "@docusaurus/module-type-aliases": "2.0.0-beta.20", "@docusaurus/types": "2.0.0-beta.20", "@types/mdx-js__react": "^1.5.5", - "@types/mermaid": "^8.2.9", "@types/nprogress": "^0.2.0", "@types/prismjs": "^1.26.0", "@types/rtlcss": "^3.5.0", diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index 2b89a1e4be5e..5b8274e872da 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -11,6 +11,7 @@ /// /// /// +/// // This file, like all the other ambient declaration files for plugins, is // needed for TS to understand our `@theme` alias. The export signatures are @@ -552,14 +553,6 @@ declare module '@theme/Heading' { export default function Heading(props: Props): JSX.Element; } -declare module '@theme/Mermaid' { - export interface Props { - value: string; - } - - export default function Mermaid(props: Props): JSX.Element; -} - declare module '@theme/Layout' { import type {ReactNode} from 'react'; @@ -675,14 +668,6 @@ declare module '@theme/MDXComponents/Pre' { export default function MDXPre(props: Props): JSX.Element; } -declare module '@theme/MDXComponents/Mermaid' { - export interface Props { - value: string; - } - - export default function MDXMermaid(props: Props): JSX.Element; -} - declare module '@theme/MDXComponents' { import type {ComponentType, ComponentProps} from 'react'; @@ -693,7 +678,6 @@ declare module '@theme/MDXComponents' { import type MDXDetails from '@theme/MDXComponents/Details'; import type MDXUl from '@theme/MDXComponents/Ul'; import type MDXImg from '@theme/MDXComponents/Img'; - import type MDXMermaid from '@theme/MDXComponents/Mermaid'; export type MDXComponentsObject = { readonly head: typeof MDXHead; @@ -709,7 +693,6 @@ declare module '@theme/MDXComponents' { readonly h4: (props: ComponentProps<'h4'>) => JSX.Element; readonly h5: (props: ComponentProps<'h5'>) => JSX.Element; readonly h6: (props: ComponentProps<'h6'>) => JSX.Element; - readonly mermaid: typeof MDXMermaid; // eslint-disable-next-line @typescript-eslint/no-explicit-any [tagName: string]: ComponentType; }; @@ -1296,7 +1279,3 @@ declare module '@theme/prism-include-languages' { PrismObject: typeof PrismNamespace, ): void; } - -declare module '@theme/useMermaid' { - export default function useMermaid(): void; -} diff --git a/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx b/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx index b9aae88c4051..7f0acffee47d 100644 --- a/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx @@ -13,6 +13,7 @@ import { ThemeClassNames, useKeyboardNavigation, } from '@docusaurus/theme-common'; +import useMermaid from '@docusaurus/theme-mermaid/theme/useMermaid'; import SkipToContent from '@theme/SkipToContent'; import AnnouncementBar from '@theme/AnnouncementBar'; import Navbar from '@theme/Navbar'; @@ -21,7 +22,6 @@ import LayoutProviders from '@theme/LayoutProviders'; import ErrorPageContent from '@theme/ErrorPageContent'; import './styles.css'; import type {Props} from '@theme/Layout'; -import useMermaid from '@theme/useMermaid'; export default function Layout(props: Props): JSX.Element { const { diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx b/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx index b6e406b071da..d6b6b240792e 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx @@ -6,6 +6,7 @@ */ import React from 'react'; +import MDXMermaid from '@docusaurus/theme-mermaid/theme/MDXComponents/Mermaid'; import MDXHead from '@theme/MDXComponents/Head'; import MDXCode from '@theme/MDXComponents/Code'; import MDXA from '@theme/MDXComponents/A'; @@ -14,7 +15,6 @@ import MDXDetails from '@theme/MDXComponents/Details'; import MDXHeading from '@theme/MDXComponents/Heading'; import MDXUl from '@theme/MDXComponents/Ul'; import MDXImg from '@theme/MDXComponents/Img'; -import MDXMermaid from '@theme/MDXComponents/Mermaid'; import type {MDXComponentsObject} from '@theme/MDXComponents'; diff --git a/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts b/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts index aa3237906a66..b160bf307c84 100644 --- a/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts +++ b/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts @@ -6,7 +6,6 @@ */ import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import type mermaidAPI from 'mermaid/mermaidAPI'; import type {PrismTheme} from 'prism-react-renderer'; import type {DeepPartial} from 'utility-types'; import type {MagicCommentConfig} from './codeBlockUtils'; @@ -103,15 +102,6 @@ export type TableOfContents = { maxHeadingLevel: number; }; -export type MermaidConfig = { - theme?: { - light: mermaidAPI.Theme; - dark: mermaidAPI.Theme; - [htmlTheme: string]: mermaidAPI.Theme; - }; - config?: mermaidAPI.Config; -}; - // Theme config after validation/normalization export type ThemeConfig = { docs: { @@ -135,7 +125,6 @@ export type ThemeConfig = { image?: string; metadata: {[key: string]: string}[]; tableOfContents: TableOfContents; - mermaid?: MermaidConfig; }; // User-provided theme config, unnormalized diff --git a/packages/docusaurus-theme-mermaid/.npmignore b/packages/docusaurus-theme-mermaid/.npmignore new file mode 100644 index 000000000000..03c9ae1e1b54 --- /dev/null +++ b/packages/docusaurus-theme-mermaid/.npmignore @@ -0,0 +1,3 @@ +.tsbuildinfo* +tsconfig* +__tests__ diff --git a/packages/docusaurus-theme-mermaid/README.md b/packages/docusaurus-theme-mermaid/README.md new file mode 100644 index 000000000000..ec903286aad8 --- /dev/null +++ b/packages/docusaurus-theme-mermaid/README.md @@ -0,0 +1,21 @@ +# Docusaurus Theme Mermaid + +The mermaid components for Docusaurus. + +## Installation + +Add `docusaurus/theme-mermaid` to your package: + +```bash +npm i @docusaurus/theme-mermaid +# or +yarn add @docusaurus/theme-mermaid +``` + +## Swizzling components + +```bash +$ npm swizzle @docusaurus/theme-mermaid [component name] +``` + +All components used by this theme can be found [here](https://github.com/facebook/docusaurus/tree/main/packages/docusaurus-theme-mermaid/src/theme) diff --git a/packages/docusaurus-theme-mermaid/package.json b/packages/docusaurus-theme-mermaid/package.json new file mode 100644 index 000000000000..f0a22ab45b69 --- /dev/null +++ b/packages/docusaurus-theme-mermaid/package.json @@ -0,0 +1,53 @@ +{ + "name": "@docusaurus/theme-mermaid", + "version": "2.0.0-beta.20", + "description": "Mermaid components for Docusaurus.", + "main": "lib/index.js", + "exports": { + "./theme/MDXComponents/Mermaid": "./lib/theme/MDXComponents/Mermaid.js", + "./theme/useMermaid": "./lib/theme/useMermaid.js", + "./theme/Mermaid": "./lib/theme/Mermaid/index.js", + ".": "./lib/index.js" + }, + "types": "src/theme-mermaid.d.ts", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/facebook/docusaurus.git", + "directory": "packages/docusaurus-theme-mermaid" + }, + "license": "MIT", + "scripts": { + "build": "tsc --build && node ../../admin/scripts/copyUntypedFiles.js && prettier --config ../../.prettierrc --write \"lib/theme/**/*.js\"", + "watch": "run-p -c copy:watch build:watch", + "build:watch": "tsc --build --watch", + "copy:watch": "node ../../admin/scripts/copyUntypedFiles.js --watch" + }, + "dependencies": { + "@docusaurus/core": "2.0.0-beta.20", + "@docusaurus/theme-common": "2.0.0-beta.20", + "@docusaurus/theme-translations": "2.0.0-beta.20", + "@docusaurus/utils": "2.0.0-beta.20", + "@docusaurus/utils-common": "2.0.0-beta.20", + "@docusaurus/utils-validation": "2.0.0-beta.20", + "@mdx-js/react": "^1.6.22", + "mermaid": "^9.1.1", + "tslib": "^2.4.0" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "2.0.0-beta.20", + "@docusaurus/types": "2.0.0-beta.20", + "@types/mdx-js__react": "^1.5.5", + "@types/mermaid": "^8.2.9", + "react-test-renderer": "^17.0.2" + }, + "peerDependencies": { + "react": "^16.8.4 || ^17.0.0", + "react-dom": "^16.8.4 || ^17.0.0" + }, + "engines": { + "node": ">=14" + } +} diff --git a/packages/docusaurus-theme-mermaid/src/__tests__/validateThemeConfig.test.ts b/packages/docusaurus-theme-mermaid/src/__tests__/validateThemeConfig.test.ts new file mode 100644 index 000000000000..4c6962b2f215 --- /dev/null +++ b/packages/docusaurus-theme-mermaid/src/__tests__/validateThemeConfig.test.ts @@ -0,0 +1,71 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {validateThemeConfig} from '../validateThemeConfig'; +import type {Joi} from '@docusaurus/utils-validation'; + +function testValidateThemeConfig(themeConfig: {[key: string]: unknown}) { + function validate( + schema: Joi.ObjectSchema<{[key: string]: unknown}>, + cfg: {[key: string]: unknown}, + ) { + const {value, error} = schema.validate(cfg, { + convert: false, + }); + if (error) { + throw error; + } + return value; + } + + return validateThemeConfig({validate, themeConfig}); +} + +describe('validateThemeConfig', () => { + it('undefined config', () => { + const mermaid = undefined; + expect(testValidateThemeConfig({mermaid})).toEqual({}); + }); + + it('nonexistent config', () => { + expect(testValidateThemeConfig({})).toEqual({}); + }); + + it('empty config', () => { + const mermaid = {}; + expect(testValidateThemeConfig({mermaid})).toEqual({ + mermaid: {}, + }); + }); + + it('theme', () => { + const mermaid = { + theme: { + light: 'light', + dark: 'dark', + }, + }; + expect(testValidateThemeConfig({mermaid})).toEqual({ + mermaid: { + ...mermaid, + }, + }); + }); + + it('config', () => { + const mermaid = { + config: { + fontFamily: 'Ariel', + }, + }; + expect(testValidateThemeConfig({mermaid})).toEqual({ + mermaid: { + ...mermaid, + }, + }); + }); +}); diff --git a/packages/docusaurus-theme-mermaid/src/index.ts b/packages/docusaurus-theme-mermaid/src/index.ts new file mode 100644 index 000000000000..2c1c33c4bf15 --- /dev/null +++ b/packages/docusaurus-theme-mermaid/src/index.ts @@ -0,0 +1,43 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {readDefaultCodeTranslationMessages} from '@docusaurus/theme-translations'; +import type {LoadContext, Plugin} from '@docusaurus/types'; + +export default function themeMermaid(context: LoadContext): Plugin { + const { + i18n: {currentLocale}, + } = context; + + return { + name: 'docusaurus-theme-mermaid', + + getThemePath() { + return '../lib/theme'; + }, + getTypeScriptThemePath() { + return '../src/theme'; + }, + + getDefaultCodeTranslationMessages() { + return readDefaultCodeTranslationMessages({ + locale: currentLocale, + name: 'theme-mermaid', + }); + }, + + contentLoaded() {}, + + async postBuild() {}, + + injectHtmlTags() { + return {}; + }, + }; +} + +export {validateThemeConfig} from './validateThemeConfig'; diff --git a/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts b/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts new file mode 100644 index 000000000000..3f0fef2229a1 --- /dev/null +++ b/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts @@ -0,0 +1,45 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/// + +declare module '@docusaurus/theme-mermaid' { + import type {DeepPartial} from 'utility-types'; + import type mermaidAPI from 'mermaid/mermaidAPI'; + + export type ThemeConfig = { + mermaid: { + theme?: { + light: mermaidAPI.Theme; + dark: mermaidAPI.Theme; + [htmlTheme: string]: mermaidAPI.Theme; + }; + config?: mermaidAPI.Config; + }; + }; + export type UserThemeConfig = DeepPartial; +} + +declare module '@docusaurus/theme-mermaid/theme/MDXComponents/Mermaid' { + export interface Props { + value: string; + } + + export default function MDXMermaid(props: Props): JSX.Element; +} + +declare module '@docusaurus/theme-mermaid/theme/useMermaid' { + export default function useMermaid(): void; +} + +declare module '@docusaurus/theme-mermaid/theme/Mermaid' { + export interface Props { + value: string; + } + + export default function Mermaid(props: Props): JSX.Element; +} diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Mermaid.tsx b/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/Mermaid.tsx similarity index 68% rename from packages/docusaurus-theme-classic/src/theme/MDXComponents/Mermaid.tsx rename to packages/docusaurus-theme-mermaid/src/theme/MDXComponents/Mermaid.tsx index 1d9c77d2c51d..61a27398a154 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Mermaid.tsx +++ b/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/Mermaid.tsx @@ -6,8 +6,8 @@ */ import React from 'react'; -import Mermaid from '@theme/Mermaid'; -import type {Props} from '@theme/MDXComponents/Mermaid'; +import Mermaid from '@docusaurus/theme-mermaid/theme/Mermaid'; +import type {Props} from '@docusaurus/theme-mermaid/theme/MDXComponents/Mermaid'; export default function MDXMermaid(props: Props): JSX.Element { return ; diff --git a/packages/docusaurus-theme-classic/src/theme/Mermaid/index.tsx b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx similarity index 95% rename from packages/docusaurus-theme-classic/src/theme/Mermaid/index.tsx rename to packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx index 3cda5dc631a1..18c9ef6c3acf 100644 --- a/packages/docusaurus-theme-classic/src/theme/Mermaid/index.tsx +++ b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx @@ -8,7 +8,7 @@ import React, {useEffect, useState} from 'react'; import useIsBrowser from '@docusaurus/useIsBrowser'; import mermaid from 'mermaid'; -import type {Props} from '@theme/Mermaid'; +import type {Props} from '@docusaurus/theme-mermaid/theme/Mermaid'; /** * Assign a unique ID to each mermaid svg as per requirements diff --git a/packages/docusaurus-theme-classic/src/theme/useMermaid.tsx b/packages/docusaurus-theme-mermaid/src/theme/useMermaid.tsx similarity index 94% rename from packages/docusaurus-theme-classic/src/theme/useMermaid.tsx rename to packages/docusaurus-theme-mermaid/src/theme/useMermaid.tsx index a3927d3a9093..6af9b2901c1b 100644 --- a/packages/docusaurus-theme-classic/src/theme/useMermaid.tsx +++ b/packages/docusaurus-theme-mermaid/src/theme/useMermaid.tsx @@ -7,11 +7,10 @@ import {useEffect} from 'react'; import mermaid from 'mermaid'; -import {useThemeConfig} from '@docusaurus/theme-common'; import useIsBrowser from '@docusaurus/useIsBrowser'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import type mermaidAPI from 'mermaid/mermaidAPI'; -import type {ThemeConfig} from '@docusaurus/theme-common'; +import type {ThemeConfig} from '@docusaurus/theme-mermaid'; const DEFAULT_DARK_THEME = 'dark' as mermaidAPI.Theme.Dark; const DEFAULT_LIGHT_THEME = 'default' as mermaidAPI.Theme.Default; @@ -45,7 +44,7 @@ function getTheme( export default function useMermaid(): void { const {siteConfig} = useDocusaurusContext(); - const themeConfig = useThemeConfig(); + const themeConfig = siteConfig.themeConfig as ThemeConfig; const isBrowser = useIsBrowser(); // Watch for changes in theme in the HTML attribute `data-theme`. diff --git a/packages/docusaurus-theme-mermaid/src/validateThemeConfig.ts b/packages/docusaurus-theme-mermaid/src/validateThemeConfig.ts new file mode 100644 index 000000000000..0ee3866a0424 --- /dev/null +++ b/packages/docusaurus-theme-mermaid/src/validateThemeConfig.ts @@ -0,0 +1,31 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {Joi} from '@docusaurus/utils-validation'; +import type { + ThemeConfig, + ThemeConfigValidationContext, +} from '@docusaurus/types'; + +export const Schema = Joi.object({ + mermaid: Joi.object({ + theme: Joi.object({ + dark: Joi.string().optional(), + light: Joi.string().optional(), + }).optional(), + config: Joi.object().optional(), + }) + .label('themeConfig.mermaid') + .optional(), +}); + +export function validateThemeConfig({ + validate, + themeConfig, +}: ThemeConfigValidationContext): ThemeConfig { + return validate(Schema, themeConfig); +} diff --git a/packages/docusaurus-theme-mermaid/tsconfig.client.json b/packages/docusaurus-theme-mermaid/tsconfig.client.json new file mode 100644 index 000000000000..1f0c48f14b25 --- /dev/null +++ b/packages/docusaurus-theme-mermaid/tsconfig.client.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "noEmit": false, + "composite": true, + "incremental": true, + "tsBuildInfoFile": "./lib/.tsbuildinfo-client", + "rootDir": "src", + "outDir": "lib", + "module": "esnext", + "target": "esnext" + }, + "include": ["src/theme", "src/*.d.ts"], + "exclude": ["**/__tests__/**"] +} diff --git a/packages/docusaurus-theme-mermaid/tsconfig.json b/packages/docusaurus-theme-mermaid/tsconfig.json new file mode 100644 index 000000000000..7c1bb85ac462 --- /dev/null +++ b/packages/docusaurus-theme-mermaid/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.json", + "references": [{"path": "./tsconfig.client.json"}], + "compilerOptions": { + "noEmit": false, + "incremental": true, + "tsBuildInfoFile": "./lib/.tsbuildinfo", + "module": "commonjs", + "rootDir": "src", + "outDir": "lib" + }, + "include": ["src"], + "exclude": ["src/theme", "**/__tests__/**"] +} From ed1f21cf1bbf60c4f3dca7a10c32c570e6b059d4 Mon Sep 17 00:00:00 2001 From: Samuel Wall Date: Fri, 27 May 2022 10:39:51 +0000 Subject: [PATCH 04/28] refactor: remove theme-classic mermaid dependency --- packages/docusaurus-theme-classic/package.json | 1 - .../src/theme-classic.d.ts | 1 - .../src/theme/Layout/index.tsx | 2 -- .../src/theme/MDXComponents/index.tsx | 2 -- packages/docusaurus-theme-mermaid/src/index.ts | 8 -------- .../src/theme-mermaid.d.ts | 6 +++--- .../src/theme/MDXComponents/Mermaid.tsx | 6 ++++-- .../src/theme/MDXComponents/index.ts | 13 +++++++++++++ .../src/theme/Mermaid/index.tsx | 3 +-- .../src/theme/useMermaid.tsx | 9 ++++++--- .../markdown-features-diagrams.mdx | 15 ++++++++++----- website/docusaurus.config.js | 1 + website/package.json | 1 + 13 files changed, 39 insertions(+), 29 deletions(-) create mode 100644 packages/docusaurus-theme-mermaid/src/theme/MDXComponents/index.ts diff --git a/packages/docusaurus-theme-classic/package.json b/packages/docusaurus-theme-classic/package.json index f1cec82b4166..577babee2892 100644 --- a/packages/docusaurus-theme-classic/package.json +++ b/packages/docusaurus-theme-classic/package.json @@ -25,7 +25,6 @@ "@docusaurus/plugin-content-docs": "2.0.0-beta.20", "@docusaurus/plugin-content-pages": "2.0.0-beta.20", "@docusaurus/theme-common": "2.0.0-beta.20", - "@docusaurus/theme-mermaid": "2.0.0-beta.20", "@docusaurus/theme-translations": "2.0.0-beta.20", "@docusaurus/utils": "2.0.0-beta.20", "@docusaurus/utils-common": "2.0.0-beta.20", diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index 5b8274e872da..bc9b9c9bbaf3 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -11,7 +11,6 @@ /// /// /// -/// // This file, like all the other ambient declaration files for plugins, is // needed for TS to understand our `@theme` alias. The export signatures are diff --git a/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx b/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx index 7f0acffee47d..c5503edcaaa2 100644 --- a/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx @@ -13,7 +13,6 @@ import { ThemeClassNames, useKeyboardNavigation, } from '@docusaurus/theme-common'; -import useMermaid from '@docusaurus/theme-mermaid/theme/useMermaid'; import SkipToContent from '@theme/SkipToContent'; import AnnouncementBar from '@theme/AnnouncementBar'; import Navbar from '@theme/Navbar'; @@ -34,7 +33,6 @@ export default function Layout(props: Props): JSX.Element { } = props; useKeyboardNavigation(); - useMermaid(); return ( diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx b/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx index d6b6b240792e..82e7c5ac6b12 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx @@ -6,7 +6,6 @@ */ import React from 'react'; -import MDXMermaid from '@docusaurus/theme-mermaid/theme/MDXComponents/Mermaid'; import MDXHead from '@theme/MDXComponents/Head'; import MDXCode from '@theme/MDXComponents/Code'; import MDXA from '@theme/MDXComponents/A'; @@ -32,7 +31,6 @@ const MDXComponents: MDXComponentsObject = { h4: (props) => , h5: (props) => , h6: (props) => , - mermaid: MDXMermaid, }; export default MDXComponents; diff --git a/packages/docusaurus-theme-mermaid/src/index.ts b/packages/docusaurus-theme-mermaid/src/index.ts index 2c1c33c4bf15..2d2356c568d8 100644 --- a/packages/docusaurus-theme-mermaid/src/index.ts +++ b/packages/docusaurus-theme-mermaid/src/index.ts @@ -29,14 +29,6 @@ export default function themeMermaid(context: LoadContext): Plugin { name: 'theme-mermaid', }); }, - - contentLoaded() {}, - - async postBuild() {}, - - injectHtmlTags() { - return {}; - }, }; } diff --git a/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts b/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts index 3f0fef2229a1..022535425141 100644 --- a/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts +++ b/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts @@ -24,7 +24,7 @@ declare module '@docusaurus/theme-mermaid' { export type UserThemeConfig = DeepPartial; } -declare module '@docusaurus/theme-mermaid/theme/MDXComponents/Mermaid' { +declare module '@theme/MDXComponents/Mermaid' { export interface Props { value: string; } @@ -32,11 +32,11 @@ declare module '@docusaurus/theme-mermaid/theme/MDXComponents/Mermaid' { export default function MDXMermaid(props: Props): JSX.Element; } -declare module '@docusaurus/theme-mermaid/theme/useMermaid' { +declare module '@theme/useMermaid' { export default function useMermaid(): void; } -declare module '@docusaurus/theme-mermaid/theme/Mermaid' { +declare module '@theme/Mermaid' { export interface Props { value: string; } diff --git a/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/Mermaid.tsx b/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/Mermaid.tsx index 61a27398a154..4a85000dc519 100644 --- a/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/Mermaid.tsx +++ b/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/Mermaid.tsx @@ -6,9 +6,11 @@ */ import React from 'react'; -import Mermaid from '@docusaurus/theme-mermaid/theme/Mermaid'; -import type {Props} from '@docusaurus/theme-mermaid/theme/MDXComponents/Mermaid'; +import Mermaid from '@theme/Mermaid'; +import type {Props} from '@theme/MDXComponents/Mermaid'; +import useMermaid from '@theme/useMermaid'; export default function MDXMermaid(props: Props): JSX.Element { + useMermaid(); return ; } diff --git a/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/index.ts b/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/index.ts new file mode 100644 index 000000000000..16f1526e0f2b --- /dev/null +++ b/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/index.ts @@ -0,0 +1,13 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import MDXComponents from '@theme-init/MDXComponents'; +import MDXMermaid from '@theme/MDXComponents/Mermaid'; + +export default { + ...MDXComponents, + mermaid: MDXMermaid, +}; diff --git a/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx index 18c9ef6c3acf..5b0f2b5aea98 100644 --- a/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx +++ b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx @@ -8,7 +8,7 @@ import React, {useEffect, useState} from 'react'; import useIsBrowser from '@docusaurus/useIsBrowser'; import mermaid from 'mermaid'; -import type {Props} from '@docusaurus/theme-mermaid/theme/Mermaid'; +import type {Props} from '@theme/Mermaid'; /** * Assign a unique ID to each mermaid svg as per requirements @@ -58,7 +58,6 @@ export default function Mermaid({value}: Props): JSX.Element { } return undefined; }, [isBrowser, value]); - // eslint-disable-next-line react/no-danger return
; } diff --git a/packages/docusaurus-theme-mermaid/src/theme/useMermaid.tsx b/packages/docusaurus-theme-mermaid/src/theme/useMermaid.tsx index 6af9b2901c1b..ae89587b4da7 100644 --- a/packages/docusaurus-theme-mermaid/src/theme/useMermaid.tsx +++ b/packages/docusaurus-theme-mermaid/src/theme/useMermaid.tsx @@ -42,6 +42,8 @@ function getTheme( return options?.theme?.[htmlTheme] ?? options?.config?.theme ?? defaultTheme; } +let observer: MutationObserver | undefined; + export default function useMermaid(): void { const {siteConfig} = useDocusaurusContext(); const themeConfig = siteConfig.themeConfig as ThemeConfig; @@ -49,7 +51,7 @@ export default function useMermaid(): void { // Watch for changes in theme in the HTML attribute `data-theme`. useEffect(() => { - if (siteConfig.markdown?.mermaid === true && isBrowser) { + if (!observer && siteConfig.markdown?.mermaid === true && isBrowser) { const html: HTMLHtmlElement = document.querySelector('html')!; const init = (target: HTMLHtmlElement): void => { const theme = getTheme(target, themeConfig.mermaid); @@ -67,7 +69,7 @@ export default function useMermaid(): void { html.setAttribute('data-mermaid', theme); }; - const observer = new MutationObserver((mutations) => { + observer = new MutationObserver((mutations) => { for (const mutation of mutations) { if ( mutation.type !== 'attributes' || @@ -85,7 +87,8 @@ export default function useMermaid(): void { observer.observe(html, {attributes: true}); return () => { try { - observer.disconnect(); + (observer as MutationObserver).disconnect(); + observer = undefined; } catch { // Do nothing } diff --git a/website/docs/guides/markdown-features/markdown-features-diagrams.mdx b/website/docs/guides/markdown-features/markdown-features-diagrams.mdx index 295fa311fdcd..8115655b7f98 100644 --- a/website/docs/guides/markdown-features/markdown-features-diagrams.mdx +++ b/website/docs/guides/markdown-features/markdown-features-diagrams.mdx @@ -9,9 +9,13 @@ slug: /markdown-features/diagrams Diagrams can be rendered using [Mermaid](https://mermaid-js.github.io/mermaid/) in a code block. -## Setup +## Installation {#installation} -Enable Mermaid functionality by setting `markdown.mermaid` to true in your `docusaurus.config.js`. +```bash npm2yarn +npm install --save @docusaurus/theme-mermaid +``` + +Enable Mermaid functionality by adding plugin `@docusaurus/theme-mermaid` and setting `markdown.mermaid` to `true` in your `docusaurus.config.js`. ```js title=docusaurus.config.js /** @type {import('@docusaurus/types').Config} */ @@ -19,10 +23,11 @@ const config = { markdown: { mermaid: true, }, + plugins: ['@docusaurus/theme-mermaid'], }; ``` -## Usage +## Usage {#usage} Add a code block with language `mermaid`: @@ -46,7 +51,7 @@ graph TD; See the [Mermaid syntax documentation](https://mermaid-js.github.io/mermaid/#/./n00b-syntaxReference) for more information on the Mermaid syntax. -## Theming +## Theming {#theming} The diagram dark and light themes can be changed by setting `theme` values in the `themeConfig` in your `docusaurus.config.js`. @@ -62,7 +67,7 @@ themeConfig: See the [Mermaid theme documentation](https://mermaid-js.github.io/mermaid/#/theming) for more information on theming Mermaid diagrams. -## Mermaid Config +## Mermaid Config {#configuration} Mermaid config can be configured through the `config` object in `themeConfig` in your `docusaurus.config.js`: diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index a56ffe1e9ed6..fe3baa8ae016 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -274,6 +274,7 @@ const config = { ], }, ], + '@docusaurus/theme-mermaid', ...dogfoodingPluginInstances, ], presets: [ diff --git a/website/package.json b/website/package.json index 8f9c678d1271..10f7ad8718ff 100644 --- a/website/package.json +++ b/website/package.json @@ -44,6 +44,7 @@ "@docusaurus/remark-plugin-npm2yarn": "2.0.0-beta.20", "@docusaurus/theme-classic": "2.0.0-beta.20", "@docusaurus/theme-common": "2.0.0-beta.20", + "@docusaurus/theme-mermaid": "2.0.0-beta.20", "@docusaurus/theme-live-codeblock": "2.0.0-beta.20", "@docusaurus/utils": "2.0.0-beta.20", "@docusaurus/utils-common": "2.0.0-beta.20", From 777c086a9f8e6a83299f02e042a7cc677c9a258a Mon Sep 17 00:00:00 2001 From: Samuel Wall Date: Fri, 27 May 2022 10:55:10 +0000 Subject: [PATCH 05/28] refactor(mdx-loader): markdown config option --- packages/docusaurus-mdx-loader/src/loader.ts | 5 +++-- packages/docusaurus-plugin-content-blog/src/index.ts | 2 +- packages/docusaurus-plugin-content-docs/src/index.ts | 2 +- packages/docusaurus-plugin-content-pages/src/index.ts | 2 +- packages/docusaurus/src/server/configValidation.ts | 4 +--- packages/docusaurus/src/server/plugins/synthetic.ts | 2 +- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/docusaurus-mdx-loader/src/loader.ts b/packages/docusaurus-mdx-loader/src/loader.ts index 12d1500dc989..da7324c8e725 100644 --- a/packages/docusaurus-mdx-loader/src/loader.ts +++ b/packages/docusaurus-mdx-loader/src/loader.ts @@ -68,7 +68,7 @@ export type Options = Partial & { metadata: {[key: string]: unknown}; }) => {[key: string]: unknown}; filepath: string; - mermaid?: boolean; + markdown?: {mermaid?: boolean}; }; /** @@ -151,7 +151,8 @@ export async function mdxLoader( const hasFrontMatter = Object.keys(frontMatter).length > 0; if (!compilerCache.has(this.query)) { - const mermaidOptions = reqOptions.mermaid === true ? [mermaid] : []; + const mermaidOptions = + reqOptions.markdown?.mermaid === true ? [mermaid] : []; const options: Options = { ...reqOptions, remarkPlugins: [ diff --git a/packages/docusaurus-plugin-content-blog/src/index.ts b/packages/docusaurus-plugin-content-blog/src/index.ts index 629d2c6b7f87..3ab43317d469 100644 --- a/packages/docusaurus-plugin-content-blog/src/index.ts +++ b/packages/docusaurus-plugin-content-blog/src/index.ts @@ -465,7 +465,7 @@ export default async function pluginContentBlog( (author) => author.imageURL, ), }), - mermaid: siteConfig.markdown?.mermaid, + markdown: siteConfig.markdown, }, }, { diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index 2db423f93bbb..e54c5b8cf431 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -379,7 +379,7 @@ export default async function pluginContentDocs( }) => ({ image: frontMatter.image, }), - mermaid: siteConfig.markdown?.mermaid, + markdown: siteConfig.markdown, }, }, { diff --git a/packages/docusaurus-plugin-content-pages/src/index.ts b/packages/docusaurus-plugin-content-pages/src/index.ts index 5a96e7dc92a9..7c1680bed138 100644 --- a/packages/docusaurus-plugin-content-pages/src/index.ts +++ b/packages/docusaurus-plugin-content-pages/src/index.ts @@ -221,7 +221,7 @@ export default function pluginContentPages( `${docuHash(aliasedSource)}.json`, ); }, - mermaid: siteConfig.markdown?.mermaid, + markdown: siteConfig.markdown, }, }, { diff --git a/packages/docusaurus/src/server/configValidation.ts b/packages/docusaurus/src/server/configValidation.ts index 2d28ff3f9d7a..99cdacbcfdcc 100644 --- a/packages/docusaurus/src/server/configValidation.ts +++ b/packages/docusaurus/src/server/configValidation.ts @@ -233,9 +233,7 @@ export const ConfigSchema = Joi.object({ .try(Joi.string().equal('babel'), Joi.function()) .optional(), }).optional(), - markdown: Joi.object({ - mermaid: Joi.boolean().optional(), - }).optional(), + markdown: Joi.object().unknown().optional(), }).messages({ 'docusaurus.configValidationWarning': 'Docusaurus config validation warning. Field {#label}: {#warningMessage}', diff --git a/packages/docusaurus/src/server/plugins/synthetic.ts b/packages/docusaurus/src/server/plugins/synthetic.ts index 4240a7627813..0513addc46a0 100644 --- a/packages/docusaurus/src/server/plugins/synthetic.ts +++ b/packages/docusaurus/src/server/plugins/synthetic.ts @@ -106,7 +106,7 @@ export function createMDXFallbackPlugin({ // External MDX files might have front matter, just disable the warning isMDXPartialFrontMatterWarningDisabled: true, remarkPlugins: [admonitions], - mermaid: siteConfig.markdown?.mermaid, + markdown: siteConfig.markdown, }; return { From 3a32f60a6b3904093189bf24832656c9ee7e231e Mon Sep 17 00:00:00 2001 From: Samuel Wall Date: Fri, 27 May 2022 10:58:26 +0000 Subject: [PATCH 06/28] refactor(theme-mermaid): remove exports --- packages/docusaurus-theme-mermaid/package.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/docusaurus-theme-mermaid/package.json b/packages/docusaurus-theme-mermaid/package.json index f0a22ab45b69..8a46440b149a 100644 --- a/packages/docusaurus-theme-mermaid/package.json +++ b/packages/docusaurus-theme-mermaid/package.json @@ -3,12 +3,6 @@ "version": "2.0.0-beta.20", "description": "Mermaid components for Docusaurus.", "main": "lib/index.js", - "exports": { - "./theme/MDXComponents/Mermaid": "./lib/theme/MDXComponents/Mermaid.js", - "./theme/useMermaid": "./lib/theme/useMermaid.js", - "./theme/Mermaid": "./lib/theme/Mermaid/index.js", - ".": "./lib/index.js" - }, "types": "src/theme-mermaid.d.ts", "publishConfig": { "access": "public" From 11836a0c6730f3748e7376642126d2ebf80f40f1 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Fri, 27 May 2022 19:30:15 +0800 Subject: [PATCH 07/28] little refactors --- packages/docusaurus-mdx-loader/src/loader.ts | 33 +++++++++---------- .../src/index.ts | 2 +- .../src/index.ts | 2 +- .../src/index.ts | 2 +- .../src/theme-mermaid.d.ts | 6 ++++ .../src/theme/MDXComponents/index.ts | 1 + .../src/theme/Mermaid/index.tsx | 21 +++++------- .../src/theme/useMermaid.tsx | 21 +++++++----- packages/docusaurus-types/src/index.d.ts | 28 ++++++++-------- 9 files changed, 61 insertions(+), 55 deletions(-) diff --git a/packages/docusaurus-mdx-loader/src/loader.ts b/packages/docusaurus-mdx-loader/src/loader.ts index da7324c8e725..e86b68c6fc01 100644 --- a/packages/docusaurus-mdx-loader/src/loader.ts +++ b/packages/docusaurus-mdx-loader/src/loader.ts @@ -24,6 +24,7 @@ import transformImage from './remark/transformImage'; import transformLinks from './remark/transformLinks'; import mermaid from './remark/mermaid'; +import type {MarkdownConfig} from '@docusaurus/types'; import type {LoaderContext} from 'webpack'; import type {Processor, Plugin} from 'unified'; @@ -56,20 +57,20 @@ export type MDXOptions = { beforeDefaultRehypePlugins: MDXPlugin[]; }; -export type Options = Partial & { - staticDirs: string[]; - siteDir: string; - isMDXPartial?: (filePath: string) => boolean; - isMDXPartialFrontMatterWarningDisabled?: boolean; - removeContentTitle?: boolean; - metadataPath?: string | ((filePath: string) => string); - createAssets?: (metadata: { - frontMatter: {[key: string]: unknown}; - metadata: {[key: string]: unknown}; - }) => {[key: string]: unknown}; - filepath: string; - markdown?: {mermaid?: boolean}; -}; +export type Options = Partial & + MarkdownConfig & { + staticDirs: string[]; + siteDir: string; + isMDXPartial?: (filePath: string) => boolean; + isMDXPartialFrontMatterWarningDisabled?: boolean; + removeContentTitle?: boolean; + metadataPath?: string | ((filePath: string) => string); + createAssets?: (metadata: { + frontMatter: {[key: string]: unknown}; + metadata: {[key: string]: unknown}; + }) => {[key: string]: unknown}; + filepath: string; + }; /** * When this throws, it generally means that there's no metadata file associated @@ -151,14 +152,12 @@ export async function mdxLoader( const hasFrontMatter = Object.keys(frontMatter).length > 0; if (!compilerCache.has(this.query)) { - const mermaidOptions = - reqOptions.markdown?.mermaid === true ? [mermaid] : []; const options: Options = { ...reqOptions, remarkPlugins: [ ...(reqOptions.beforeDefaultRemarkPlugins ?? []), ...DEFAULT_OPTIONS.remarkPlugins, - ...mermaidOptions, + ...(reqOptions.mermaid ? [mermaid] : []), [ transformImage, { diff --git a/packages/docusaurus-plugin-content-blog/src/index.ts b/packages/docusaurus-plugin-content-blog/src/index.ts index 3ab43317d469..54bf18fc7bcf 100644 --- a/packages/docusaurus-plugin-content-blog/src/index.ts +++ b/packages/docusaurus-plugin-content-blog/src/index.ts @@ -465,7 +465,7 @@ export default async function pluginContentBlog( (author) => author.imageURL, ), }), - markdown: siteConfig.markdown, + ...siteConfig.markdown, }, }, { diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index e54c5b8cf431..7486ea0159ae 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -379,7 +379,7 @@ export default async function pluginContentDocs( }) => ({ image: frontMatter.image, }), - markdown: siteConfig.markdown, + ...siteConfig.markdown, }, }, { diff --git a/packages/docusaurus-plugin-content-pages/src/index.ts b/packages/docusaurus-plugin-content-pages/src/index.ts index 7c1680bed138..bfe24f09552a 100644 --- a/packages/docusaurus-plugin-content-pages/src/index.ts +++ b/packages/docusaurus-plugin-content-pages/src/index.ts @@ -221,7 +221,7 @@ export default function pluginContentPages( `${docuHash(aliasedSource)}.json`, ); }, - markdown: siteConfig.markdown, + ...siteConfig.markdown, }, }, { diff --git a/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts b/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts index 022535425141..4d458e430c08 100644 --- a/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts +++ b/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts @@ -10,6 +10,7 @@ declare module '@docusaurus/theme-mermaid' { import type {DeepPartial} from 'utility-types'; import type mermaidAPI from 'mermaid/mermaidAPI'; + import type {LoadContext, Plugin} from '@docusaurus/types'; export type ThemeConfig = { mermaid: { @@ -22,6 +23,11 @@ declare module '@docusaurus/theme-mermaid' { }; }; export type UserThemeConfig = DeepPartial; + + export default function themeMermaid( + context: LoadContext, + options: Options, + ): Plugin; } declare module '@theme/MDXComponents/Mermaid' { diff --git a/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/index.ts b/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/index.ts index 16f1526e0f2b..5bf8c3dacf8a 100644 --- a/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/index.ts +++ b/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/index.ts @@ -4,6 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ + import MDXComponents from '@theme-init/MDXComponents'; import MDXMermaid from '@theme/MDXComponents/Mermaid'; diff --git a/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx index 5b0f2b5aea98..fa9a0399740b 100644 --- a/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx +++ b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx @@ -5,28 +5,25 @@ * LICENSE file in the root directory of this source tree. */ -import React, {useEffect, useState} from 'react'; +import React, {useEffect, useState, useRef} from 'react'; import useIsBrowser from '@docusaurus/useIsBrowser'; import mermaid from 'mermaid'; import type {Props} from '@theme/Mermaid'; -/** - * Assign a unique ID to each mermaid svg as per requirements - * of `mermaid.render`. - */ -let id = 0; - export default function Mermaid({value}: Props): JSX.Element { // When theme updates, rerender the SVG. - const [svg, setSvg] = useState(''); + const [svg, setSvg] = useState(''); const isBrowser = useIsBrowser(); + // Assign a unique ID to each mermaid svg as per requirements of + // `mermaid.render`. + const id = useRef(0); useEffect(() => { const render = () => { - mermaid.render(`mermaid-svg-${id.toString()}`, value, (renderedSvg) => + mermaid.render(`mermaid-svg-${id.current}`, value, (renderedSvg) => setSvg(renderedSvg), ); - id += 1; + id.current += 1; }; render(); @@ -51,9 +48,7 @@ export default function Mermaid({value}: Props): JSX.Element { return () => { try { observer.disconnect(); - } catch { - // Do nothing - } + } catch {} }; } return undefined; diff --git a/packages/docusaurus-theme-mermaid/src/theme/useMermaid.tsx b/packages/docusaurus-theme-mermaid/src/theme/useMermaid.tsx index ae89587b4da7..884833121434 100644 --- a/packages/docusaurus-theme-mermaid/src/theme/useMermaid.tsx +++ b/packages/docusaurus-theme-mermaid/src/theme/useMermaid.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import {useEffect} from 'react'; +import {useEffect, useRef} from 'react'; import mermaid from 'mermaid'; import useIsBrowser from '@docusaurus/useIsBrowser'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; @@ -24,7 +24,7 @@ const HTML_THEME_ATTRIBUTE = 'data-theme'; * Gets the theme based on config and current data-theme of the HTML. * * @param html The HTML element of the page. - * @param config The configuration for this chart. + * @param options The configuration for this chart. */ function getTheme( html: HTMLHtmlElement, @@ -42,16 +42,19 @@ function getTheme( return options?.theme?.[htmlTheme] ?? options?.config?.theme ?? defaultTheme; } -let observer: MutationObserver | undefined; - export default function useMermaid(): void { const {siteConfig} = useDocusaurusContext(); const themeConfig = siteConfig.themeConfig as ThemeConfig; const isBrowser = useIsBrowser(); + const observer = useRef(null); // Watch for changes in theme in the HTML attribute `data-theme`. useEffect(() => { - if (!observer && siteConfig.markdown?.mermaid === true && isBrowser) { + if ( + !observer.current && + siteConfig.markdown?.mermaid === true && + isBrowser + ) { const html: HTMLHtmlElement = document.querySelector('html')!; const init = (target: HTMLHtmlElement): void => { const theme = getTheme(target, themeConfig.mermaid); @@ -69,7 +72,7 @@ export default function useMermaid(): void { html.setAttribute('data-mermaid', theme); }; - observer = new MutationObserver((mutations) => { + observer.current = new MutationObserver((mutations) => { for (const mutation of mutations) { if ( mutation.type !== 'attributes' || @@ -84,11 +87,11 @@ export default function useMermaid(): void { init(html); - observer.observe(html, {attributes: true}); + observer.current.observe(html, {attributes: true}); return () => { try { - (observer as MutationObserver).disconnect(); - observer = undefined; + observer.current?.disconnect(); + observer.current = null; } catch { // Do nothing } diff --git a/packages/docusaurus-types/src/index.d.ts b/packages/docusaurus-types/src/index.d.ts index 1ef3b078d787..2e19ab9714db 100644 --- a/packages/docusaurus-types/src/index.d.ts +++ b/packages/docusaurus-types/src/index.d.ts @@ -76,6 +76,20 @@ export type I18nConfig = { localeConfigs: {[locale: string]: Partial}; }; +export type MarkdownConfig = { + /** + * Allow mermaid language code blocks to be rendered into Mermaid diagrams: + * + * - `true`: code blocks with language mermaid will be rendered. + * - `false` | `undefined` (default): code blocks with language mermaid + * will be left as code blocks. + * + * @see https://docusaurus.io/docs/markdown-features/diagrams/ + * @default false + */ + mermaid?: boolean; +}; + /** * Docusaurus config, after validation/normalization. */ @@ -331,19 +345,7 @@ export type DocusaurusConfig = { jsLoader: 'babel' | ((isServer: boolean) => RuleSetRule); }; /** Markdown-related options. */ - markdown?: { - /** - * Allow mermaid language code blocks to be rendered into Mermaid diagrams: - * - * - `true`: code blocks with language mermaid will be rendered. - * - `false` | `undefined` (default): code blocks with language mermaid - * will be left as code blocks. - * - * @see https://docusaurus.io/docs/markdown-features/diagrams/ - * @default false - */ - mermaid?: boolean; - }; + markdown?: MarkdownConfig; }; /** From 8c9e0057ebf7ff02372adc313ed23b86f079a874 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Fri, 27 May 2022 19:35:12 +0800 Subject: [PATCH 08/28] remove unused --- packages/docusaurus-theme-mermaid/package.json | 6 +----- packages/docusaurus-theme-mermaid/src/index.ts | 16 ++-------------- .../src/theme-mermaid.d.ts | 7 ++----- 3 files changed, 5 insertions(+), 24 deletions(-) diff --git a/packages/docusaurus-theme-mermaid/package.json b/packages/docusaurus-theme-mermaid/package.json index 8a46440b149a..abf5f25214fb 100644 --- a/packages/docusaurus-theme-mermaid/package.json +++ b/packages/docusaurus-theme-mermaid/package.json @@ -21,10 +21,6 @@ }, "dependencies": { "@docusaurus/core": "2.0.0-beta.20", - "@docusaurus/theme-common": "2.0.0-beta.20", - "@docusaurus/theme-translations": "2.0.0-beta.20", - "@docusaurus/utils": "2.0.0-beta.20", - "@docusaurus/utils-common": "2.0.0-beta.20", "@docusaurus/utils-validation": "2.0.0-beta.20", "@mdx-js/react": "^1.6.22", "mermaid": "^9.1.1", @@ -42,6 +38,6 @@ "react-dom": "^16.8.4 || ^17.0.0" }, "engines": { - "node": ">=14" + "node": ">=16.14" } } diff --git a/packages/docusaurus-theme-mermaid/src/index.ts b/packages/docusaurus-theme-mermaid/src/index.ts index 2d2356c568d8..82b1636c598d 100644 --- a/packages/docusaurus-theme-mermaid/src/index.ts +++ b/packages/docusaurus-theme-mermaid/src/index.ts @@ -5,14 +5,9 @@ * LICENSE file in the root directory of this source tree. */ -import {readDefaultCodeTranslationMessages} from '@docusaurus/theme-translations'; -import type {LoadContext, Plugin} from '@docusaurus/types'; - -export default function themeMermaid(context: LoadContext): Plugin { - const { - i18n: {currentLocale}, - } = context; +import type {Plugin} from '@docusaurus/types'; +export default function themeMermaid(): Plugin { return { name: 'docusaurus-theme-mermaid', @@ -22,13 +17,6 @@ export default function themeMermaid(context: LoadContext): Plugin { getTypeScriptThemePath() { return '../src/theme'; }, - - getDefaultCodeTranslationMessages() { - return readDefaultCodeTranslationMessages({ - locale: currentLocale, - name: 'theme-mermaid', - }); - }, }; } diff --git a/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts b/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts index 4d458e430c08..3fa2b90be17c 100644 --- a/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts +++ b/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts @@ -10,7 +10,7 @@ declare module '@docusaurus/theme-mermaid' { import type {DeepPartial} from 'utility-types'; import type mermaidAPI from 'mermaid/mermaidAPI'; - import type {LoadContext, Plugin} from '@docusaurus/types'; + import type {Plugin} from '@docusaurus/types'; export type ThemeConfig = { mermaid: { @@ -24,10 +24,7 @@ declare module '@docusaurus/theme-mermaid' { }; export type UserThemeConfig = DeepPartial; - export default function themeMermaid( - context: LoadContext, - options: Options, - ): Plugin; + export default function themeMermaid(): Plugin; } declare module '@theme/MDXComponents/Mermaid' { From 722f75b72e89e06904e9b635a6cc46941ce28572 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Sun, 29 May 2022 13:50:44 +0800 Subject: [PATCH 09/28] remark plugin refactor --- .../__snapshots__/index.test.ts.snap | 51 +++++++++++++++++++ .../remark/mermaid/__tests__/index.test.ts | 44 +++++----------- .../src/remark/mermaid/index.ts | 39 +++++--------- 3 files changed, 79 insertions(+), 55 deletions(-) create mode 100644 packages/docusaurus-mdx-loader/src/remark/mermaid/__tests__/__snapshots__/index.test.ts.snap diff --git a/packages/docusaurus-mdx-loader/src/remark/mermaid/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-mdx-loader/src/remark/mermaid/__tests__/__snapshots__/index.test.ts.snap new file mode 100644 index 000000000000..157f963ccdb3 --- /dev/null +++ b/packages/docusaurus-mdx-loader/src/remark/mermaid/__tests__/__snapshots__/index.test.ts.snap @@ -0,0 +1,51 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`mermaid remark plugin does nothing if there's no mermaid code block 1`] = ` +" + + +const layoutProps = { + +}; +const MDXLayout = "wrapper" +export default function MDXContent({ + components, + ...props +}) { + return +

{\`Heading 1\`}

+

{\`No Mermaid diagram :(\`}

+
{\`this is not mermaid
+\`}
+
; +} + +; +MDXContent.isMDXComponent = true;" +`; + +exports[`mermaid remark plugin works for basic mermaid code blocks 1`] = ` +" + + +const layoutProps = { + +}; +const MDXLayout = "wrapper" +export default function MDXContent({ + components, + ...props +}) { + return +

{\`Heading 1\`}

+ B;/n A-->C;/n B-->D;/n C-->D;" + }}> +
; +} + +; +MDXContent.isMDXComponent = true;" +`; diff --git a/packages/docusaurus-mdx-loader/src/remark/mermaid/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/mermaid/__tests__/index.test.ts index abadf6e6445c..e61272955427 100644 --- a/packages/docusaurus-mdx-loader/src/remark/mermaid/__tests__/index.test.ts +++ b/packages/docusaurus-mdx-loader/src/remark/mermaid/__tests__/index.test.ts @@ -15,19 +15,25 @@ describe('mermaid remark plugin', () => { }); } - it('no mermaid', async () => { + it("does nothing if there's no mermaid code block", async () => { const mdxCompiler = createTestCompiler(); const result = await mdxCompiler.process( - '# Heading 1\n\nNo Mermaid diagram :(', - ); - expect(result.contents).toBe( - '\n\n\nconst layoutProps = {\n \n};\nconst MDXLayout = "wrapper"\nexport default function MDXContent({\n components,\n ...props\n}) {\n return \n

{`Heading 1`}

\n

{`No Mermaid diagram :(`}

\n
;\n}\n\n;\nMDXContent.isMDXComponent = true;', + `# Heading 1 + +No Mermaid diagram :( + +\`\`\`js +this is not mermaid +\`\`\` +`, ); + expect(result.contents).toMatchSnapshot(); }); - it('basic', async () => { + it('works for basic mermaid code blocks', async () => { const mdxCompiler = createTestCompiler(); - const result = await mdxCompiler.process(`# Heading 1\n + const result = await mdxCompiler.process(`# Heading 1 + \`\`\`mermaid graph TD; A-->B; @@ -35,28 +41,6 @@ graph TD; B-->D; C-->D; \`\`\``); - expect(result.contents).toBe(` - - -const layoutProps = { -${' '} -}; -const MDXLayout = "wrapper" -export default function MDXContent({ - components, - ...props -}) { - return -

{\`Heading 1\`}

- B; - A-->C; - B-->D; - C-->D;\`} /> -
; -} - -; -MDXContent.isMDXComponent = true;`); + expect(result.contents).toMatchSnapshot(); }); }); diff --git a/packages/docusaurus-mdx-loader/src/remark/mermaid/index.ts b/packages/docusaurus-mdx-loader/src/remark/mermaid/index.ts index 9d1a0588f7bc..ec68abbf2bd1 100644 --- a/packages/docusaurus-mdx-loader/src/remark/mermaid/index.ts +++ b/packages/docusaurus-mdx-loader/src/remark/mermaid/index.ts @@ -8,41 +8,30 @@ import visit from 'unist-util-visit'; import type {Transformer} from 'unified'; import type {Data, Literal, Node, Parent} from 'unist'; - -type CodeMermaid = Literal & { - type: 'code'; - lang: 'mermaid'; -}; +import type {Code} from 'mdast'; function processMermaidNode( - node: CodeMermaid, + node: Code, index: number, parent: Parent | Literal, Data>, ) { parent.children.splice(index, 1, { - type: 'jsx', - value: ``, - position: node.position, + type: 'mermaidCodeBlock', + data: { + hName: 'mermaid', + hProperties: { + value: node.value, + }, + }, }); } export default function plugin(): Transformer { - return async (root) => { - // Find all the mermaid diagram code blocks. i.e. ```mermaid - const instances: [CodeMermaid, number, Parent, Data>][] = []; - visit( - root, - {type: 'code', lang: 'mermaid'}, - (node: CodeMermaid, index, parent) => { - if (parent) { - instances.push([node, index, parent]); - } - }, - ); - - // Replace each Mermaid code block with the Mermaid component - instances.forEach(([node, index, parent]) => { - processMermaidNode(node, index, parent); + return (root) => { + visit(root, 'code', (node: Code, index, parent) => { + if (node.lang === 'mermaid') { + processMermaidNode(node, index, parent!); + } }); }; } From 0a5e372a36eaf817ab4df8e157caff1faeef0051 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Sun, 29 May 2022 14:12:39 +0800 Subject: [PATCH 10/28] greatly simplify --- .../docusaurus-theme-mermaid/package.json | 1 + .../src/theme-mermaid.d.ts | 14 +-- .../src/theme/MDXComponents/Mermaid.tsx | 16 --- .../src/theme/MDXComponents/index.ts | 4 +- .../src/theme/Mermaid/index.tsx | 47 ++------ .../src/theme/useMermaid.tsx | 102 ------------------ .../src/theme/useMermaidTheme.ts | 35 ++++++ 7 files changed, 53 insertions(+), 166 deletions(-) delete mode 100644 packages/docusaurus-theme-mermaid/src/theme/MDXComponents/Mermaid.tsx delete mode 100644 packages/docusaurus-theme-mermaid/src/theme/useMermaid.tsx create mode 100644 packages/docusaurus-theme-mermaid/src/theme/useMermaidTheme.ts diff --git a/packages/docusaurus-theme-mermaid/package.json b/packages/docusaurus-theme-mermaid/package.json index 3c94fc135b3f..9049e4f38536 100644 --- a/packages/docusaurus-theme-mermaid/package.json +++ b/packages/docusaurus-theme-mermaid/package.json @@ -22,6 +22,7 @@ "dependencies": { "@docusaurus/core": "2.0.0-beta.21", "@docusaurus/module-type-aliases": "2.0.0-beta.21", + "@docusaurus/theme-common": "2.0.0-beta.21", "@docusaurus/types": "2.0.0-beta.21", "@docusaurus/utils-validation": "2.0.0-beta.21", "@mdx-js/react": "^1.6.22", diff --git a/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts b/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts index 3fa2b90be17c..5a440ea31d87 100644 --- a/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts +++ b/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts @@ -13,7 +13,7 @@ declare module '@docusaurus/theme-mermaid' { import type {Plugin} from '@docusaurus/types'; export type ThemeConfig = { - mermaid: { + mermaid?: { theme?: { light: mermaidAPI.Theme; dark: mermaidAPI.Theme; @@ -27,16 +27,10 @@ declare module '@docusaurus/theme-mermaid' { export default function themeMermaid(): Plugin; } -declare module '@theme/MDXComponents/Mermaid' { - export interface Props { - value: string; - } - - export default function MDXMermaid(props: Props): JSX.Element; -} +declare module '@theme/useMermaidTheme' { + import type mermaidAPI from 'mermaid/mermaidAPI'; -declare module '@theme/useMermaid' { - export default function useMermaid(): void; + export default function useMermaidTheme(): mermaidAPI.Theme; } declare module '@theme/Mermaid' { diff --git a/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/Mermaid.tsx b/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/Mermaid.tsx deleted file mode 100644 index 4a85000dc519..000000000000 --- a/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/Mermaid.tsx +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import React from 'react'; -import Mermaid from '@theme/Mermaid'; -import type {Props} from '@theme/MDXComponents/Mermaid'; -import useMermaid from '@theme/useMermaid'; - -export default function MDXMermaid(props: Props): JSX.Element { - useMermaid(); - return ; -} diff --git a/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/index.ts b/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/index.ts index 5bf8c3dacf8a..4bdd2062e00b 100644 --- a/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/index.ts +++ b/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/index.ts @@ -6,9 +6,9 @@ */ import MDXComponents from '@theme-init/MDXComponents'; -import MDXMermaid from '@theme/MDXComponents/Mermaid'; +import Mermaid from '@theme/Mermaid'; export default { ...MDXComponents, - mermaid: MDXMermaid, + mermaid: Mermaid, }; diff --git a/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx index fa9a0399740b..4109fedfadcc 100644 --- a/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx +++ b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx @@ -5,54 +5,29 @@ * LICENSE file in the root directory of this source tree. */ -import React, {useEffect, useState, useRef} from 'react'; -import useIsBrowser from '@docusaurus/useIsBrowser'; +import React, {useEffect, useState, useRef, useCallback} from 'react'; import mermaid from 'mermaid'; +import useMermaidTheme from '@theme/useMermaidTheme'; import type {Props} from '@theme/Mermaid'; export default function Mermaid({value}: Props): JSX.Element { - // When theme updates, rerender the SVG. const [svg, setSvg] = useState(''); - const isBrowser = useIsBrowser(); + const theme = useMermaidTheme(); // Assign a unique ID to each mermaid svg as per requirements of // `mermaid.render`. const id = useRef(0); - useEffect(() => { - const render = () => { - mermaid.render(`mermaid-svg-${id.current}`, value, (renderedSvg) => - setSvg(renderedSvg), - ); - id.current += 1; - }; + const render = useCallback(() => { + mermaid.render(`mermaid-svg-${id.current}`, value, (renderedSvg) => + setSvg(renderedSvg), + ); + id.current += 1; + }, [value]); + useEffect(() => { render(); + }, [theme, render]); - if (isBrowser) { - const html: HTMLHtmlElement = document.querySelector('html')!; - - const observer = new MutationObserver((mutations) => { - for (const mutation of mutations) { - if ( - mutation.type !== 'attributes' || - mutation.attributeName !== 'data-mermaid' - ) { - continue; - } - render(); - break; - } - }); - - observer.observe(html, {attributes: true}); - return () => { - try { - observer.disconnect(); - } catch {} - }; - } - return undefined; - }, [isBrowser, value]); // eslint-disable-next-line react/no-danger return
; } diff --git a/packages/docusaurus-theme-mermaid/src/theme/useMermaid.tsx b/packages/docusaurus-theme-mermaid/src/theme/useMermaid.tsx deleted file mode 100644 index 884833121434..000000000000 --- a/packages/docusaurus-theme-mermaid/src/theme/useMermaid.tsx +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import {useEffect, useRef} from 'react'; -import mermaid from 'mermaid'; -import useIsBrowser from '@docusaurus/useIsBrowser'; -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import type mermaidAPI from 'mermaid/mermaidAPI'; -import type {ThemeConfig} from '@docusaurus/theme-mermaid'; - -const DEFAULT_DARK_THEME = 'dark' as mermaidAPI.Theme.Dark; -const DEFAULT_LIGHT_THEME = 'default' as mermaidAPI.Theme.Default; - -const DARK_THEME_KEY = 'dark'; -const LIGHT_THEME_KEY = 'light'; - -const HTML_THEME_ATTRIBUTE = 'data-theme'; - -/** - * Gets the theme based on config and current data-theme of the HTML. - * - * @param html The HTML element of the page. - * @param options The configuration for this chart. - */ -function getTheme( - html: HTMLHtmlElement, - options?: ThemeConfig['mermaid'], -): mermaidAPI.Theme { - let htmlTheme = html.getAttribute(HTML_THEME_ATTRIBUTE) ?? LIGHT_THEME_KEY; - - if (!(htmlTheme === LIGHT_THEME_KEY || htmlTheme === DARK_THEME_KEY)) { - htmlTheme = LIGHT_THEME_KEY; - } - - const defaultTheme = - htmlTheme === LIGHT_THEME_KEY ? DEFAULT_LIGHT_THEME : DEFAULT_DARK_THEME; - - return options?.theme?.[htmlTheme] ?? options?.config?.theme ?? defaultTheme; -} - -export default function useMermaid(): void { - const {siteConfig} = useDocusaurusContext(); - const themeConfig = siteConfig.themeConfig as ThemeConfig; - const isBrowser = useIsBrowser(); - const observer = useRef(null); - - // Watch for changes in theme in the HTML attribute `data-theme`. - useEffect(() => { - if ( - !observer.current && - siteConfig.markdown?.mermaid === true && - isBrowser - ) { - const html: HTMLHtmlElement = document.querySelector('html')!; - const init = (target: HTMLHtmlElement): void => { - const theme = getTheme(target, themeConfig.mermaid); - - if (themeConfig.mermaid?.config) { - mermaid.initialize({ - startOnLoad: true, - ...themeConfig.mermaid.config, - theme, - }); - } else { - mermaid.initialize({startOnLoad: true, theme}); - } - - html.setAttribute('data-mermaid', theme); - }; - - observer.current = new MutationObserver((mutations) => { - for (const mutation of mutations) { - if ( - mutation.type !== 'attributes' || - mutation.attributeName !== 'data-theme' - ) { - continue; - } - init(mutation.target as HTMLHtmlElement); - break; - } - }); - - init(html); - - observer.current.observe(html, {attributes: true}); - return () => { - try { - observer.current?.disconnect(); - observer.current = null; - } catch { - // Do nothing - } - }; - } - return undefined; - }, [isBrowser, siteConfig.markdown?.mermaid, themeConfig.mermaid]); -} diff --git a/packages/docusaurus-theme-mermaid/src/theme/useMermaidTheme.ts b/packages/docusaurus-theme-mermaid/src/theme/useMermaidTheme.ts new file mode 100644 index 000000000000..4e68c225d9a6 --- /dev/null +++ b/packages/docusaurus-theme-mermaid/src/theme/useMermaidTheme.ts @@ -0,0 +1,35 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {useEffect} from 'react'; +import mermaid from 'mermaid'; +import {useColorMode, useThemeConfig} from '@docusaurus/theme-common'; +import type mermaidAPI from 'mermaid/mermaidAPI'; +import type {ThemeConfig} from '@docusaurus/theme-mermaid'; + +const DEFAULT_DARK_THEME = 'dark' as mermaidAPI.Theme.Dark; +const DEFAULT_LIGHT_THEME = 'default' as mermaidAPI.Theme.Default; + +/** + * Gets the theme based on config and current color mode. + */ +export default function useMermaidTheme(): mermaidAPI.Theme { + const {colorMode} = useColorMode(); + const {mermaid: options} = useThemeConfig() as ThemeConfig; + + const defaultTheme = + colorMode === 'light' ? DEFAULT_LIGHT_THEME : DEFAULT_DARK_THEME; + + const theme = + options?.theme?.[colorMode] ?? options?.config?.theme ?? defaultTheme; + + useEffect(() => { + mermaid.initialize({startOnLoad: true, ...options?.config, theme}); + }, [theme, options]); + + return theme; +} From 73f53a81885c76ae839ec5579808559e2e417e48 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Sun, 29 May 2022 14:27:03 +0800 Subject: [PATCH 11/28] simplify API --- .../src/theme-mermaid.d.ts | 7 ++-- .../src/theme/useMermaidTheme.ts | 18 ++------ .../src/validateThemeConfig.ts | 31 +++++++++----- .../markdown-features-diagrams.mdx | 41 +++++++++---------- 4 files changed, 46 insertions(+), 51 deletions(-) diff --git a/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts b/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts index 5a440ea31d87..1cb387c52e9c 100644 --- a/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts +++ b/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts @@ -13,13 +13,12 @@ declare module '@docusaurus/theme-mermaid' { import type {Plugin} from '@docusaurus/types'; export type ThemeConfig = { - mermaid?: { - theme?: { + mermaid: { + theme: { light: mermaidAPI.Theme; dark: mermaidAPI.Theme; - [htmlTheme: string]: mermaidAPI.Theme; }; - config?: mermaidAPI.Config; + mermaidOptions: mermaidAPI.Config; }; }; export type UserThemeConfig = DeepPartial; diff --git a/packages/docusaurus-theme-mermaid/src/theme/useMermaidTheme.ts b/packages/docusaurus-theme-mermaid/src/theme/useMermaidTheme.ts index 4e68c225d9a6..b51df07342a6 100644 --- a/packages/docusaurus-theme-mermaid/src/theme/useMermaidTheme.ts +++ b/packages/docusaurus-theme-mermaid/src/theme/useMermaidTheme.ts @@ -11,24 +11,12 @@ import {useColorMode, useThemeConfig} from '@docusaurus/theme-common'; import type mermaidAPI from 'mermaid/mermaidAPI'; import type {ThemeConfig} from '@docusaurus/theme-mermaid'; -const DEFAULT_DARK_THEME = 'dark' as mermaidAPI.Theme.Dark; -const DEFAULT_LIGHT_THEME = 'default' as mermaidAPI.Theme.Default; - -/** - * Gets the theme based on config and current color mode. - */ export default function useMermaidTheme(): mermaidAPI.Theme { const {colorMode} = useColorMode(); - const {mermaid: options} = useThemeConfig() as ThemeConfig; - - const defaultTheme = - colorMode === 'light' ? DEFAULT_LIGHT_THEME : DEFAULT_DARK_THEME; - - const theme = - options?.theme?.[colorMode] ?? options?.config?.theme ?? defaultTheme; - + const {mermaid: options} = useThemeConfig() as unknown as ThemeConfig; + const theme = options.theme[colorMode]; useEffect(() => { - mermaid.initialize({startOnLoad: true, ...options?.config, theme}); + mermaid.initialize({startOnLoad: true, ...options.mermaidOptions, theme}); }, [theme, options]); return theme; diff --git a/packages/docusaurus-theme-mermaid/src/validateThemeConfig.ts b/packages/docusaurus-theme-mermaid/src/validateThemeConfig.ts index 0ee3866a0424..88a0b220a468 100644 --- a/packages/docusaurus-theme-mermaid/src/validateThemeConfig.ts +++ b/packages/docusaurus-theme-mermaid/src/validateThemeConfig.ts @@ -6,21 +6,30 @@ */ import {Joi} from '@docusaurus/utils-validation'; -import type { - ThemeConfig, - ThemeConfigValidationContext, -} from '@docusaurus/types'; +import type {ThemeConfig} from '@docusaurus/theme-mermaid'; +import type mermaidAPI from 'mermaid/mermaidAPI'; +import type {ThemeConfigValidationContext} from '@docusaurus/types'; + +const DEFAULT_THEME_CONFIG: ThemeConfig = { + mermaid: { + theme: { + dark: 'dark' as mermaidAPI.Theme, + light: 'default' as mermaidAPI.Theme, + }, + mermaidOptions: {}, + }, +}; export const Schema = Joi.object({ mermaid: Joi.object({ theme: Joi.object({ - dark: Joi.string().optional(), - light: Joi.string().optional(), - }).optional(), - config: Joi.object().optional(), - }) - .label('themeConfig.mermaid') - .optional(), + dark: Joi.string().default(DEFAULT_THEME_CONFIG.mermaid.theme.dark), + light: Joi.string().default(DEFAULT_THEME_CONFIG.mermaid.theme.light), + }).default(DEFAULT_THEME_CONFIG.mermaid.theme), + mermaidOptions: Joi.object().default( + DEFAULT_THEME_CONFIG.mermaid.mermaidOptions, + ), + }).default(DEFAULT_THEME_CONFIG.mermaid), }); export function validateThemeConfig({ diff --git a/website/docs/guides/markdown-features/markdown-features-diagrams.mdx b/website/docs/guides/markdown-features/markdown-features-diagrams.mdx index 8115655b7f98..ae59efe5b464 100644 --- a/website/docs/guides/markdown-features/markdown-features-diagrams.mdx +++ b/website/docs/guides/markdown-features/markdown-features-diagrams.mdx @@ -17,13 +17,12 @@ npm install --save @docusaurus/theme-mermaid Enable Mermaid functionality by adding plugin `@docusaurus/theme-mermaid` and setting `markdown.mermaid` to `true` in your `docusaurus.config.js`. -```js title=docusaurus.config.js -/** @type {import('@docusaurus/types').Config} */ -const config = { +```js title="docusaurus.config.js" +module.exports = { markdown: { mermaid: true, }, - plugins: ['@docusaurus/theme-mermaid'], + themes: ['@docusaurus/theme-mermaid'], }; ``` @@ -53,34 +52,34 @@ See the [Mermaid syntax documentation](https://mermaid-js.github.io/mermaid/#/./ ## Theming {#theming} -The diagram dark and light themes can be changed by setting `theme` values in the `themeConfig` in your `docusaurus.config.js`. +The diagram dark and light themes can be changed by setting `mermaid.theme` values in the `themeConfig` in your `docusaurus.config.js`. You can set themes for both light and dark mode. -```js title=docusaurus.config.js -themeConfig: - /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ - ({ +```js title="docusaurus.config.js" +module.exports = { + themeConfig: { mermaid: { - theme: { light: 'neutral', dark: 'forest' } - } - }), + theme: {light: 'neutral', dark: 'forest'}, + }, + }, +}; ``` See the [Mermaid theme documentation](https://mermaid-js.github.io/mermaid/#/theming) for more information on theming Mermaid diagrams. ## Mermaid Config {#configuration} -Mermaid config can be configured through the `config` object in `themeConfig` in your `docusaurus.config.js`: +Options in `mermaid.mermaidOptions` will be passed directly to `mermaid.initialize`: -```js title=docusaurus.config.js -themeConfig: - /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ - ({ +```js title="docusaurus.config.js" +module.exports = { + themeConfig: { mermaid: { - config: { + mermaidOptions: { maxTextSize: 50, - } - } - }), + }, + }, + }, +}; ``` See the [Mermaid configuration documentation](https://mermaid-js.github.io/mermaid/#/./Setup?id=configuration) for the available config options. From ec6f920784973b5ae3c33f8206c8bed67cee6f94 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Sun, 29 May 2022 14:42:41 +0800 Subject: [PATCH 12/28] fix tests --- .../src/remark/mermaid/index.ts | 31 ++++++++----------- .../src/__tests__/validateThemeConfig.test.ts | 26 +++++++++------- .../src/validateThemeConfig.ts | 2 +- 3 files changed, 29 insertions(+), 30 deletions(-) diff --git a/packages/docusaurus-mdx-loader/src/remark/mermaid/index.ts b/packages/docusaurus-mdx-loader/src/remark/mermaid/index.ts index ec68abbf2bd1..d0b6232cdfad 100644 --- a/packages/docusaurus-mdx-loader/src/remark/mermaid/index.ts +++ b/packages/docusaurus-mdx-loader/src/remark/mermaid/index.ts @@ -7,30 +7,25 @@ import visit from 'unist-util-visit'; import type {Transformer} from 'unified'; -import type {Data, Literal, Node, Parent} from 'unist'; import type {Code} from 'mdast'; -function processMermaidNode( - node: Code, - index: number, - parent: Parent | Literal, Data>, -) { - parent.children.splice(index, 1, { - type: 'mermaidCodeBlock', - data: { - hName: 'mermaid', - hProperties: { - value: node.value, - }, - }, - }); -} - +// TODO: this plugin shouldn't be in the core MDX loader +// After we allow plugins to provide Remark/Rehype plugins (see +// https://github.com/facebook/docusaurus/issues/6370), this should be provided +// by theme-mermaid itself export default function plugin(): Transformer { return (root) => { visit(root, 'code', (node: Code, index, parent) => { if (node.lang === 'mermaid') { - processMermaidNode(node, index, parent!); + parent!.children.splice(index, 1, { + type: 'mermaidCodeBlock', + data: { + hName: 'mermaid', + hProperties: { + value: node.value, + }, + }, + }); } }); }; diff --git a/packages/docusaurus-theme-mermaid/src/__tests__/validateThemeConfig.test.ts b/packages/docusaurus-theme-mermaid/src/__tests__/validateThemeConfig.test.ts index 4c6962b2f215..c88ec02fcd3a 100644 --- a/packages/docusaurus-theme-mermaid/src/__tests__/validateThemeConfig.test.ts +++ b/packages/docusaurus-theme-mermaid/src/__tests__/validateThemeConfig.test.ts @@ -5,13 +5,17 @@ * LICENSE file in the root directory of this source tree. */ -import {validateThemeConfig} from '../validateThemeConfig'; +import { + validateThemeConfig, + DEFAULT_THEME_CONFIG, +} from '../validateThemeConfig'; import type {Joi} from '@docusaurus/utils-validation'; +import type {ThemeConfig, UserThemeConfig} from '@docusaurus/theme-mermaid'; -function testValidateThemeConfig(themeConfig: {[key: string]: unknown}) { +function testValidateThemeConfig(themeConfig: UserThemeConfig) { function validate( - schema: Joi.ObjectSchema<{[key: string]: unknown}>, - cfg: {[key: string]: unknown}, + schema: Joi.ObjectSchema, + cfg: UserThemeConfig, ) { const {value, error} = schema.validate(cfg, { convert: false, @@ -28,18 +32,16 @@ function testValidateThemeConfig(themeConfig: {[key: string]: unknown}) { describe('validateThemeConfig', () => { it('undefined config', () => { const mermaid = undefined; - expect(testValidateThemeConfig({mermaid})).toEqual({}); + expect(testValidateThemeConfig({mermaid})).toEqual(DEFAULT_THEME_CONFIG); }); it('nonexistent config', () => { - expect(testValidateThemeConfig({})).toEqual({}); + expect(testValidateThemeConfig({})).toEqual(DEFAULT_THEME_CONFIG); }); it('empty config', () => { const mermaid = {}; - expect(testValidateThemeConfig({mermaid})).toEqual({ - mermaid: {}, - }); + expect(testValidateThemeConfig({mermaid})).toEqual(DEFAULT_THEME_CONFIG); }); it('theme', () => { @@ -51,19 +53,21 @@ describe('validateThemeConfig', () => { }; expect(testValidateThemeConfig({mermaid})).toEqual({ mermaid: { + ...DEFAULT_THEME_CONFIG.mermaid, ...mermaid, }, }); }); - it('config', () => { + it('mermaidOptions', () => { const mermaid = { - config: { + mermaidOptions: { fontFamily: 'Ariel', }, }; expect(testValidateThemeConfig({mermaid})).toEqual({ mermaid: { + ...DEFAULT_THEME_CONFIG.mermaid, ...mermaid, }, }); diff --git a/packages/docusaurus-theme-mermaid/src/validateThemeConfig.ts b/packages/docusaurus-theme-mermaid/src/validateThemeConfig.ts index 88a0b220a468..de65508c3457 100644 --- a/packages/docusaurus-theme-mermaid/src/validateThemeConfig.ts +++ b/packages/docusaurus-theme-mermaid/src/validateThemeConfig.ts @@ -10,7 +10,7 @@ import type {ThemeConfig} from '@docusaurus/theme-mermaid'; import type mermaidAPI from 'mermaid/mermaidAPI'; import type {ThemeConfigValidationContext} from '@docusaurus/types'; -const DEFAULT_THEME_CONFIG: ThemeConfig = { +export const DEFAULT_THEME_CONFIG: ThemeConfig = { mermaid: { theme: { dark: 'dark' as mermaidAPI.Theme, From 47bec9b2e41ec4cc66af39fe502ac995cfb30861 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Sun, 29 May 2022 14:46:02 +0800 Subject: [PATCH 13/28] move dogfooding --- .../{_docs tests/tests => _pages tests}/diagrams.md | 3 --- website/_dogfooding/_pages tests/index.md | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) rename website/_dogfooding/{_docs tests/tests => _pages tests}/diagrams.md (99%) diff --git a/website/_dogfooding/_docs tests/tests/diagrams.md b/website/_dogfooding/_pages tests/diagrams.md similarity index 99% rename from website/_dogfooding/_docs tests/tests/diagrams.md rename to website/_dogfooding/_pages tests/diagrams.md index 01a413267bb1..eec9c33c86a7 100644 --- a/website/_dogfooding/_docs tests/tests/diagrams.md +++ b/website/_dogfooding/_pages tests/diagrams.md @@ -1,6 +1,3 @@ ---- ---- - # Diagram Examples ## Sequence Diagram diff --git a/website/_dogfooding/_pages tests/index.md b/website/_dogfooding/_pages tests/index.md index cf94300fb891..a6028df75d81 100644 --- a/website/_dogfooding/_pages tests/index.md +++ b/website/_dogfooding/_pages tests/index.md @@ -27,4 +27,5 @@ import Readme from "../README.md" - [Asset linking tests](/tests/pages/markdown-tests) - [General Markdown tests](/tests/pages/markdownPageTests) - [TOC tests](/tests/pages/page-toc-tests) +- [Diagram tests](/tests/pages/diagrams) - [Tabs tests](/tests/pages/tabs-tests) From 5ec7c0b0b1ca56bf2424a7e594844e9ff26be7a2 Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Thu, 13 Oct 2022 18:35:10 +0200 Subject: [PATCH 14/28] mermaid.mermaidOptions => mermaid.options --- .../src/__tests__/validateThemeConfig.test.ts | 4 ++-- .../src/theme-mermaid.d.ts | 2 +- .../src/theme/useMermaidTheme.ts | 14 +++++++++++--- .../src/validateThemeConfig.ts | 6 ++---- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/docusaurus-theme-mermaid/src/__tests__/validateThemeConfig.test.ts b/packages/docusaurus-theme-mermaid/src/__tests__/validateThemeConfig.test.ts index c88ec02fcd3a..dc71a9c49c25 100644 --- a/packages/docusaurus-theme-mermaid/src/__tests__/validateThemeConfig.test.ts +++ b/packages/docusaurus-theme-mermaid/src/__tests__/validateThemeConfig.test.ts @@ -59,9 +59,9 @@ describe('validateThemeConfig', () => { }); }); - it('mermaidOptions', () => { + it('mermaid options', () => { const mermaid = { - mermaidOptions: { + options: { fontFamily: 'Ariel', }, }; diff --git a/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts b/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts index 1cb387c52e9c..5c15765ccbe5 100644 --- a/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts +++ b/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts @@ -18,7 +18,7 @@ declare module '@docusaurus/theme-mermaid' { light: mermaidAPI.Theme; dark: mermaidAPI.Theme; }; - mermaidOptions: mermaidAPI.Config; + options: mermaidAPI.Config; }; }; export type UserThemeConfig = DeepPartial; diff --git a/packages/docusaurus-theme-mermaid/src/theme/useMermaidTheme.ts b/packages/docusaurus-theme-mermaid/src/theme/useMermaidTheme.ts index b51df07342a6..04bafdab802c 100644 --- a/packages/docusaurus-theme-mermaid/src/theme/useMermaidTheme.ts +++ b/packages/docusaurus-theme-mermaid/src/theme/useMermaidTheme.ts @@ -11,12 +11,20 @@ import {useColorMode, useThemeConfig} from '@docusaurus/theme-common'; import type mermaidAPI from 'mermaid/mermaidAPI'; import type {ThemeConfig} from '@docusaurus/theme-mermaid'; +// TODO expose as client API? +function useMermaidThemeConfig() { + return (useThemeConfig() as unknown as ThemeConfig).mermaid; +} + export default function useMermaidTheme(): mermaidAPI.Theme { const {colorMode} = useColorMode(); - const {mermaid: options} = useThemeConfig() as unknown as ThemeConfig; - const theme = options.theme[colorMode]; + const mermaidThemeConfig = useMermaidThemeConfig(); + + const theme = mermaidThemeConfig.theme[colorMode]; + const {options} = mermaidThemeConfig; + useEffect(() => { - mermaid.initialize({startOnLoad: true, ...options.mermaidOptions, theme}); + mermaid.initialize({startOnLoad: true, ...options, theme}); }, [theme, options]); return theme; diff --git a/packages/docusaurus-theme-mermaid/src/validateThemeConfig.ts b/packages/docusaurus-theme-mermaid/src/validateThemeConfig.ts index de65508c3457..c68201f225dd 100644 --- a/packages/docusaurus-theme-mermaid/src/validateThemeConfig.ts +++ b/packages/docusaurus-theme-mermaid/src/validateThemeConfig.ts @@ -16,7 +16,7 @@ export const DEFAULT_THEME_CONFIG: ThemeConfig = { dark: 'dark' as mermaidAPI.Theme, light: 'default' as mermaidAPI.Theme, }, - mermaidOptions: {}, + options: {}, }, }; @@ -26,9 +26,7 @@ export const Schema = Joi.object({ dark: Joi.string().default(DEFAULT_THEME_CONFIG.mermaid.theme.dark), light: Joi.string().default(DEFAULT_THEME_CONFIG.mermaid.theme.light), }).default(DEFAULT_THEME_CONFIG.mermaid.theme), - mermaidOptions: Joi.object().default( - DEFAULT_THEME_CONFIG.mermaid.mermaidOptions, - ), + options: Joi.object().default(DEFAULT_THEME_CONFIG.mermaid.options), }).default(DEFAULT_THEME_CONFIG.mermaid), }); From 25cb8aa10caeeb66f8519e0924cf3f09a503179f Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Thu, 13 Oct 2022 18:56:11 +0200 Subject: [PATCH 15/28] validate config.markdown.mermaid --- packages/docusaurus-types/src/config.d.ts | 2 +- .../server/__tests__/configValidation.test.ts | 49 ++++++++++++++++++- .../docusaurus/src/server/configValidation.ts | 8 ++- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/packages/docusaurus-types/src/config.d.ts b/packages/docusaurus-types/src/config.d.ts index 97e525bd596c..031c7994d5ef 100644 --- a/packages/docusaurus-types/src/config.d.ts +++ b/packages/docusaurus-types/src/config.d.ts @@ -285,7 +285,7 @@ export type DocusaurusConfig = { jsLoader: 'babel' | ((isServer: boolean) => RuleSetRule); }; /** Markdown-related options. */ - markdown?: MarkdownConfig; + markdown: MarkdownConfig; }; /** diff --git a/packages/docusaurus/src/server/__tests__/configValidation.test.ts b/packages/docusaurus/src/server/__tests__/configValidation.test.ts index 9297df2db422..a02eda441c08 100644 --- a/packages/docusaurus/src/server/__tests__/configValidation.test.ts +++ b/packages/docusaurus/src/server/__tests__/configValidation.test.ts @@ -11,7 +11,8 @@ import { DEFAULT_CONFIG, validateConfig, } from '../configValidation'; -import type {Config} from '@docusaurus/types'; +import type {Config, DocusaurusConfig} from '@docusaurus/types'; +import type {DeepPartial} from 'utility-types'; const baseConfig = { baseUrl: '/', @@ -19,7 +20,7 @@ const baseConfig = { url: 'https://mysite.com', } as Config; -const normalizeConfig = (config: Partial) => +const normalizeConfig = (config: DeepPartial) => validateConfig({...baseConfig, ...config}, 'docusaurus.config.js'); describe('normalizeConfig', () => { @@ -58,6 +59,9 @@ describe('normalizeConfig', () => { crossorigin: 'anonymous', }, ], + markdown: { + mermaid: true, + }, }; const normalizedConfig = normalizeConfig(userConfig); expect(normalizedConfig).toEqual(userConfig); @@ -414,3 +418,44 @@ describe('config warnings', () => { ); }); }); + +describe('markdown', () => { + it('accepts undefined object', () => { + expect( + normalizeConfig({ + markdown: undefined, + }), + ).toEqual(expect.objectContaining({markdown: DEFAULT_CONFIG.markdown})); + }); + + it('accepts empty object', () => { + expect( + normalizeConfig({ + markdown: {}, + }), + ).toEqual(expect.objectContaining({markdown: DEFAULT_CONFIG.markdown})); + }); + + it('accepts valid markdown object', () => { + const markdown: DocusaurusConfig['markdown'] = { + mermaid: true, + }; + expect( + normalizeConfig({ + markdown, + }), + ).toEqual(expect.objectContaining({markdown})); + }); + + it('throw for null object', () => { + expect(() => { + normalizeConfig({ + // @ts-expect-error: test + markdown: null, + }); + }).toThrowErrorMatchingInlineSnapshot(` + ""markdown" must be of type object + " + `); + }); +}); diff --git a/packages/docusaurus/src/server/configValidation.ts b/packages/docusaurus/src/server/configValidation.ts index c4552630a1c3..03a73854fd43 100644 --- a/packages/docusaurus/src/server/configValidation.ts +++ b/packages/docusaurus/src/server/configValidation.ts @@ -43,6 +43,7 @@ export const DEFAULT_CONFIG: Pick< | 'tagline' | 'baseUrlIssueBanner' | 'staticDirectories' + | 'markdown' > = { i18n: DEFAULT_I18N_CONFIG, onBrokenLinks: 'throw', @@ -61,6 +62,9 @@ export const DEFAULT_CONFIG: Pick< tagline: '', baseUrlIssueBanner: true, staticDirectories: [DEFAULT_STATIC_DIR_NAME], + markdown: { + mermaid: false, + }, }; function createPluginSchema(theme: boolean) { @@ -246,7 +250,9 @@ export const ConfigSchema = Joi.object({ .try(Joi.string().equal('babel'), Joi.function()) .optional(), }).optional(), - markdown: Joi.object().unknown().optional(), + markdown: Joi.object({ + mermaid: Joi.boolean().default(DEFAULT_CONFIG.markdown.mermaid), + }).default(DEFAULT_CONFIG.markdown), }).messages({ 'docusaurus.configValidationWarning': 'Docusaurus config validation warning. Field {#label}: {#warningMessage}', From 56ca9c7de65df37e6accb9b79cef730bd4ab00c7 Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Thu, 13 Oct 2022 19:08:05 +0200 Subject: [PATCH 16/28] do not spread markdown config to mdx loader: be more explicit with attribute markdownConfig --- packages/docusaurus-mdx-loader/src/loader.ts | 29 +++++++++---------- .../src/index.ts | 2 +- .../src/index.ts | 2 +- .../src/index.ts | 2 +- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/packages/docusaurus-mdx-loader/src/loader.ts b/packages/docusaurus-mdx-loader/src/loader.ts index 92c14208dab6..12ac0e192fda 100644 --- a/packages/docusaurus-mdx-loader/src/loader.ts +++ b/packages/docusaurus-mdx-loader/src/loader.ts @@ -62,20 +62,19 @@ export type MDXOptions = { beforeDefaultRehypePlugins: MDXPlugin[]; }; -export type Options = Partial & - MarkdownConfig & { - staticDirs: string[]; - siteDir: string; - isMDXPartial?: (filePath: string) => boolean; - isMDXPartialFrontMatterWarningDisabled?: boolean; - removeContentTitle?: boolean; - metadataPath?: string | ((filePath: string) => string); - createAssets?: (metadata: { - frontMatter: {[key: string]: unknown}; - metadata: {[key: string]: unknown}; - }) => {[key: string]: unknown}; - filepath: string; - }; +export type Options = Partial & { + markdownConfig: MarkdownConfig; + staticDirs: string[]; + siteDir: string; + isMDXPartial?: (filePath: string) => boolean; + isMDXPartialFrontMatterWarningDisabled?: boolean; + removeContentTitle?: boolean; + metadataPath?: string | ((filePath: string) => string); + createAssets?: (metadata: { + frontMatter: {[key: string]: unknown}; + metadata: {[key: string]: unknown}; + }) => {[key: string]: unknown}; +}; /** * When this throws, it generally means that there's no metadata file associated @@ -174,7 +173,7 @@ export async function mdxLoader( ...(reqOptions.beforeDefaultRemarkPlugins ?? []), ...getAdmonitionsPlugins(reqOptions.admonitions ?? false), ...DEFAULT_OPTIONS.remarkPlugins, - ...(reqOptions.mermaid ? [mermaid] : []), + ...(reqOptions.markdownConfig.mermaid ? [mermaid] : []), [ transformImage, { diff --git a/packages/docusaurus-plugin-content-blog/src/index.ts b/packages/docusaurus-plugin-content-blog/src/index.ts index 6a47c40f779d..51bdf7516c32 100644 --- a/packages/docusaurus-plugin-content-blog/src/index.ts +++ b/packages/docusaurus-plugin-content-blog/src/index.ts @@ -455,7 +455,7 @@ export default async function pluginContentBlog( (author) => author.imageURL, ), }), - ...siteConfig.markdown, + markdownConfig: siteConfig.markdown, }, }, { diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index 594906cf2aac..74eac5d38afe 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -288,7 +288,7 @@ export default async function pluginContentDocs( }) => ({ image: frontMatter.image, }), - ...siteConfig.markdown, + markdownConfig: siteConfig.markdown, }, }, { diff --git a/packages/docusaurus-plugin-content-pages/src/index.ts b/packages/docusaurus-plugin-content-pages/src/index.ts index a186c3806192..c3c51b883283 100644 --- a/packages/docusaurus-plugin-content-pages/src/index.ts +++ b/packages/docusaurus-plugin-content-pages/src/index.ts @@ -211,7 +211,7 @@ export default function pluginContentPages( `${docuHash(aliasedSource)}.json`, ); }, - ...siteConfig.markdown, + markdownConfig: siteConfig.markdown, }, }, { From 9772c2e0636c642ed6138016a46dc5a0c872b3ba Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Thu, 13 Oct 2022 19:16:58 +0200 Subject: [PATCH 17/28] typo --- packages/docusaurus/src/server/plugins/synthetic.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/docusaurus/src/server/plugins/synthetic.ts b/packages/docusaurus/src/server/plugins/synthetic.ts index 9f716b940adf..f74d77886892 100644 --- a/packages/docusaurus/src/server/plugins/synthetic.ts +++ b/packages/docusaurus/src/server/plugins/synthetic.ts @@ -8,6 +8,7 @@ import path from 'path'; import type {RuleSetRule} from 'webpack'; import type {HtmlTagObject, LoadedPlugin, LoadContext} from '@docusaurus/types'; +import type {Options as MDXLoaderOptions} from '@docusaurus/mdx-loader'; /** * Make a synthetic plugin to: @@ -95,7 +96,7 @@ export function createMDXFallbackPlugin({ return isMDXRule ? (rule.include as string[]) : []; }); } - const mdxLoaderOptions = { + const mdxLoaderOptions: MDXLoaderOptions = { admonitions: true, staticDirs: siteConfig.staticDirectories.map((dir) => path.resolve(siteDir, dir), @@ -105,7 +106,7 @@ export function createMDXFallbackPlugin({ isMDXPartial: () => true, // External MDX files might have front matter, just disable the warning isMDXPartialFrontMatterWarningDisabled: true, - markdown: siteConfig.markdown, + markdownConfig: siteConfig.markdown, }; return { From 5d493642ad107be2fd1b4be47693521958243e07 Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Thu, 13 Oct 2022 19:41:46 +0200 Subject: [PATCH 18/28] temp better mermaid integration --- .../src/theme/Mermaid/index.tsx | 48 ++++++++++++------- .../src/theme/useMermaidTheme.ts | 5 +- 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx index 4109fedfadcc..b1c6e5ad0952 100644 --- a/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx +++ b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx @@ -5,29 +5,41 @@ * LICENSE file in the root directory of this source tree. */ -import React, {useEffect, useState, useRef, useCallback} from 'react'; +import React, {useState, useMemo} from 'react'; +import BrowserOnly from '@docusaurus/BrowserOnly'; import mermaid from 'mermaid'; +import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; import useMermaidTheme from '@theme/useMermaidTheme'; import type {Props} from '@theme/Mermaid'; -export default function Mermaid({value}: Props): JSX.Element { - const [svg, setSvg] = useState(''); - const theme = useMermaidTheme(); - // Assign a unique ID to each mermaid svg as per requirements of - // `mermaid.render`. - const id = useRef(0); - - const render = useCallback(() => { - mermaid.render(`mermaid-svg-${id.current}`, value, (renderedSvg) => - setSvg(renderedSvg), - ); - id.current += 1; - }, [value]); +const clientId = { + prefix: 'cid_', + count: 0, +}; - useEffect(() => { - render(); - }, [theme, render]); +// TODO temporary, replace by React 18 useId() +function useClientId(): string { + if (!ExecutionEnvironment.canUseDOM) { + throw new Error('useClientId() can only use on the client/browser side.'); + } + const [value] = useState(() => { + clientId.count += 1; + return `${clientId.prefix}${clientId.count}`; + }); + return value; +} +function MermaidRenderer({value}: Props): JSX.Element { + const id = useClientId(); + const theme = useMermaidTheme(); + const svgString = useMemo(() => { + console.log({theme}); // TODO + return mermaid.render(`mermaid-svg-${id}`, value); + }, [id, value, theme]); // eslint-disable-next-line react/no-danger - return
; + return
; +} + +export default function Mermaid(props: Props): JSX.Element { + return {() => }; } diff --git a/packages/docusaurus-theme-mermaid/src/theme/useMermaidTheme.ts b/packages/docusaurus-theme-mermaid/src/theme/useMermaidTheme.ts index 04bafdab802c..2e4311d4a5b3 100644 --- a/packages/docusaurus-theme-mermaid/src/theme/useMermaidTheme.ts +++ b/packages/docusaurus-theme-mermaid/src/theme/useMermaidTheme.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import {useEffect} from 'react'; +import {useMemo} from 'react'; import mermaid from 'mermaid'; import {useColorMode, useThemeConfig} from '@docusaurus/theme-common'; import type mermaidAPI from 'mermaid/mermaidAPI'; @@ -23,7 +23,8 @@ export default function useMermaidTheme(): mermaidAPI.Theme { const theme = mermaidThemeConfig.theme[colorMode]; const {options} = mermaidThemeConfig; - useEffect(() => { + // TODO bad location + useMemo(() => { mermaid.initialize({startOnLoad: true, ...options, theme}); }, [theme, options]); From 062ed20631712b26be0b513983750c7b36e28795 Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Thu, 13 Oct 2022 19:50:53 +0200 Subject: [PATCH 19/28] expose mermaid hooks as client apis instead of themes --- packages/docusaurus-theme-mermaid/package.json | 13 +++++++++++++ .../{theme/useMermaidTheme.ts => client/index.ts} | 5 ++--- .../docusaurus-theme-mermaid/src/theme-mermaid.d.ts | 6 ------ .../src/theme/Mermaid/index.tsx | 3 ++- 4 files changed, 17 insertions(+), 10 deletions(-) rename packages/docusaurus-theme-mermaid/src/{theme/useMermaidTheme.ts => client/index.ts} (86%) diff --git a/packages/docusaurus-theme-mermaid/package.json b/packages/docusaurus-theme-mermaid/package.json index 58f82ff24fbe..e42f81e712a7 100644 --- a/packages/docusaurus-theme-mermaid/package.json +++ b/packages/docusaurus-theme-mermaid/package.json @@ -4,6 +4,19 @@ "description": "Mermaid components for Docusaurus.", "main": "lib/index.js", "types": "src/theme-mermaid.d.ts", + "sideEffects": false, + "exports": { + "./lib/*": "./lib/*", + "./src/*": "./src/*", + "./client": { + "type": "./lib/client/index.d.ts", + "default": "./lib/client/index.js" + }, + ".": { + "types": "./src/theme-mermaid.d.ts", + "default": "./lib/index.js" + } + }, "publishConfig": { "access": "public" }, diff --git a/packages/docusaurus-theme-mermaid/src/theme/useMermaidTheme.ts b/packages/docusaurus-theme-mermaid/src/client/index.ts similarity index 86% rename from packages/docusaurus-theme-mermaid/src/theme/useMermaidTheme.ts rename to packages/docusaurus-theme-mermaid/src/client/index.ts index 2e4311d4a5b3..966a1c2e73a7 100644 --- a/packages/docusaurus-theme-mermaid/src/theme/useMermaidTheme.ts +++ b/packages/docusaurus-theme-mermaid/src/client/index.ts @@ -11,12 +11,11 @@ import {useColorMode, useThemeConfig} from '@docusaurus/theme-common'; import type mermaidAPI from 'mermaid/mermaidAPI'; import type {ThemeConfig} from '@docusaurus/theme-mermaid'; -// TODO expose as client API? -function useMermaidThemeConfig() { +export function useMermaidThemeConfig(): ThemeConfig['mermaid'] { return (useThemeConfig() as unknown as ThemeConfig).mermaid; } -export default function useMermaidTheme(): mermaidAPI.Theme { +export function useMermaidTheme(): mermaidAPI.Theme { const {colorMode} = useColorMode(); const mermaidThemeConfig = useMermaidThemeConfig(); diff --git a/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts b/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts index 5c15765ccbe5..9b605341a517 100644 --- a/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts +++ b/packages/docusaurus-theme-mermaid/src/theme-mermaid.d.ts @@ -26,12 +26,6 @@ declare module '@docusaurus/theme-mermaid' { export default function themeMermaid(): Plugin; } -declare module '@theme/useMermaidTheme' { - import type mermaidAPI from 'mermaid/mermaidAPI'; - - export default function useMermaidTheme(): mermaidAPI.Theme; -} - declare module '@theme/Mermaid' { export interface Props { value: string; diff --git a/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx index b1c6e5ad0952..9c464102de43 100644 --- a/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx +++ b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx @@ -9,7 +9,8 @@ import React, {useState, useMemo} from 'react'; import BrowserOnly from '@docusaurus/BrowserOnly'; import mermaid from 'mermaid'; import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; -import useMermaidTheme from '@theme/useMermaidTheme'; +import {useMermaidTheme} from '@docusaurus/theme-mermaid/client'; + import type {Props} from '@theme/Mermaid'; const clientId = { From 4da56ed667c879f4a771bdc1a72d8f9fa7003913 Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Fri, 14 Oct 2022 14:39:41 +0200 Subject: [PATCH 20/28] fix snapshots --- .../__tests__/__snapshots__/config.test.ts.snap | 15 +++++++++++++++ .../__tests__/__snapshots__/index.test.ts.snap | 3 +++ 2 files changed, 18 insertions(+) diff --git a/packages/docusaurus/src/server/__tests__/__snapshots__/config.test.ts.snap b/packages/docusaurus/src/server/__tests__/__snapshots__/config.test.ts.snap index 64dfeff98eea..8cdd215878b5 100644 --- a/packages/docusaurus/src/server/__tests__/__snapshots__/config.test.ts.snap +++ b/packages/docusaurus/src/server/__tests__/__snapshots__/config.test.ts.snap @@ -15,6 +15,9 @@ exports[`loadSiteConfig website with .cjs siteConfig 1`] = ` ], "path": "i18n", }, + "markdown": { + "mermaid": false, + }, "noIndex": false, "onBrokenLinks": "throw", "onBrokenMarkdownLinks": "warn", @@ -52,6 +55,9 @@ exports[`loadSiteConfig website with valid async config 1`] = ` ], "path": "i18n", }, + "markdown": { + "mermaid": false, + }, "noIndex": false, "onBrokenLinks": "throw", "onBrokenMarkdownLinks": "warn", @@ -91,6 +97,9 @@ exports[`loadSiteConfig website with valid async config creator function 1`] = ` ], "path": "i18n", }, + "markdown": { + "mermaid": false, + }, "noIndex": false, "onBrokenLinks": "throw", "onBrokenMarkdownLinks": "warn", @@ -130,6 +139,9 @@ exports[`loadSiteConfig website with valid config creator function 1`] = ` ], "path": "i18n", }, + "markdown": { + "mermaid": false, + }, "noIndex": false, "onBrokenLinks": "throw", "onBrokenMarkdownLinks": "warn", @@ -172,6 +184,9 @@ exports[`loadSiteConfig website with valid siteConfig 1`] = ` ], "path": "i18n", }, + "markdown": { + "mermaid": false, + }, "noIndex": false, "onBrokenLinks": "throw", "onBrokenMarkdownLinks": "warn", diff --git a/packages/docusaurus/src/server/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus/src/server/__tests__/__snapshots__/index.test.ts.snap index fb73309cd272..58371dc1126f 100644 --- a/packages/docusaurus/src/server/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus/src/server/__tests__/__snapshots__/index.test.ts.snap @@ -89,6 +89,9 @@ exports[`load loads props for site with custom i18n path 1`] = ` ], "path": "i18n", }, + "markdown": { + "mermaid": false, + }, "noIndex": false, "onBrokenLinks": "throw", "onBrokenMarkdownLinks": "warn", From b6c408d3d131bcf99f2a30734a9f82055ecf11f5 Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Fri, 14 Oct 2022 16:11:25 +0200 Subject: [PATCH 21/28] good mermaid integration --- .../src/client/index.ts | 58 ++++++++++++++++--- .../src/theme/Mermaid/index.tsx | 32 ++-------- website/_dogfooding/_pages tests/diagrams.md | 24 ++++++++ 3 files changed, 79 insertions(+), 35 deletions(-) diff --git a/packages/docusaurus-theme-mermaid/src/client/index.ts b/packages/docusaurus-theme-mermaid/src/client/index.ts index 966a1c2e73a7..b86ae5460e4b 100644 --- a/packages/docusaurus-theme-mermaid/src/client/index.ts +++ b/packages/docusaurus-theme-mermaid/src/client/index.ts @@ -6,8 +6,8 @@ */ import {useMemo} from 'react'; -import mermaid from 'mermaid'; import {useColorMode, useThemeConfig} from '@docusaurus/theme-common'; +import mermaid from 'mermaid'; import type mermaidAPI from 'mermaid/mermaidAPI'; import type {ThemeConfig} from '@docusaurus/theme-mermaid'; @@ -15,17 +15,61 @@ export function useMermaidThemeConfig(): ThemeConfig['mermaid'] { return (useThemeConfig() as unknown as ThemeConfig).mermaid; } -export function useMermaidTheme(): mermaidAPI.Theme { +export function useMermaidConfig(): mermaidAPI.Config { const {colorMode} = useColorMode(); const mermaidThemeConfig = useMermaidThemeConfig(); const theme = mermaidThemeConfig.theme[colorMode]; const {options} = mermaidThemeConfig; - // TODO bad location - useMemo(() => { - mermaid.initialize({startOnLoad: true, ...options, theme}); - }, [theme, options]); + return useMemo( + () => ({startOnLoad: false, ...options, theme}), + [theme, options], + ); +} + +export function useMermaidSvg( + txt: string, + mermaidConfigParam?: mermaidAPI.Config, +): string { + /* + For flexibility, we allow the hook to receive a custom Mermaid config + The user could inject a modified version of the default config for example + */ + const defaultMermaidConfig = useMermaidConfig(); + const mermaidConfig = mermaidConfigParam ?? defaultMermaidConfig; + + return useMemo(() => { + /* + Mermaid API is really weird :s + It is a big mutable singleton with multiple config levels + Note: most recent API type definitions are missing + + There are 2 kind of configs: + + - siteConfig: some kind of global/protected shared config + you can only set with "initialize" + + - config/currentConfig + the config the renderer will use + it is reset to siteConfig before each render + but it can be altered by the mermaid txt content itself through directives + + To use a new mermaid config (on colorMode change for example) we should + update siteConfig, and it can only be done with initialize() + */ + mermaid.mermaidAPI.initialize(mermaidConfig); + + /* + Random client-only id, we don't care much about it + But mermaid want an id so... + */ + const mermaidId = `mermaid-svg-${Math.round(Math.random() * 10000)}`; - return theme; + /* + Not even documented: mermaid.render returns the svg string + Using the documented form is un-necessary + */ + return mermaid.render(mermaidId, txt); + }, [txt, mermaidConfig]); } diff --git a/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx index 9c464102de43..a4a06a9a8307 100644 --- a/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx +++ b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx @@ -5,40 +5,16 @@ * LICENSE file in the root directory of this source tree. */ -import React, {useState, useMemo} from 'react'; +import React from 'react'; import BrowserOnly from '@docusaurus/BrowserOnly'; -import mermaid from 'mermaid'; -import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; -import {useMermaidTheme} from '@docusaurus/theme-mermaid/client'; +import {useMermaidSvg} from '@docusaurus/theme-mermaid/client'; import type {Props} from '@theme/Mermaid'; -const clientId = { - prefix: 'cid_', - count: 0, -}; - -// TODO temporary, replace by React 18 useId() -function useClientId(): string { - if (!ExecutionEnvironment.canUseDOM) { - throw new Error('useClientId() can only use on the client/browser side.'); - } - const [value] = useState(() => { - clientId.count += 1; - return `${clientId.prefix}${clientId.count}`; - }); - return value; -} - function MermaidRenderer({value}: Props): JSX.Element { - const id = useClientId(); - const theme = useMermaidTheme(); - const svgString = useMemo(() => { - console.log({theme}); // TODO - return mermaid.render(`mermaid-svg-${id}`, value); - }, [id, value, theme]); + const svg = useMermaidSvg(value); // eslint-disable-next-line react/no-danger - return
; + return
; } export default function Mermaid(props: Props): JSX.Element { diff --git a/website/_dogfooding/_pages tests/diagrams.md b/website/_dogfooding/_pages tests/diagrams.md index eec9c33c86a7..a01d8a6b1b29 100644 --- a/website/_dogfooding/_pages tests/diagrams.md +++ b/website/_dogfooding/_pages tests/diagrams.md @@ -16,6 +16,30 @@ sequenceDiagram Bob-->>John: Jolly good! ``` +## Sequence Diagram (always dark) + +It is possible to override default config locally with Mermaid text directives such as: + +``` +%%{init: { 'theme': 'dark' } }%% +``` + +```mermaid +%%{init: { 'theme': 'dark' } }%% + +sequenceDiagram + participant Alice + participant Bob + Alice->>John: Hello John, how are you? + loop Health check + John->>John: Fight against hypochondria + end + Note right of John: Rational thoughts
prevail! + John-->>Alice: Great! + John->>Bob: How about you? + Bob-->>John: Jolly good! +``` + ## Gantt Chart ```mermaid From d5ca004e111388ebe49a1381649cfa8f19bfa2c8 Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Fri, 14 Oct 2022 16:13:19 +0200 Subject: [PATCH 22/28] increase random count --- packages/docusaurus-theme-mermaid/src/client/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docusaurus-theme-mermaid/src/client/index.ts b/packages/docusaurus-theme-mermaid/src/client/index.ts index b86ae5460e4b..72517051b96f 100644 --- a/packages/docusaurus-theme-mermaid/src/client/index.ts +++ b/packages/docusaurus-theme-mermaid/src/client/index.ts @@ -64,7 +64,7 @@ export function useMermaidSvg( Random client-only id, we don't care much about it But mermaid want an id so... */ - const mermaidId = `mermaid-svg-${Math.round(Math.random() * 10000)}`; + const mermaidId = `mermaid-svg-${Math.round(Math.random() * 10000000)}`; /* Not even documented: mermaid.render returns the svg string From 76c870322e1f4d6cc93bb59fc5a4d12770c30149 Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Fri, 14 Oct 2022 16:22:54 +0200 Subject: [PATCH 23/28] add max-width 100% to container/svg --- .../src/client/index.ts | 3 +++ .../src/theme/Mermaid/index.tsx | 20 ++++++++++++++----- .../src/theme/Mermaid/styles.module.css | 14 +++++++++++++ 3 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 packages/docusaurus-theme-mermaid/src/theme/Mermaid/styles.module.css diff --git a/packages/docusaurus-theme-mermaid/src/client/index.ts b/packages/docusaurus-theme-mermaid/src/client/index.ts index 72517051b96f..e432d6a81a99 100644 --- a/packages/docusaurus-theme-mermaid/src/client/index.ts +++ b/packages/docusaurus-theme-mermaid/src/client/index.ts @@ -11,6 +11,9 @@ import mermaid from 'mermaid'; import type mermaidAPI from 'mermaid/mermaidAPI'; import type {ThemeConfig} from '@docusaurus/theme-mermaid'; +// Stable className to allow users to easily target with CSS +export const MermaidContainerClassName = 'docusaurus-mermaid-container'; + export function useMermaidThemeConfig(): ThemeConfig['mermaid'] { return (useThemeConfig() as unknown as ThemeConfig).mermaid; } diff --git a/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx index a4a06a9a8307..26a882e6ddaf 100644 --- a/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx +++ b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/index.tsx @@ -7,16 +7,26 @@ import React from 'react'; import BrowserOnly from '@docusaurus/BrowserOnly'; -import {useMermaidSvg} from '@docusaurus/theme-mermaid/client'; +import { + MermaidContainerClassName, + useMermaidSvg, +} from '@docusaurus/theme-mermaid/client'; import type {Props} from '@theme/Mermaid'; -function MermaidRenderer({value}: Props): JSX.Element { +import styles from './styles.module.css'; + +function MermaidDiagram({value}: Props): JSX.Element { const svg = useMermaidSvg(value); - // eslint-disable-next-line react/no-danger - return
; + return ( +
+ ); } export default function Mermaid(props: Props): JSX.Element { - return {() => }; + return {() => }; } diff --git a/packages/docusaurus-theme-mermaid/src/theme/Mermaid/styles.module.css b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/styles.module.css new file mode 100644 index 000000000000..fa19d80d927e --- /dev/null +++ b/packages/docusaurus-theme-mermaid/src/theme/Mermaid/styles.module.css @@ -0,0 +1,14 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.container { + max-width: 100%; +} + +.container > svg { + max-width: 100%; +} From c8d1e2c21d6bc9108382fafd8269eb02b7d380ab Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Fri, 14 Oct 2022 16:32:43 +0200 Subject: [PATCH 24/28] try to fix journey bug use forest theme --- website/_dogfooding/_pages tests/diagrams.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/website/_dogfooding/_pages tests/diagrams.md b/website/_dogfooding/_pages tests/diagrams.md index a01d8a6b1b29..ca8bc9505412 100644 --- a/website/_dogfooding/_pages tests/diagrams.md +++ b/website/_dogfooding/_pages tests/diagrams.md @@ -16,16 +16,16 @@ sequenceDiagram Bob-->>John: Jolly good! ``` -## Sequence Diagram (always dark) +## Sequence Diagram (forest theme directive) It is possible to override default config locally with Mermaid text directives such as: ``` -%%{init: { 'theme': 'dark' } }%% +%%{init: { "theme": "forest" } }%% ``` ```mermaid -%%{init: { 'theme': 'dark' } }%% +%%{init: { "theme": "forest" } }%% sequenceDiagram participant Alice @@ -145,6 +145,12 @@ journey Sit down: 5: Me ``` +:::note + +If there's too much space above it's due to a [Mermaid bug](https://github.com/mermaid-js/mermaid/issues/3501) + +::: + ## Pie Chart ```mermaid From bd67df138b905272fa5f38a1e50d832ec41e498c Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Fri, 14 Oct 2022 16:37:09 +0200 Subject: [PATCH 25/28] fix bad project-words merge --- project-words.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/project-words.txt b/project-words.txt index c0bc28ab0156..094e9896a651 100644 --- a/project-words.txt +++ b/project-words.txt @@ -105,11 +105,8 @@ formik fouc froms funboxteam -<<<<<<< HEAD gantt -======= gabrielcsapo ->>>>>>> main getopts gitgraph gitpod From 8c88c55514af42ccc0e4d401c8f88d33022ce565 Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Fri, 14 Oct 2022 16:59:00 +0200 Subject: [PATCH 26/28] refactor MDXComponents usage --- .../src/theme-classic.d.ts | 10 ++++++++++ .../src/theme/MDXComponents/index.tsx | 2 ++ .../src/theme/Mermaid.tsx | 16 ++++++++++++++++ .../src/theme/MDXComponents/index.ts | 14 -------------- 4 files changed, 28 insertions(+), 14 deletions(-) create mode 100644 packages/docusaurus-theme-classic/src/theme/Mermaid.tsx delete mode 100644 packages/docusaurus-theme-mermaid/src/theme/MDXComponents/index.ts diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index 39799fb78d43..2e89d14c8ddd 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -897,6 +897,7 @@ declare module '@theme/MDXComponents' { import type MDXUl from '@theme/MDXComponents/Ul'; import type MDXImg from '@theme/MDXComponents/Img'; import type Admonition from '@theme/Admonition'; + import type Mermaid from '@theme/Mermaid'; export type MDXComponentsObject = { readonly head: typeof MDXHead; @@ -913,6 +914,7 @@ declare module '@theme/MDXComponents' { readonly h5: (props: ComponentProps<'h5'>) => JSX.Element; readonly h6: (props: ComponentProps<'h6'>) => JSX.Element; readonly admonition: typeof Admonition; + readonly mermaid: typeof Mermaid; // eslint-disable-next-line @typescript-eslint/no-explicit-any [tagName: string]: ComponentType; }; @@ -1221,6 +1223,14 @@ declare module '@theme/SearchBar' { export default function SearchBar(): JSX.Element; } +declare module '@theme/Mermaid' { + export interface Props { + value: string; + } + + export default function Mermaid(props: Props): JSX.Element; +} + declare module '@theme/TabItem' { import type {ReactNode} from 'react'; diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx b/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx index 8b6141f5e2bc..13931951950a 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx @@ -15,6 +15,7 @@ import MDXHeading from '@theme/MDXComponents/Heading'; import MDXUl from '@theme/MDXComponents/Ul'; import MDXImg from '@theme/MDXComponents/Img'; import Admonition from '@theme/Admonition'; +import Mermaid from '@theme/Mermaid'; import type {MDXComponentsObject} from '@theme/MDXComponents'; @@ -33,6 +34,7 @@ const MDXComponents: MDXComponentsObject = { h5: (props) => , h6: (props) => , admonition: Admonition, + mermaid: Mermaid, }; export default MDXComponents; diff --git a/packages/docusaurus-theme-classic/src/theme/Mermaid.tsx b/packages/docusaurus-theme-classic/src/theme/Mermaid.tsx new file mode 100644 index 000000000000..1c326bb04fb6 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/Mermaid.tsx @@ -0,0 +1,16 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// This component is meant to be implemented by a Mermaid renderer theme +// It is notable created to be overridden by docusaurus-theme-mermaid + +// By default, the classic theme does not provide any Mermaid implementation +// Yet we declare it there so that we can register it in MDX +// TODO later the mermaid theme should be able to register its MDX component +// see https://github.com/facebook/docusaurus/pull/7490#issuecomment-1279117288 + +export {default} from '@docusaurus/Noop'; diff --git a/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/index.ts b/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/index.ts deleted file mode 100644 index 4bdd2062e00b..000000000000 --- a/packages/docusaurus-theme-mermaid/src/theme/MDXComponents/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import MDXComponents from '@theme-init/MDXComponents'; -import Mermaid from '@theme/Mermaid'; - -export default { - ...MDXComponents, - mermaid: Mermaid, -}; From 57d481c9f0b10d909b5e486a3d553e0cc6283665 Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Fri, 14 Oct 2022 17:20:34 +0200 Subject: [PATCH 27/28] add mermaid in tabs dogfood, see https://github.com/sjwall/mdx-mermaid/issues/66 --- .../{diagrams.md => diagrams.mdx} | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) rename website/_dogfooding/_pages tests/{diagrams.md => diagrams.mdx} (93%) diff --git a/website/_dogfooding/_pages tests/diagrams.md b/website/_dogfooding/_pages tests/diagrams.mdx similarity index 93% rename from website/_dogfooding/_pages tests/diagrams.md rename to website/_dogfooding/_pages tests/diagrams.mdx index ca8bc9505412..aeb27d26af62 100644 --- a/website/_dogfooding/_pages tests/diagrams.md +++ b/website/_dogfooding/_pages tests/diagrams.mdx @@ -281,3 +281,35 @@ pie showData checkout develop merge release ``` + +## Mermaid in tabs + +import Tabs from '@theme/Tabs'; + +import TabItem from '@theme/TabItem'; + + + + +The following mermaid diagram is shown: + +```mermaid +graph LR + a ---> c(10) + b ---> c(10) +``` + + + + + +This mermaid diagram is not displayed: + +```mermaid +graph LR + d ---> z(42) + e ---> z(42) +``` + + + From 1377f4abaaaf093dc8ff87b9386808eaa0187c8a Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Fri, 14 Oct 2022 17:23:05 +0200 Subject: [PATCH 28/28] ````mdx-code-block --- website/_dogfooding/_pages tests/diagrams.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/_dogfooding/_pages tests/diagrams.mdx b/website/_dogfooding/_pages tests/diagrams.mdx index aeb27d26af62..c759be77a886 100644 --- a/website/_dogfooding/_pages tests/diagrams.mdx +++ b/website/_dogfooding/_pages tests/diagrams.mdx @@ -284,8 +284,8 @@ pie showData ## Mermaid in tabs +````mdx-code-block import Tabs from '@theme/Tabs'; - import TabItem from '@theme/TabItem'; @@ -313,3 +313,4 @@ graph LR +````