import { useEffect } from 'react'
/**
* Custom hook that intercepts all copy operations and forces them to copy plain text only (no formatting).
*
* This hook automatically enables plain text copying for the entire application when called.
*
* @example
* ```tsx
* function App() {
* // Enable plain text copying for the entire app
* useCopyAsPlainText()
*
* return
Your app content
* }
* ```
*/
export const useCopyAsPlainText = (): void => {
useEffect(() => {
const handleCopy = async (event: ClipboardEvent) => {
// Get the current selection
const selection = window.getSelection()
if (!selection || selection.rangeCount === 0) {
// No selection, let default behavior happen
return
}
// Get the selected text as plain text
const plainText = selection.toString()
if (!plainText) {
// No text selected, let default behavior happen
return
}
// Prevent the default copy behavior
event.preventDefault()
try {
// Check if Clipboard API is available (modern browsers)
if (navigator.clipboard && navigator.clipboard.writeText) {
await navigator.clipboard.writeText(plainText)
} else {
// Fallback for older browsers using the deprecated method
// Create a temporary textarea element
const textarea = document.createElement('textarea')
textarea.value = plainText
textarea.style.position = 'fixed'
textarea.style.left = '-9999px'
textarea.style.top = '-9999px'
document.body.appendChild(textarea)
textarea.focus()
textarea.select()
try {
document.execCommand('copy')
} finally {
document.body.removeChild(textarea)
}
}
} catch {
// Silently fall back to default behavior
}
}
// Add the event listener to the document
document.addEventListener('copy', handleCopy)
// Cleanup function to remove the event listener
return () => {
document.removeEventListener('copy', handleCopy)
}
}, [])
}
export default useCopyAsPlainText