54 lines
1.5 KiB
TypeScript
54 lines
1.5 KiB
TypeScript
"use client";
|
|
|
|
import React, { useState } from "react";
|
|
import { Check, Copy } from "lucide-react";
|
|
import { Button } from "@/components/ui/button";
|
|
import { copyToClipboard } from "@/lib/utils";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
export interface CopyButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
text?: string | (() => string);
|
|
onCopy?: () => void;
|
|
iconOnly?: boolean;
|
|
variant?: any;
|
|
}
|
|
|
|
export const CopyButton = React.forwardRef<HTMLButtonElement, CopyButtonProps>(
|
|
({ text, onCopy, iconOnly = true, className, variant = "link", children, onClick, ...props }, ref) => {
|
|
const [copied, setCopied] = useState(false);
|
|
|
|
const handleCopy = (e: React.MouseEvent<HTMLButtonElement>) => {
|
|
e.stopPropagation();
|
|
|
|
if (text) {
|
|
const copyContent = typeof text === "function" ? text() : text;
|
|
copyToClipboard(copyContent);
|
|
}
|
|
|
|
if (onCopy) {
|
|
onCopy();
|
|
}
|
|
|
|
if (onClick) {
|
|
onClick(e);
|
|
}
|
|
|
|
setCopied(true);
|
|
setTimeout(() => setCopied(false), 2000);
|
|
};
|
|
|
|
return (
|
|
<Button
|
|
ref={ref}
|
|
onClick={handleCopy}
|
|
variant={variant}
|
|
className={cn(iconOnly ? "h-auto p-0 text-green-400 hover:text-green-300" : "", className)}
|
|
{...props}
|
|
>
|
|
{copied ? <Check className={iconOnly ? "w-3 h-3" : "w-4 h-4 mr-2 text-green-400"} /> : <Copy className={iconOnly ? "w-3 h-3" : "w-4 h-4 mr-2"} />}
|
|
{!iconOnly && children}
|
|
</Button>
|
|
);
|
|
}
|
|
);
|
|
CopyButton.displayName = "CopyButton"; |