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 };