import React from 'react'
import PropTypes from 'prop-types'
import { makeStyles } from '@material-ui/core/styles'
import { Button } from '@material-ui/core'
import { isBrowser } from '../utils/checks'
import { error } from '../utils/log'
import sleep from '../utils/sleep'
const useStyles = makeStyles(
{
textarea: {
opacity: 0,
width: 0,
height: 0,
padding: 0,
},
},
{ name: 'copyButton' }
)
/**
* Copy some text to the clipboard.
*
* @param {object} ref React reference object
* @param {string} text Value to be copied
*/
const copyToClipboard = async (ref, text = null) => {
const element = ref.current
if (!isBrowser || !element) return false
if (text) {
element.innerHTML = text
// Wait for some time until the DOM has been updated.
await sleep(1000)
}
const range = document.createRange()
range.selectNode(element)
window.getSelection().addRange(range)
let successful = false
try {
document.execCommand('copy')
successful = document.execCommand('copy')
} catch (err) {
error(`Unable to copy: ${err}`)
successful = false
}
window.getSelection().removeAllRanges()
return successful
}
/**
* Button to copy some text to the clipboard.
*
* @component
*/
const CopyButton = ({ value, children, ...props }) => {
const classes = useStyles()
const spanRef = React.createRef(null)
const handleClick = () => {
copyToClipboard(spanRef)
}
return (
<React.Fragment>
<span ref={spanRef} className={classes.textarea}>
{value}
</span>
<Button onClick={handleClick} {...props}>
{children}
</Button>
</React.Fragment>
)
}
CopyButton.propTypes = {
/** Value to be copied. */
value: PropTypes.string,
/** Content of the button component */
children: PropTypes.node.isRequired,
}
export default CopyButton
export { copyToClipboard }
Source