You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
1.6 KiB
69 lines
1.6 KiB
2 years ago
|
import { ref, watch } from 'vue'
|
||
|
|
||
|
import { isDef } from '@/utils/is'
|
||
|
interface Options {
|
||
|
target?: HTMLElement
|
||
|
}
|
||
|
export function useCopyToClipboard(initial?: string) {
|
||
|
const clipboardRef = ref(initial || '')
|
||
|
const isSuccessRef = ref(false)
|
||
|
const copiedRef = ref(false)
|
||
|
|
||
|
watch(
|
||
|
clipboardRef,
|
||
|
(str?: string) => {
|
||
|
if (isDef(str)) {
|
||
|
copiedRef.value = true
|
||
|
isSuccessRef.value = copyTextToClipboard(str)
|
||
|
}
|
||
|
},
|
||
|
{ immediate: !!initial, flush: 'sync' }
|
||
|
)
|
||
|
|
||
|
return { clipboardRef, isSuccessRef, copiedRef }
|
||
|
}
|
||
|
|
||
|
export function copyTextToClipboard(input: string, { target = document.body }: Options = {}) {
|
||
|
const element = document.createElement('textarea')
|
||
|
const previouslyFocusedElement = document.activeElement
|
||
|
|
||
|
element.value = input
|
||
|
|
||
|
element.setAttribute('readonly', '')
|
||
|
;(element.style as any).contain = 'strict'
|
||
|
element.style.position = 'absolute'
|
||
|
element.style.left = '-9999px'
|
||
|
element.style.fontSize = '12pt'
|
||
|
|
||
|
const selection = document.getSelection()
|
||
|
let originalRange
|
||
|
if (selection && selection.rangeCount > 0) {
|
||
|
originalRange = selection.getRangeAt(0)
|
||
|
}
|
||
|
|
||
|
target.append(element)
|
||
|
element.select()
|
||
|
|
||
|
element.selectionStart = 0
|
||
|
element.selectionEnd = input.length
|
||
|
|
||
|
let isSuccess = false
|
||
|
try {
|
||
|
isSuccess = document.execCommand('copy')
|
||
|
} catch (e: any) {
|
||
|
throw new Error(e)
|
||
|
}
|
||
|
|
||
|
element.remove()
|
||
|
|
||
|
if (originalRange && selection) {
|
||
|
selection.removeAllRanges()
|
||
|
selection.addRange(originalRange)
|
||
|
}
|
||
|
|
||
|
if (previouslyFocusedElement) {
|
||
|
;(previouslyFocusedElement as HTMLElement).focus()
|
||
|
}
|
||
|
return isSuccess
|
||
|
}
|