github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/ui/dashboard/src/components/CopyToClipboard/index.tsx (about) 1 import copy from "copy-to-clipboard"; 2 import { classNames } from "../../utils/styles"; 3 import { 4 CopyToClipboardIcon, 5 CopyToClipboardSuccessIcon, 6 } from "../../constants/icons"; 7 import { 8 createContext, 9 useCallback, 10 useContext, 11 useEffect, 12 useState, 13 } from "react"; 14 15 type ICopyToClipboardContext = { 16 doCopy: boolean; 17 setDoCopy: (value: boolean) => void; 18 }; 19 20 const CopyToClipboardContext = createContext<ICopyToClipboardContext | null>( 21 null 22 ); 23 24 const CopyToClipboardProvider = ({ children }) => { 25 const [doCopy, setDoCopy] = useState(false); 26 return ( 27 <CopyToClipboardContext.Provider value={{ doCopy, setDoCopy }}> 28 {children({ setDoCopy })} 29 </CopyToClipboardContext.Provider> 30 ); 31 }; 32 33 const CopyToClipboard = ({ 34 data, 35 className = "text-foreground-light", 36 stopPropagation = true, 37 }) => { 38 const context = useContext(CopyToClipboardContext); 39 const { doCopy, setDoCopy } = context 40 ? context 41 : ({} as ICopyToClipboardContext); 42 const [copySuccess, setCopySuccess] = useState(false); 43 44 const handleCopy = useCallback( 45 async (e) => { 46 if (e && stopPropagation) { 47 e.stopPropagation(); 48 } 49 const copyOutput = copy(data); 50 if (copyOutput) { 51 setCopySuccess(true); 52 } 53 }, 54 [data, setCopySuccess, stopPropagation] 55 ); 56 57 useEffect(() => { 58 let timeoutId; 59 if (copySuccess) { 60 timeoutId = setTimeout(() => { 61 setCopySuccess(false); 62 }, 1000); 63 } 64 return () => clearTimeout(timeoutId); 65 }, [copySuccess]); 66 67 useEffect(() => { 68 const triggerCopy = async () => { 69 // @ts-ignore 70 await handleCopy(); 71 setDoCopy(false); 72 }; 73 if (doCopy) { 74 triggerCopy(); 75 } 76 }, [handleCopy, doCopy, setDoCopy]); 77 78 return ( 79 <> 80 {!copySuccess && ( 81 <CopyToClipboardIcon 82 className={classNames("h-6 w-6 cursor-pointer", className)} 83 onClick={handleCopy} 84 /> 85 )} 86 {copySuccess && ( 87 <CopyToClipboardSuccessIcon className="h-6 w-6 text-ok" /> 88 )} 89 </> 90 ); 91 }; 92 93 export default CopyToClipboard; 94 95 export { CopyToClipboardProvider };