@@ -22,7 +22,14 @@ export const useClipboard = (textToCopy: string): UseClipboardResult => {
22
22
setIsCopied ( false ) ;
23
23
} , 1000 ) ;
24
24
} catch ( err ) {
25
- const isCopied = simulateClipboardWrite ( textToCopy ) ;
25
+ const input = document . createElement ( "input" ) ;
26
+ input . value = textToCopy ;
27
+ document . body . appendChild ( input ) ;
28
+ input . focus ( ) ;
29
+ input . select ( ) ;
30
+ const isCopied = document . execCommand ( "copy" ) ;
31
+ document . body . removeChild ( input ) ;
32
+
26
33
if ( isCopied ) {
27
34
setIsCopied ( true ) ;
28
35
timeoutIdRef . current = window . setTimeout ( ( ) => {
@@ -42,61 +49,3 @@ export const useClipboard = (textToCopy: string): UseClipboardResult => {
42
49
43
50
return { isCopied, copyToClipboard } ;
44
51
} ;
45
-
46
- /**
47
- * Provides a fallback clipboard method for when browsers do not have access
48
- * to the clipboard API (the browser is older, or the deployment is only running
49
- * on HTTP, when the clipboard API is only available in secure contexts).
50
- *
51
- * It feels silly that you have to make a whole dummy input just to simulate a
52
- * clipboard, but that's really the recommended approach for older browsers.
53
- *
54
- * @see {@link https://web.dev/patterns/clipboard/copy-text?hl=en }
55
- */
56
- function simulateClipboardWrite ( textToCopy : string ) : boolean {
57
- const previousFocusTarget = document . activeElement ;
58
- const dummyInput = document . createElement ( "input" ) ;
59
-
60
- // Using visually-hidden styling to ensure that inserting the element doesn't
61
- // cause any content reflows on the page (removes any risk of UI flickers).
62
- // Can't use visibility:hidden or display:none, because then the elements
63
- // can't receive focus, which is needed for the execCommand method to work
64
- const style = dummyInput . style ;
65
- style . display = "inline-block" ;
66
- style . position = "absolute" ;
67
- style . overflow = "hidden" ;
68
- style . clip = "rect(0 0 0 0)" ;
69
- style . clipPath = "rect(0 0 0 0)" ;
70
- style . height = "1px" ;
71
- style . width = "1px" ;
72
- style . margin = "-1px" ;
73
- style . padding = "0" ;
74
- style . border = "0" ;
75
-
76
- document . body . appendChild ( dummyInput ) ;
77
- dummyInput . value = textToCopy ;
78
- dummyInput . focus ( ) ;
79
- dummyInput . select ( ) ;
80
-
81
- /**
82
- * The document.execCommand method is officially deprecated. Browsers are free
83
- * to remove the method entirely or choose to turn it into a no-op function
84
- * that always returns false. You cannot make any assumptions about how its
85
- * core functionality will be removed.
86
- *
87
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Clipboard }
88
- */
89
- let isCopied : boolean ;
90
- try {
91
- isCopied = document ?. execCommand ( "copy" ) ?? false ;
92
- } catch {
93
- isCopied = false ;
94
- }
95
-
96
- dummyInput . remove ( ) ;
97
- if ( previousFocusTarget instanceof HTMLElement ) {
98
- previousFocusTarget . focus ( ) ;
99
- }
100
-
101
- return isCopied ;
102
- }
0 commit comments