バグ解消法、お役立ち情報など

Next.jsのコードブロックにコピーボタンを設置する

image

はじめに

Next.jsで作成したコードブロックに、コピーボタンを設置する方法を記載します。

動作イメージは以下の通りです。

gif

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.tsx
import { 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>

これで、以下のようにコピーボタンを設置できました!

gif

おわりに

実装にあたって、下記の記事を参考にさせていただきました。

https://itc-engineering-blog.netlify.app/blogs/nextjs-filename-copy

バグ解消法、お役立ち情報など