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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 
 
 
 
 

68 lines
1.6 KiB

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
}