CopyTooltip.tsx
1 // svg 2 import { ReactComponent as CopyIcon } from "@assets/svg/files/copy-icon.svg"; 3 import { ReactComponent as CopyGrayIcon } from "@/assets/svg/files/copy-gray-icon.svg"; 4 // 5 import { VariantProps, cva } from "cva"; 6 import { ButtonHTMLAttributes, FC, useState } from "react"; 7 import * as Popover from "@radix-ui/react-popover"; 8 import { useTranslation } from "react-i18next"; 9 10 const customCopy = cva("customCopy", { 11 variants: { 12 background: { 13 default: ["bg-AccpetButtonColor"], 14 noBG: ["bg-transparent"], 15 }, 16 rounded: { 17 small: ["rounded-sm"], 18 medium: ["rounded"], 19 large: ["rounded-md"], 20 xLarge: ["rounded-lg"], 21 }, 22 boxSize: { 23 none: ["p-0"], 24 small: ["p-1"], 25 }, 26 }, 27 defaultVariants: { 28 boxSize: "none", 29 background: "noBG", 30 rounded: "medium", 31 }, 32 }); 33 34 const copyIcon = cva("copyIcon", { 35 variants: { 36 size: { 37 xSmall: ["w-3", "h-3"], 38 small: ["w-4", "h-4"], 39 medium: ["w-5", "h-5"], 40 large: ["w-6", "h-6"], 41 xLarge: ["w-8", "h-8"], 42 }, 43 }, 44 defaultVariants: { 45 size: "medium", 46 }, 47 }); 48 49 export interface TooltipProps 50 extends ButtonHTMLAttributes<HTMLButtonElement>, 51 VariantProps<typeof copyIcon>, 52 VariantProps<typeof customCopy> { 53 side?: "top" | "right" | "bottom" | "left" | undefined; 54 sideOffset?: number | undefined; 55 align?: "center" | "end" | "start" | undefined; 56 alignOffset?: number | undefined; 57 showTime?: number | undefined; 58 copyStroke?: string; 59 copyText?: string; 60 isTransaction?: boolean; 61 } 62 63 export const CustomCopy: FC<TooltipProps> = ({ 64 className, 65 copyText = "copy", 66 background, 67 rounded, 68 size, 69 boxSize, 70 side = "top", 71 sideOffset = 0, 72 align = "start", 73 alignOffset = 0, 74 showTime = 1000, 75 copyStroke = "fill-PrimaryTextColorLight dark:fill-PrimaryTextColor", 76 isTransaction = false, 77 ...props 78 }) => { 79 const { t } = useTranslation(); 80 const [open, setOpen] = useState(false); 81 return ( 82 <Popover.Root open={open}> 83 <Popover.Trigger asChild> 84 <button 85 onClick={() => { 86 navigator.clipboard.writeText(copyText); 87 setOpen(true); 88 setTimeout(() => { 89 setOpen(false); 90 }, showTime); 91 }} 92 className={`p-0 ${customCopy({ 93 background, 94 rounded, 95 boxSize, 96 className, 97 })}`} 98 {...props} 99 > 100 {isTransaction ? ( 101 <CopyGrayIcon 102 className={`!stroke-0 ${copyStroke} ${copyIcon({ size })}`} 103 /> 104 ) : ( 105 <CopyIcon 106 className={`!stroke-0 ${copyStroke} ${copyIcon({ size })}`} 107 /> 108 )} 109 </button> 110 </Popover.Trigger> 111 <Popover.Portal className="z-[9999]"> 112 <Popover.Content 113 className="z-[9999] shadow-md" 114 side={side} 115 sideOffset={sideOffset} 116 align={align} 117 alignOffset={alignOffset} 118 > 119 <div className="flex flex-row justify-start items-center py-1 px-2 bg-SecondaryColorLight/50 dark:bg-SecondaryColor/50 rounded-md"> 120 <p className="text-sm text-PrimaryTextColorLight/60 dark:text-PrimaryTextColor/60"> 121 {t("copied")} 122 </p> 123 </div> 124 <Popover.Arrow className="fill-SecondaryColorLight/50 dark:fill-SecondaryColor/50" /> 125 </Popover.Content> 126 </Popover.Portal> 127 </Popover.Root> 128 ); 129 };