Files
erika/components/copybutton.tsx
T

56 lines
1.7 KiB
TypeScript

"use client";
import React, { useState } from "react";
import { Check, Copy } from "lucide-react";
import { Button, buttonVariants } from "@/components/ui/button";
import { copyToClipboard } from "@/lib/utils";
import { cn } from "@/lib/utils";
import type { VariantProps } from "class-variance-authority";
export interface CopyButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
text?: string | (() => string);
onCopy?: () => void;
iconOnly?: boolean;
variant?: VariantProps<typeof buttonVariants>["variant"];
}
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";