feat(utils): add use-clipboard

This commit is contained in:
unix
2020-04-03 06:34:28 +08:00
parent 9f34c332ea
commit 101a4c8395
4 changed files with 57 additions and 17 deletions

View File

@@ -0,0 +1,53 @@
import usePortal from './use-portal'
import useWarning from './use-warning'
import { useCallback } from 'react'
export type UseClipboardOptions = {
onError: Function
}
export type UseClipboardResult = {
copy: (text: string) => void
}
const defaultOptions: UseClipboardOptions = {
onError: () => useWarning('Failed to copy.', 'use-clipboard'),
}
const useClipboard = (
options: UseClipboardOptions = defaultOptions,
): UseClipboardResult => {
const el = usePortal('clipboard')
const copyText = (el: HTMLElement | null, text: string) => {
if (!el || !text) return
const selection = window.getSelection()
if (!selection) return
el.style.whiteSpace = 'pre'
el.textContent = text
const range = window.document.createRange()
selection.removeAllRanges()
range.selectNode(el)
selection.addRange(range)
try {
window.document.execCommand('copy')
} catch (e) {
options.onError && options.onError()
}
selection.removeAllRanges()
if (el) {
el.textContent = ''
}
}
const copy = useCallback((text: string) => {
copyText(el ,text)
}, [el])
return { copy }
}
export default useClipboard

View File

@@ -8,13 +8,13 @@ const createElement = (id: string): HTMLElement => {
return el
}
const usePortal = (selectId: string = getId()): Element | null => {
const usePortal = (selectId: string = getId()): HTMLElement | null => {
const id = `zeit-ui-${selectId}`
const { isBrowser } = useSSR()
const [elSnapshot, setElSnapshot] = useState<Element | null>(isBrowser ? createElement(id) : null)
const [elSnapshot, setElSnapshot] = useState<HTMLElement | null>(isBrowser ? createElement(id) : null)
useEffect(() => {
const hasElement = document.querySelector(`#${id}`)
const hasElement = document.querySelector<HTMLElement>(`#${id}`)
const el = hasElement || createElement(id)
if (!hasElement) {