mirror of https://github.com/kern/filepizza
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
1.3 KiB
TypeScript
62 lines
1.3 KiB
TypeScript
import { useState, useCallback, useEffect } from 'react'
|
|
|
|
export default function useClipboard(
|
|
text: string,
|
|
delay = 1000,
|
|
): {
|
|
hasCopied: boolean
|
|
onCopy: () => void
|
|
} {
|
|
const [hasCopied, setHasCopied] = useState(false)
|
|
|
|
const onCopy = useCallback(() => {
|
|
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
navigator.clipboard
|
|
.writeText(text)
|
|
.then(() => {
|
|
setHasCopied(true)
|
|
})
|
|
.catch((error) => {
|
|
console.error('Clipboard API error:', error)
|
|
fallbackCopyText(text)
|
|
})
|
|
} else {
|
|
fallbackCopyText(text)
|
|
}
|
|
}, [text])
|
|
|
|
const fallbackCopyText = (textToCopy: string) => {
|
|
const textArea = document.createElement('textarea')
|
|
textArea.value = textToCopy
|
|
|
|
textArea.style.position = 'absolute'
|
|
textArea.style.left = '-999999px'
|
|
|
|
document.body.appendChild(textArea)
|
|
textArea.select()
|
|
|
|
try {
|
|
document.execCommand('copy')
|
|
setHasCopied(true)
|
|
} catch (error) {
|
|
console.error('execCommand:', error)
|
|
} finally {
|
|
textArea.remove()
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
let timeoutId: NodeJS.Timeout
|
|
if (hasCopied) {
|
|
timeoutId = setTimeout(() => {
|
|
setHasCopied(false)
|
|
}, delay)
|
|
}
|
|
return () => {
|
|
clearTimeout(timeoutId)
|
|
}
|
|
}, [hasCopied, delay])
|
|
|
|
return { hasCopied, onCopy }
|
|
}
|