All files / pages/ApiKeys CopyToClipboardButton.tsx

41.66% Statements 5/12
25% Branches 1/4
33.33% Functions 1/3
45.45% Lines 5/11

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45                      1x 2x 2x   2x                                   2x                      
import { useState } from 'react';
import { Button } from '@/components/ui/button';
import { Copy, Check } from 'lucide-react';
import { useToast } from '@/hooks/use-toast';
 
interface CopyToClipboardButtonProps {
    value: string;
    label?: string;
    className?: string;
}
 
export const CopyToClipboardButton = ({ value, label, className }: CopyToClipboardButtonProps) => {
    const [copied, setCopied] = useState(false);
    const { toast } = useToast();
 
    const handleCopy = async () => {
        try {
            await navigator.clipboard.writeText(value);
            setCopied(true);
            toast({
                title: label ? `${label} copied` : 'Copied to clipboard',
                variant: 'default',
            });
            setTimeout(() => setCopied(false), 2000);
        } catch (err) {
            toast({
                title: 'Failed to copy',
                description: 'Please try selecting and copying manually.',
                variant: 'destructive',
            });
        }
    };
 
    return (
        <Button
            variant="ghost"
            size="sm"
            className={className}
            onClick={handleCopy}
        >
            {copied ? <Check className="h-4 w-4 text-green-500" /> : <Copy className="h-4 w-4" />}
        </Button>
    );
};