1. 概要
ちょっとした小ネタなので忘備録も兼ねて短めに内容をまとめます。
今回実装しているプロジェクトで、クリップボードを実装する要件があったので実装してみました。あまりNext.jsにおいてクリップボードを組み込む記事がないように感じたので、今回はUI面も含めてクリップボードの作り方を紹介しようと思います。
2. Clipboard
早速コードを紹介しようと思います。
UIライブラリーはchakra-uiを使用していて、アイコンはreact iconsを使用しています。
"use client";
import { Center, Tooltip } from "@chakra-ui/react";
import { useState } from "react";
import { FaCheck } from "react-icons/fa6";
import { MdErrorOutline, MdOutlineCopyAll } from "react-icons/md";
export default function ClipBoard({ value }:{ value:string }){
const [isCopied, setIsCopied] = useState(false);
const [err, setErr] = useState(false);
async function handleCopy(){
try{
setErr(false);
await navigator.clipboard.writeText(value);
setIsCopied(true);
await new Promise(resolve => setTimeout(resolve, 5000));
setIsCopied(false);
}catch(err){
setErr(true);
}
}
return(
<Tooltip hasArrow label={err ? "error" : isCopied ? "copied" : "copy"} color={err ? "red" : "black"} fontSize="sm" bgColor="gray.200" >
<Center mx={2} _hover={{ cursor: "pointer" }} onClick={handleCopy}>
{ err ? <MdErrorOutline color="red" /> : isCopied ? <FaCheck color="#39aaaa" /> : <MdOutlineCopyAll color="#39aaaa" />}
</Center>
</Tooltip>
);
}
まずUI面について説明します。
基本的にはコピーのアイコンが表示されるようになっており、そのアイコンをホバーするとTooltipによって状態を表すテキストが表示されます。TooltipはUIを設定する複数のプロパティを持っていて、hasArrowで吹き出しに矢印を付けるかどうかや、placementで吹き出しの位置を調整することもできます。細かい内容は公式ドキュメントを参照してもらえればと思います。
デフォルトではコピーのアイコンを表示しておいて、コピーできたかやエラーが発生したかに基づいてアイコンを出し分けるようにしています。
実際にどういうアイコンを使うかはその時々の要件に合わせるとよいでしょう。
次にロジック面について説明します。
クリップボードにテキストを張り付けるコード自体はawait navigator.clipboard.writeText(value)
ですが、その前後で少々工夫しています。
isCopiedの状態によってチェックアイコンとコピーアイコンを使い分けているのですが、await new Promise(resolve => setTimeout(resolve, 5000))
のあとにsetIsCopied(false)
とすることで時間経過でもとのコピーアイコンに戻し、再びコピーができるようになることを視覚的に表現しています。
一つ注意したいのが、navigatorオブジェクトはJavaScriptの組み込みのWebAPIであるのでクライアントサイドでしか使えません。コンポーネントを記述したファイルのトップに"use client"
を付けるのを忘れないようにしましょう。
3. おわりに
一つのコンポーネントについてだけなのでかなり短い記事になりましたが、お役に立てれば幸いです。