Next.jsのコードブロックにコピーボタンを設置する
はじめに
Next.jsで作成したコードブロックに、コピーボタンを設置する方法を記載します。
動作イメージは以下の通りです。
echo 'Hello, World!';
ファイル名を指定した場合echo 'Hello, World!';
右側のアイコンをクリックすると、コードがクリップボードにコピーされます。
作り方
1. react-copy-to-clipboard のインストール
まずはReactのライブラリであるreact-copy-to-clipboard
をインストールします。
npm i react-copy-to-clipboard --save
2. 実装
先に最終形をお見せすると、以下のようになります。
CodeBlock.tsximport { CopyToClipboard } from 'react-copy-to-clipboard' import { FaRegClone } from "react-icons/fa"; const customCode: CodeComponent = ({ node, inline, className, children, ...props }) => { const [isCopied, setIsCopied] = React.useState(false); const onCopyClicked = () => { setIsCopied(true); setTimeout(() => { setIsCopied(false); }, 4000); }; return !inline && match ? ( <div> <div className="code-block-wrapper"> <span className='code-block-body'> <SyntaxHighlighter> {String(children).replace(/\n$/, '')} </SyntaxHighlighter> <CopyToClipboard text={children}> <button onClick={onCopyClicked} className="copy-button"> <span>{isCopied ? "copied!" : <FaRegClone />}</span> </button> </CopyToClipboard> </span> </div> <style jsx>{` .code-block-body { position: relative; height: 100%; display: block; } .copy-button { position: absolute; right: 0; top: 0px; border: 0px; background: transparent; color: #f2f2f2; padding: 12px; font-size: 1em; cursor: pointer; } `}</style> </div> ); };
(importなど、不要な記述は省略しています)
まず、useState
でコピーボタンの状態を管理するための準備をします。
const [isCopied, setIsCopied] = React.useState(false);
react-copy-to-clipboard
ライブラリを使い、コピー処理を実装します。
const onCopyClicked = () => { setIsCopied(true); setTimeout(() => { setIsCopied(false); }, 4000); }; ... <CopyToClipboard text={children}> <button onClick={onCopyClicked} className="copy-button"> <span>{isCopied ? "copied!" : <FaRegClone />}</span> </button> </CopyToClipboard>
CSSでコピーボタンの見た目を調整します。
<style jsx>{` .code-block-body { position: relative; height: 100%; display: block; } .copy-button { position: absolute; right: 0; top: 0px; border: 0px; background: transparent; color: #f2f2f2; padding: 12px; font-size: 1em; cursor: pointer; } `}</style>
これで、以下のようにコピーボタンを設置できました!
おわりに
実装にあたって、下記の記事を参考にさせていただきました。
https://itc-engineering-blog.netlify.app/blogs/nextjs-filename-copy