mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-08 13:52:36 +02:00
feat(v2): CodeBlock copy button (#1643)
* feat(v2): CodeBlock copy button * fix: live theme editor breaking bug
This commit is contained in:
parent
4faa608edd
commit
7b7d1e6161
7 changed files with 164 additions and 21 deletions
|
@ -5,15 +5,44 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, {useEffect, useState, useRef} from 'react';
|
||||
import classnames from 'classnames';
|
||||
import Highlight, {defaultProps} from 'prism-react-renderer';
|
||||
import nightOwlTheme from 'prism-react-renderer/themes/nightOwl';
|
||||
import Clipboard from 'clipboard';
|
||||
import styles from './styles.module.css';
|
||||
|
||||
export default ({children, className: languageClassName}) => {
|
||||
const [showCopied, setShowCopied] = useState(false);
|
||||
const target = useRef(null);
|
||||
const button = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
let clipboard;
|
||||
|
||||
if (button.current) {
|
||||
clipboard = new Clipboard(button.current, {
|
||||
target: () => target.current,
|
||||
});
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (clipboard) {
|
||||
clipboard.destroy();
|
||||
}
|
||||
};
|
||||
}, [button.current, target.current]);
|
||||
|
||||
const language =
|
||||
languageClassName && languageClassName.replace(/language-/, '');
|
||||
|
||||
const handleCopyCode = () => {
|
||||
window.getSelection().empty();
|
||||
setShowCopied(true);
|
||||
|
||||
setTimeout(() => setShowCopied(false), 2000);
|
||||
};
|
||||
|
||||
return (
|
||||
<Highlight
|
||||
{...defaultProps}
|
||||
|
@ -21,15 +50,28 @@ export default ({children, className: languageClassName}) => {
|
|||
code={children.trim()}
|
||||
language={language}>
|
||||
{({className, style, tokens, getLineProps, getTokenProps}) => (
|
||||
<pre className={classnames(className, styles.codeBlock)} style={style}>
|
||||
{tokens.map((line, i) => (
|
||||
<div key={i} {...getLineProps({line, key: i})}>
|
||||
{line.map((token, key) => (
|
||||
<span key={key} {...getTokenProps({token, key})} />
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</pre>
|
||||
<div className={styles.codeBlockWrapper}>
|
||||
<pre
|
||||
ref={target}
|
||||
className={classnames(className, styles.codeBlock)}
|
||||
style={style}>
|
||||
{tokens.map((line, i) => (
|
||||
<div key={i} {...getLineProps({line, key: i})}>
|
||||
{line.map((token, key) => (
|
||||
<span key={key} {...getTokenProps({token, key})} />
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</pre>
|
||||
<button
|
||||
ref={button}
|
||||
type="button"
|
||||
aria-label="Copy code to clipboard"
|
||||
className={styles.copyButton}
|
||||
onClick={handleCopyCode}>
|
||||
{showCopied ? 'Copied' : 'Copy'}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</Highlight>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue