Skip to content

Commit 20b0927

Browse files
authored
Fix CopyToClipboard Issue (#5109)
* feat: enhance clipboard functionality with fallback support * feat: refactor toast notifications for clipboard copy functionality * refactor: simplify clipboard fallback logic by removing support check * refactor: improve fallback copy textarea styling for better accessibility
1 parent e789227 commit 20b0927

File tree

1 file changed

+54
-22
lines changed

1 file changed

+54
-22
lines changed

src/composables/useCopyToClipboard.ts

Lines changed: 54 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,64 @@ import { useToast } from 'primevue/usetoast'
44
import { t } from '@/i18n'
55

66
export function useCopyToClipboard() {
7-
const { copy, isSupported } = useClipboard()
7+
const { copy, copied } = useClipboard()
88
const toast = useToast()
9+
const showSuccessToast = () => {
10+
toast.add({
11+
severity: 'success',
12+
summary: t('g.success'),
13+
detail: t('clipboard.successMessage'),
14+
life: 3000
15+
})
16+
}
17+
const showErrorToast = () => {
18+
toast.add({
19+
severity: 'error',
20+
summary: t('g.error'),
21+
detail: t('clipboard.errorMessage')
22+
})
23+
}
24+
25+
function fallbackCopy(text: string) {
26+
const textarea = document.createElement('textarea')
27+
textarea.setAttribute('readonly', '')
28+
textarea.value = text
29+
textarea.style.position = 'absolute'
30+
textarea.style.left = '-9999px'
31+
textarea.setAttribute('aria-hidden', 'true')
32+
textarea.setAttribute('tabindex', '-1')
33+
textarea.style.width = '1px'
34+
textarea.style.height = '1px'
35+
document.body.appendChild(textarea)
36+
textarea.select()
37+
38+
try {
39+
// using legacy document.execCommand for fallback for old and linux browsers
40+
const successful = document.execCommand('copy')
41+
if (successful) {
42+
showSuccessToast()
43+
} else {
44+
showErrorToast()
45+
}
46+
} catch (err) {
47+
showErrorToast()
48+
} finally {
49+
textarea.remove()
50+
}
51+
}
952

1053
const copyToClipboard = async (text: string) => {
11-
if (isSupported) {
12-
try {
13-
await copy(text)
14-
toast.add({
15-
severity: 'success',
16-
summary: t('g.success'),
17-
detail: t('clipboard.successMessage'),
18-
life: 3000
19-
})
20-
} catch (err) {
21-
toast.add({
22-
severity: 'error',
23-
summary: t('g.error'),
24-
detail: t('clipboard.errorMessage')
25-
})
54+
try {
55+
await copy(text)
56+
if (copied.value) {
57+
showSuccessToast()
58+
} else {
59+
// If VueUse copy failed, try fallback
60+
fallbackCopy(text)
2661
}
27-
} else {
28-
toast.add({
29-
severity: 'error',
30-
summary: t('g.error'),
31-
detail: t('clipboard.errorNotSupported')
32-
})
62+
} catch (err) {
63+
// VueUse copy failed, try fallback
64+
fallbackCopy(text)
3365
}
3466
}
3567

0 commit comments

Comments
 (0)