Bin
2025-12-17 bc6aa38242b0a7dea4b18bc90e2d78740436a58b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import { useCallback } from "react";
import { useToast, ToastType } from "@humansignal/ui";
 
interface UseCopyTextOptions {
  successMessage?: string;
  errorMessage?: string;
}
 
export const useCopyText = (options: UseCopyTextOptions = {}) => {
  const toast = useToast();
  const { successMessage = "Copied to clipboard", errorMessage = "Failed to copy to clipboard" } = options;
 
  // Fallback function for copying text to clipboard
  const fallbackCopyToClipboard = useCallback(
    (text: string) => {
      const textArea = document.createElement("textarea");
      textArea.value = text;
 
      // Avoid scrolling to bottom of page in MS Edge
      textArea.style.top = "0";
      textArea.style.left = "0";
      textArea.style.position = "fixed";
      textArea.style.opacity = "0";
 
      document.body.appendChild(textArea);
      textArea.focus();
      textArea.select();
 
      try {
        const successful = document.execCommand("copy");
        if (successful) {
          toast?.show({ message: successMessage });
        } else {
          toast?.show({ message: errorMessage, type: ToastType.error });
        }
      } catch (err) {
        console.error("Failed to copy text: ", err);
        toast?.show({ message: errorMessage, type: ToastType.error });
      }
 
      document.body.removeChild(textArea);
    },
    [toast, successMessage, errorMessage],
  );
 
  const copyText = useCallback(
    async (text: string) => {
      // Try using the Clipboard API first
      if (navigator.clipboard && window.isSecureContext) {
        try {
          // Ensure the document is focused before attempting to copy
          if (!document.hasFocus()) {
            // If document is not focused, use the fallback method
            fallbackCopyToClipboard(text);
            return;
          }
 
          await navigator.clipboard.writeText(text);
          toast?.show({ message: successMessage });
        } catch (error) {
          console.error("Failed to copy to clipboard", error);
          fallbackCopyToClipboard(text);
        }
      } else {
        // Fallback for non-secure contexts or when Clipboard API is not available
        fallbackCopyToClipboard(text);
      }
    },
    [toast, successMessage, fallbackCopyToClipboard],
  );
 
  return copyText;
};