Skip to content

Instantly share code, notes, and snippets.

@starkovsky
Created May 27, 2024 09:08
Show Gist options
  • Select an option

  • Save starkovsky/44c8a814d09d0482d3d85d93e1140c2b to your computer and use it in GitHub Desktop.

Select an option

Save starkovsky/44c8a814d09d0482d3d85d93e1140c2b to your computer and use it in GitHub Desktop.
/**
* Asynchronously writes data to the clipboard using the Clipboard API.
*
* @param {string | (() => Promise<string>)} stringOrPromise - A string or a promise that resolves to a string.
* @return {Promise<void>} A promise that resolves once the data is written to the clipboard.
* @throws {Error} If the Clipboard API is not supported.
* @throws {Error} If the data is a promise and the Clipboard API is not supported.
*
* @example
await copyToClipboard('Hello, world!')
* @example
const anyPromiseReturnString = async () =>
(await fetch('https://jsonplaceholder.typicode.com/posts/1'))
.json()
.then((data) => data.title);
await copyToClipboard(anyPromiseReturnString)
*/
export const copyToClipboard = async (stringOrPromise: string | (() => Promise<string>)): Promise<void> => {
if (!window.ClipboardItem) {
if (!navigator.clipboard || !navigator.clipboard.writeText) {
throw new Error('Clipboard is not supported');
}
if (typeof stringOrPromise === 'string') {
return navigator.clipboard.writeText(stringOrPromise);
}
return navigator.clipboard.writeText(await stringOrPromise());
}
try {
let item: ClipboardItem;
if (typeof stringOrPromise === 'string') {
item = new ClipboardItem({
'text/plain': new Blob([stringOrPromise], { type: 'text/plain' }),
});
} else {
const promiseBlob = (textString: string) => new Blob([textString], { type: 'text/plain' });
item = new ClipboardItem({
'text/plain': stringOrPromise().then(promiseBlob),
});
}
await navigator.clipboard.write([item]);
} catch (error) {
throw new Error(`Failed to write to clipboard: ${(error as Error).message}`);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment