gitscope
← marzneshin / v0.3.0-alpha8 / dashboard/src/components/copy-button/index.tsx
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/components/copy-button/index.tsx · TypeScript
Blame Raw
 1import { Button, Tooltip, TooltipContent, TooltipTrigger } from '@marzneshin/components';
 2import CopyToClipboard from 'react-copy-to-clipboard';
 3import { useEffect, useState } from 'react';
 4import { useTranslation } from 'react-i18next';
 5import { CopyCheck, CopyX, ClipboardCopy, LucideIcon } from 'lucide-react';
 6import { toast } from 'sonner';
 7import { cn } from '@marzneshin/utils';
 8
 9interface CopyToClipboardButtonProps {
10    text: string;
11    disabled?: boolean;
12    successMessage: string;
13    copyIcon?: LucideIcon;
14    copyLabel?: string;
15    errorLabel?: string;
16    className?: string;
17    tooltipMsg?: string;
18}
19
20export const CopyToClipboardButton: React.FC<CopyToClipboardButtonProps> = ({
21    text,
22    disabled = false,
23    successMessage,
24    copyIcon,
25    copyLabel,
26    errorLabel, className,
27    tooltipMsg
28}) => {
29    const { t } = useTranslation();
30    const [copied, setCopied] = useState(false);
31    const [healthy, setHealthy] = useState(false);
32
33    useEffect(() => {
34        if (copied) {
35            toast.success(t(successMessage));
36            setTimeout(() => {
37                setCopied(false);
38            }, 1000);
39        }
40    }, [copied, successMessage, t]);
41
42    useEffect(() => {
43        setHealthy(text !== '');
44    }, [text]);
45
46    const handleClick = () => {
47        if (!disabled) {
48            setCopied(true);
49        }
50    };
51
52    const tooltip = tooltipMsg ? tooltipMsg : (copyLabel ? copyLabel : undefined)
53
54    const Icon = copied ? CopyCheck : (healthy ? (copyIcon ? copyIcon : ClipboardCopy) : CopyX)
55    const isWithLabel = successMessage && copyLabel && errorLabel
56
57    return (
58        <Tooltip>
59            <TooltipTrigger>
60                <CopyToClipboard text={text}>
61                    <Button className={cn(className, "p-2 flex flex-row items-center gap-2")} disabled={disabled || !healthy} onClick={handleClick}>
62                        <Icon />
63                        {isWithLabel && t(copied ? successMessage : (healthy ? copyLabel : errorLabel))}
64                    </Button>
65                </CopyToClipboard>
66            </TooltipTrigger>
67            {tooltip &&
68                <TooltipContent>
69                    {tooltip}
70                </TooltipContent>
71            }
72        </Tooltip >
73    );
74};