Sequence diagrams size notes and messages by measuring their text in Mermaid's root fontFamily and fontSize, which the theme's variables don't set: a note drawn in IBM Plex Mono overflowed a box measured in another font. Both are set from the site's font, and diagrams wait for document.fonts.ready.
- commit
- 93bb1be179facbfac6c7167a185fba35f5259148
- parent
- 58dd9af85665244bb57f8a9a0756b22baef966f1
- author
- Dami <dami.etoile@gmail.com>
- kind
- fix risk score 1.3 of 3, Jev's estimate
| M | website/ | 27 | ++++++++++++++++++++++++--- |
@@ -4,7 +4,7 @@
44 // home. Mermaid needs literal colors, not CSS variables, which is why55 // they are read from the page rather than passed through.66 7-import React, {useEffect, useMemo, useRef, type ReactNode} from 'react';7+import React, {useEffect, useMemo, useRef, useState, type ReactNode} from 'react';88 import ErrorBoundary from '@docusaurus/ErrorBoundary';99 import {ErrorBoundaryErrorMessageFallback, useColorMode} from '@docusaurus/theme-common';1010 import {@@ -125,10 +125,16 @@ function useMermaidConfig(): MermaidConfig | undefined {
125125 if (mode === undefined) {126126 return undefined;127127 }128+ const palette = readPalette();129+ // The font is also set outside the theme: diagrams that size boxes130+ // by measuring their text (sequence diagrams) measure it in these,131+ // and text measured in another font overflows its box.128132 return {129133 startOnLoad: false,130134 theme: 'base',131- themeVariables: themeVariables(readPalette(), mode === 'dark'),135+ fontFamily: palette['font-mono'],136+ fontSize: 14,137+ themeVariables: themeVariables(palette, mode === 'dark'),132138 flowchart: {curve: 'linear', htmlLabels: true},133139 } as MermaidConfig;134140 }, [mode]);@@ -160,10 +166,25 @@ function MermaidRenderer({value}: Props): ReactNode {
160166 return <MermaidRenderResult renderResult={renderResult} />;161167 }162168 169+// Mermaid sizes boxes by measuring their text, so it draws once the170+// site's fonts have loaded; measured in a fallback font, text overflows.171+function useFontsReady(): boolean {172+ const [ready, setReady] = useState(false);173+ useEffect(() => {174+ let live = true;175+ document.fonts.ready.then(() => live && setReady(true));176+ return () => {177+ live = false;178+ };179+ }, []);180+ return ready;181+}182+163183 export default function Mermaid(props: Props): ReactNode {184+ const ready = useFontsReady();164185 return (165186 <ErrorBoundary fallback={(params) => <ErrorBoundaryErrorMessageFallback {...params} />}>166- <MermaidRenderer {...props} />187+ {ready && <MermaidRenderer {...props} />}167188 </ErrorBoundary>168189 );169190 }