Markdown is the markup language of choice for tech-savvy bloggers and publishing code samples is commonplace. When creating tutorials (such as this one), it's nice to have a quick way to copy a code block to the clipboard, instead of having to drag-select the code.
This tutorial will use two React libraries: react-markdown
and react-syntax-highlighter
.
We start with a component called postBody
. This is responsible for rendering our markdown as HTML:
import ReactMarkdown from 'react-markdown';
import rehypeRaw from 'rehype-raw';
import remarkGfm from 'remark-gfm';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
import { a11yDark } from 'react-syntax-highlighter/dist/cjs/styles/prism'
import CodeCopyBtn from './codeCopyBtn';
export default function PostBody({ content }) {
// Add the CodeCopyBtn component to our PRE element
const Pre = ({ children }) => <pre className="blog-pre">
<CodeCopyBtn>{children}</CodeCopyBtn>
{children}
</pre>
return (
<ReactMarkdown
className='post-markdown'
linkTarget='_blank'
rehypePlugins={[rehypeRaw]}
remarkPlugins={[remarkGfm]}
components={{
pre: Pre,
code({ node, inline, className = "blog-code", children, ...props }) {
const match = /language-(\w+)/.exec(className || '')
return !inline && match ? (
<SyntaxHighlighter
style={a11yDark}
language={match[1]}
PreTag="div"
{...props}
>
{String(children).replace(/\n$/, '')}
</SyntaxHighlighter>
) : (
<code className={className} {...props}>
{children}
</code>
)
}
}}
>
{content}
</ReactMarkdown>
)
}
And then we'll create a component called codeCopyBtn
:
import React from "react";
export default function CodeCopyBtn({ children }) {
const [copyOk, setCopyOk] = React.useState(false);
const iconColor = copyOk ? '#0af20a' : '#ddd';
const icon = copyOk ? 'fa-check-square' : 'fa-copy';
const handleClick = (e) => {
navigator.clipboard.writeText(children[0].props.children[0]);
console.log(children)
setCopyOk(true);
setTimeout(() => {
setCopyOk(false);
}, 500);
}
return (
<div className="code-copy-btn">
<i className={`fas ${icon}`} onClick={handleClick} style={{color: iconColor}} />
</div>
)
}
And here's the CSS:
.blog-pre {
margin-bottom: 3em !important;
-webkit-box-shadow: -10px 0px 13px -7px #000000, 10px 0px 13px -7px #000000, 35px -23px 2px -16px rgba(0, 0, 0, 0);
box-shadow: -10px 0px 13px -7px #000000, 10px 0px 13px -7px #000000, 35px -23px 2px -16px rgba(0, 0, 0, 0);
position: relative;
}
.code-copy-btn {
color: white;
position: absolute;
right: 10px;
top: -2px;
font-size: 1.5em;
cursor: pointer;
transition: all 0.3s ease-in-out;
}
.code-copy-btn:hover {
transform: scale(1.1);
opacity: 0.9;
}
I hope you found this tutorial useful. Happy coding!
For more great information, please Visit our Blog.