Skip to content

Commit 2bae43e

Browse files
Merge branch 'next'
2 parents e461d9f + 895b427 commit 2bae43e

File tree

9 files changed

+204
-124
lines changed

9 files changed

+204
-124
lines changed

__tests__/browser/markdown.test.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@ const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
55

66
describe('visual regression tests', () => {
77
describe('rdmd syntax', () => {
8+
beforeAll(async () => {
9+
// try warming up the browser???
10+
const uri = 'http://localhost:9966/#/callouts?ci=true&darkModeDataAttribute=true';
11+
await page.goto(uri, { waitUntil: 'networkidle0' });
12+
});
13+
814
beforeEach(async () => {
915
// The ToC disappears somewhere below 1200, 1175-ish?
1016
await page.setViewport({ width: 1400, height: 800 });
11-
});
17+
}, 10000);
1218

1319
const docs = [
1420
'callouts',

components/Code/index.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React, { createRef, useContext } from 'react';
33

44
import CodeOptsContext from '../../contexts/CodeOpts';
55
import ThemeContext from '../../contexts/Theme';
6+
import useHydrated from '../../hooks/useHydrated';
67

78
// Only load CodeMirror in the browser, for SSR
89
// apps. Necessary because of people like this:
@@ -57,8 +58,9 @@ const Code = (props: CodeProps) => {
5758
const { children, lang, value } = props;
5859
const theme = useContext(ThemeContext);
5960
const copyButtons = useContext(CodeOptsContext) || props.copyButtons;
61+
const isHydrated = useHydrated();
6062

61-
const language = canonicalLanguage(lang);
63+
const language = isHydrated ? canonicalLanguage(lang) : '';
6264

6365
const codeRef = createRef<HTMLElement>();
6466

@@ -71,7 +73,7 @@ const Code = (props: CodeProps) => {
7173
const code = value ?? (Array.isArray(children) ? children[0] : children) ?? '';
7274

7375
const highlightedCode =
74-
syntaxHighlighter && typeof syntaxHighlighter === 'function' && code
76+
syntaxHighlighter && typeof syntaxHighlighter === 'function' && code && isHydrated
7577
? syntaxHighlighter(code, language, codeOpts, { mdx: true })
7678
: code;
7779

@@ -86,7 +88,6 @@ const Code = (props: CodeProps) => {
8688
ref={codeRef}
8789
className={['rdmd-code', `lang-${language}`, `theme-${theme}`].join(' ')}
8890
data-lang={language}
89-
suppressHydrationWarning={true}
9091
>
9192
{highlightedCode}
9293
</code>

components/CodeTabs/index.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@ const CodeTabs = (props: Props) => {
2222
import('mermaid').then(module => {
2323
mermaid = module.default;
2424
mermaid.initialize({
25+
startOnLoad: false,
2526
theme: theme === 'dark' ? 'dark' : 'default',
2627
});
27-
mermaid.contentLoaded();
28+
mermaid.run({
29+
nodes: document.querySelectorAll('.mermaid-render'),
30+
});
2831
});
2932
}
3033
}, [hasMermaid, theme]);
@@ -44,7 +47,7 @@ const CodeTabs = (props: Props) => {
4447
// render single Mermaid diagram
4548
if (hasMermaid) {
4649
const value = children.props.children.props.value;
47-
return <pre className="mermaid mermaid_single">{value}</pre>;
50+
return <pre className="mermaid-render mermaid_single">{value}</pre>;
4851
}
4952

5053
return (

hooks/useHydrated/index.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { useEffect, useState } from 'react';
2+
3+
/**
4+
* A hook that returns whether or not the component has been hydrated.
5+
* Useful for components that should only render in the browser, and not during SSR.
6+
* Waiting to render until after hydration avoids React hydration mismatches.
7+
*/
8+
export default function useHydrated(): boolean {
9+
const [isHydrated, setIsHydrated] = useState(false);
10+
useEffect(() => setIsHydrated(true), []);
11+
return isHydrated;
12+
}

0 commit comments

Comments
 (0)