61 lines
1.7 KiB
TypeScript
61 lines
1.7 KiB
TypeScript
/**
|
|
* 點擊複製按鈕組件
|
|
*/
|
|
|
|
import { useState } from "react";
|
|
import { Check, Copy } from "lucide-react";
|
|
import { Button } from "@/Components/ui/button";
|
|
import {
|
|
Tooltip,
|
|
TooltipContent,
|
|
TooltipProvider,
|
|
TooltipTrigger,
|
|
} from "@/Components/ui/tooltip";
|
|
import { toast } from "sonner";
|
|
|
|
interface CopyButtonProps {
|
|
text: string;
|
|
label?: string;
|
|
className?: string;
|
|
}
|
|
|
|
export default function CopyButton({ text, label = "複製", className }: CopyButtonProps) {
|
|
const [copied, setCopied] = useState(false);
|
|
|
|
const handleCopy = async () => {
|
|
try {
|
|
await navigator.clipboard.writeText(text);
|
|
setCopied(true);
|
|
toast.success(`${label}已複製`);
|
|
setTimeout(() => setCopied(false), 2000);
|
|
} catch (err) {
|
|
toast.error("複製失敗");
|
|
}
|
|
};
|
|
|
|
return (
|
|
<TooltipProvider>
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
className={`h-6 w-6 p-0 hover:bg-gray-100 ${className}`}
|
|
onClick={handleCopy}
|
|
>
|
|
{copied ? (
|
|
<Check className="h-3.5 w-3.5 text-green-600" />
|
|
) : (
|
|
<Copy className="h-3.5 w-3.5 text-gray-400" />
|
|
)}
|
|
<span className="sr-only">{label}</span>
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent>
|
|
<p>{copied ? "已複製!" : label}</p>
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
</TooltipProvider>
|
|
);
|
|
}
|