feat(v2): CodeBlock copy button (#1643)

* feat(v2): CodeBlock copy button

* fix: live theme editor breaking bug
This commit is contained in:
Bruno Vego 2019-07-12 07:55:56 +02:00 committed by Endi
parent 4faa608edd
commit 7b7d1e6161
7 changed files with 164 additions and 21 deletions

View file

@ -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>
);