mirror of
https://github.com/zhigang1992/react.git
synced 2026-03-26 22:42:51 +08:00
feat(utils): add use-clipboard
This commit is contained in:
53
components/utils/use-clipboard.ts
Normal file
53
components/utils/use-clipboard.ts
Normal 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
|
||||
@@ -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) {
|
||||
|
||||
@@ -68,9 +68,8 @@
|
||||
"styled-jsx": "^3.2.4",
|
||||
"typescript": "^3.8.2",
|
||||
"typescript-transform-paths": "^1.1.14",
|
||||
"use-clipboard-copy": "^0.1.2",
|
||||
"webpack": "^4.41.6",
|
||||
"webpack-cli": "^3.3.11"
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
}
|
||||
|
||||
12
yarn.lock
12
yarn.lock
@@ -2219,11 +2219,6 @@ cli-width@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
|
||||
integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=
|
||||
|
||||
clipboard-copy@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/clipboard-copy/-/clipboard-copy-3.1.0.tgz#4c59030a43d4988990564a664baeafba99f78ca4"
|
||||
integrity sha512-Xsu1NddBXB89IUauda5BIq3Zq73UWkjkaQlPQbLNvNsd5WBMnTWPNKYR6HGaySOxGYZ+BKxP2E9X4ElnI3yiPA==
|
||||
|
||||
clipboard@^2.0.0:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.6.tgz#52921296eec0fdf77ead1749421b21c968647376"
|
||||
@@ -7888,13 +7883,6 @@ url@0.11.0, url@^0.11.0:
|
||||
punycode "1.3.2"
|
||||
querystring "0.2.0"
|
||||
|
||||
use-clipboard-copy@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/use-clipboard-copy/-/use-clipboard-copy-0.1.2.tgz#83b16292dfa8ea262be714252022a8b4ad1c28c5"
|
||||
integrity sha512-EkauxqyX+us4+Mfif/f61ew89EAOWIArqFpHR0jSG4SwwuDZzDAOeqO7gkK0vi+DQVADeB1RB3xqU3U0oOO3NQ==
|
||||
dependencies:
|
||||
clipboard-copy "^3.0.0"
|
||||
|
||||
use-subscription@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.1.1.tgz#5509363e9bb152c4fb334151d4dceb943beaa7bb"
|
||||
|
||||
Reference in New Issue
Block a user