Skip to content

Commit 03b71d9

Browse files
feat: add copy-button for codeBlocks
1 parent c1ac637 commit 03b71d9

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { useState } from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
function CopyButton({ text }) {
5+
const [copied, setCopied] = useState(false);
6+
7+
const handleCopy = () => {
8+
navigator.clipboard.writeText(text).then(() => {
9+
setCopied(true);
10+
setTimeout(() => setCopied(false), 2000);
11+
});
12+
};
13+
14+
const buttonStyle = {
15+
position: 'absolute',
16+
top: '0.5rem',
17+
right: '0.5rem',
18+
backgroundColor: '#e5e7eb',
19+
fontSize: '0.875rem',
20+
padding: '0.25rem 0.5rem',
21+
borderRadius: '0.25rem',
22+
cursor: 'pointer',
23+
transition: 'background-color 0.3s ease',
24+
};
25+
26+
const handleMouseOver = (e) => {
27+
e.target.style.backgroundColor = '#d1d5db';
28+
};
29+
30+
const handleMouseOut = (e) => {
31+
e.target.style.backgroundColor = '#e5e7eb';
32+
};
33+
34+
return (
35+
<button
36+
className="copy-button"
37+
style={buttonStyle}
38+
onClick={handleCopy}
39+
onMouseOver={handleMouseOver}
40+
onMouseOut={handleMouseOut}
41+
>
42+
{copied ? 'Copied!' : 'Copy'}
43+
</button>
44+
);
45+
}
46+
CopyButton.propTypes = {
47+
text: PropTypes.string.isRequired,
48+
};
49+
50+
//integrating the CopyButton component into the CodeBlock component
51+
52+
export default function CodeBlock({ children }) {
53+
const codeText = children?.props?.children?.toString() || '';
54+
55+
return (
56+
<div style={{ position: 'relative' }}>
57+
<CopyButton text={codeText} />
58+
<pre>{children}</pre>
59+
</div>
60+
);
61+
}
62+
63+
CodeBlock.propTypes = {
64+
children: PropTypes.node.isRequired,
65+
};

src/components/Page/Page.jsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,22 @@
22
import { useEffect, useState } from 'react';
33
import PropTypes from 'prop-types';
44
import { useLocation } from 'react-router-dom';
5+
import { MDXProvider } from '@mdx-js/react';
56

67
// Import Components
78
import PageLinks from '../PageLinks/PageLinks';
89
import Markdown from '../Markdown/Markdown';
910
import Contributors from '../Contributors/Contributors';
1011
import { PlaceholderString } from '../Placeholder/Placeholder';
1112
import AdjacentPages from './AdjacentPages';
13+
import CodeBlock from '../CodeBlock/CodeBlock';
1214

1315
// Load Styling
1416
import './Page.scss';
1517
import Link from '../Link/Link';
18+
19+
const components = { pre: CodeBlock };
20+
1621
export default function Page(props) {
1722
const {
1823
title,
@@ -113,7 +118,9 @@ export default function Page(props) {
113118
</div>
114119
) : null}
115120

116-
<div id="md-content">{contentRender}</div>
121+
<MDXProvider components={components}>
122+
<div id="md-content">{contentRender}</div>
123+
</MDXProvider>
117124

118125
{loadRelated && (
119126
<div className="print:hidden">

0 commit comments

Comments
 (0)