Skip to content

Instantly share code, notes, and snippets.

@manix84
Last active June 28, 2024 11:13
Show Gist options
  • Save manix84/a9bd5a9e57851dcef2577621fb587ae8 to your computer and use it in GitHub Desktop.
Save manix84/a9bd5a9e57851dcef2577621fb587ae8 to your computer and use it in GitHub Desktop.
A front end clipboard tool for multi type copying. It has fallback for FireFox and older browsers.
/**
This code is licensed under the terms of the MIT license
*/
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