1+ export default function copyToClipboard ( text : string ) {
2+ // Use the Async Clipboard API when available. Requires a secure browing context (i.e. HTTPS)
3+ if ( ( navigator as any ) . clipboard ) {
4+ return ( navigator as any ) . clipboard . writeText ( text )
5+ }
6+
7+ // ...Otherwise, use document.execCommand() fallback
8+
9+ // Put the text to copy into a <span>
10+ const span = document . createElement ( 'span' )
11+ span . textContent = text
12+
13+ // Preserve consecutive spaces and newlines
14+ span . style . whiteSpace = 'pre'
15+
16+ // Add the <span> to the page
17+ document . body . appendChild ( span )
18+
19+ // Make a selection object representing the range of text selected by the user
20+ const selection = window . getSelection ( )
21+ const range = window . document . createRange ( )
22+
23+ if ( ! selection ) {
24+ return Promise . reject ( )
25+ }
26+
27+ selection . removeAllRanges ( )
28+ range . selectNode ( span )
29+ selection . addRange ( range )
30+
31+ // Copy text to the clipboard
32+ let success = false
33+ try {
34+ success = window . document . execCommand ( 'copy' )
35+ } catch ( err ) {
36+ console . log ( 'Failed to copy text. Error: ' , err )
37+ }
38+
39+ // Cleanup
40+ selection . removeAllRanges ( )
41+ window . document . body . removeChild ( span )
42+
43+ // The Async Clipboard API returns a promise that may reject with `undefined`
44+ // so we match that here for consistency.
45+ return success
46+ ? Promise . resolve ( )
47+ : Promise . reject ( )
48+ }
0 commit comments