Last active
July 24, 2024 08:26
-
-
Save manix84/2bf3d984ee115eadfc3e5e3385213480 to your computer and use it in GitHub Desktop.
A React+Typescript hook for copying different mime types to the clipboard at once.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| This code is licensed under the terms of the MIT license | |
| */ | |
| /** | |
| Usage: | |
| const { copyToClipboard } = useClipboard(); | |
| copyToClipboard([ | |
| { type: "text/plain", data: "Some String" }, | |
| { type: "text/html", data: "<h1>Some Header</h1>" } | |
| ])?.then(() => { | |
| console.log("SUCCESS") | |
| }).catch(() => { | |
| console.error("OH NOS!") | |
| }); | |
| */ | |
| import { useCallback } from 'react'; | |
| type ClipboardItemData = { | |
| type: string; | |
| data: string; | |
| }; | |
| const useClipboard = () => { | |
| const copyToClipboard = useCallback(async (items: ClipboardItemData[]): Promise<void> => { | |
| if (navigator.clipboard && navigator.clipboard.write) { | |
| try { | |
| if (typeof ClipboardItem !== 'undefined' && navigator.clipboard.write) { | |
| const clipboardItems = new ClipboardItem( | |
| items.reduce((acc, item) => { | |
| acc[item.type] = new Blob([item.data], { type: item.type }); | |
| return acc; | |
| }, {} as Record<string, string | Blob | PromiseLike<string | Blob>>)); | |
| await navigator.clipboard.write([clipboardItems]); | |
| } else { | |
| const plainText = (items.filter((item) => item.type === "text/plain")[0] || items[0]).data; | |
| // Fallback for browsers that do not support ClipboardItem (e.g., Firefox) | |
| await navigator.clipboard.writeText(plainText); | |
| } | |
| } catch (error) { | |
| console.error('Error copying to clipboard: ', error); | |
| throw error; | |
| } | |
| } else { | |
| // Fallback to document.execCommand for older browsers | |
| const plainText = (items.filter((item) => item.type === "text/plain")[0] || items[0]).data; | |
| const textarea = document.createElement('textarea'); | |
| textarea.value = plainText; | |
| document.body.appendChild(textarea); | |
| textarea.select(); | |
| try { | |
| document.execCommand('copy'); | |
| } catch (error) { | |
| console.error('Error copying to clipboard: ', error); | |
| throw error; | |
| } finally { | |
| document.body.removeChild(textarea); | |
| } | |
| } | |
| }, []); | |
| return { copyToClipboard }; | |
| }; | |
| export default useClipboard; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment