Skip to content

Commit 476650b

Browse files
committed
[docs] Fix copy button not working on first page load
1 parent a389a2d commit 476650b

2 files changed

Lines changed: 43 additions & 9 deletions

File tree

packages-internal/core-docs/src/CodeCopy/CodeCopy.tsx

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as React from 'react';
22
import { useRouter } from 'next/router';
33
import clipboardCopy from 'clipboard-copy';
4+
import { throttle } from 'es-toolkit/function';
45

56
const CodeBlockContext = React.createContext<React.MutableRefObject<HTMLDivElement | null>>({
67
current: null,
@@ -41,14 +42,40 @@ export function useCodeCopy(): React.HTMLAttributes<HTMLDivElement> {
4142
function InitCodeCopy() {
4243
const rootNode = React.useContext(CodeBlockContext);
4344
const router = useRouter();
45+
46+
const [lateRootCount, setLateRootCount] = React.useState(0);
47+
48+
const throttledSetLateRoot = React.useRef(
49+
throttle(() => {
50+
setLateRootCount((prev) => prev + 1);
51+
}, 1000),
52+
).current;
4453
React.useEffect(() => {
45-
let key = 'Ctrl + ';
46-
if (typeof window !== 'undefined') {
47-
const macOS = window.navigator.platform.toUpperCase().includes('MAC');
48-
if (macOS) {
49-
key = '⌘';
54+
const observer = new MutationObserver((mutationsList, _) => {
55+
for (const mutation of mutationsList) {
56+
if (mutation.type === 'childList') {
57+
mutation.addedNodes.forEach((n) => {
58+
const node = n as HTMLDivElement;
59+
if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains('MuiCode-root')) {
60+
throttledSetLateRoot();
61+
}
62+
});
63+
}
5064
}
51-
}
65+
});
66+
67+
const observerOptions = {
68+
childList: true,
69+
subtree: true,
70+
};
71+
72+
observer.observe(document.body, observerOptions);
73+
74+
return () => {
75+
observer.disconnect();
76+
};
77+
}, [throttledSetLateRoot]);
78+
React.useEffect(() => {
5279
const codeRoots = document.getElementsByClassName(
5380
'MuiCode-root',
5481
) as HTMLCollectionOf<HTMLDivElement>;
@@ -115,7 +142,6 @@ function InitCodeCopy() {
115142
// skip the logic if the btn is not generated from the markdown.
116143
return;
117144
}
118-
keyNode.textContent = keyNode?.textContent?.replace('$key', key) || null;
119145
btn.addEventListener('click', handleClick);
120146
listeners.push(() => btn.removeEventListener('click', handleClick));
121147
}
@@ -129,7 +155,7 @@ function InitCodeCopy() {
129155
}
130156

131157
return undefined;
132-
}, [rootNode, router.pathname]);
158+
}, [rootNode, router.pathname, lateRootCount]);
133159
return null;
134160
}
135161

packages-internal/markdown/parseMarkdown.mjs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,13 +424,21 @@ function createRender(context) {
424424
return `<pre><code>${escaped ? code : escape(code, true)}</code></pre>\n`;
425425
}
426426

427+
let key = 'Ctrl + ';
428+
if (typeof window !== 'undefined') {
429+
const macOS = window.navigator.platform.toUpperCase().includes('MAC');
430+
if (macOS) {
431+
key = '⌘';
432+
}
433+
}
434+
427435
return `<div class="MuiCode-root">${title ? `<div class="MuiCode-title">${title}</div>` : ''}<pre><code class="language-${escape(lang, true)}">${
428436
escaped ? code : escape(code, true)
429437
}</code></pre>${[
430438
'<button data-ga-event-category="code" data-ga-event-action="copy-click" aria-label="Copy the code" class="MuiCode-copy">',
431439
'<span class="MuiCode-copy-label">Copy</span>',
432440
'<span class="MuiCode-copied-label">Copied</span>',
433-
'<span class="MuiCode-copyKeypress"><span>(or</span> $keyC<span>)</span></span></button></div>',
441+
`<span class="MuiCode-copyKeypress"><span>(or</span> ${key}C<span>)</span></span></button></div>`,
434442
].join('')}\n`;
435443
};
436444

0 commit comments

Comments
 (0)