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