Skip to content

Instantly share code, notes, and snippets.

@mattlo
Created April 26, 2018 21:07
Show Gist options
  • Save mattlo/f5865c5938ee52787f7044c6a841beae to your computer and use it in GitHub Desktop.
Save mattlo/f5865c5938ee52787f7044c6a841beae to your computer and use it in GitHub Desktop.
import React, {Component, Fragment} from 'react';
import PropTypes from 'prop-types';
import {Icon} from '@blueprintjs/core';
import {css, keyframes} from 'emotion';
import classnames from 'classnames';
export const hoverStyle = css`
&:hover .clipboard-btn {
visibility: visible;
opacity: 1;
}
`;
export const clipboardFx = keyframes`
0% {
opacity: 1;
transform: scale(.5);
}
80%, 100% {
opacity: 0;
}
`;
const clipboardSize = 16;
const clipboardPulseSize = clipboardSize * 3;
export const clipboardBtn = css`
visibility: hidden;
opacity: 0;
margin-left: 5px;
transition: all 0.1s ease-in-out;
position: relative;
& svg {
position: relative;
z-index: 2;
}
&:before {
content: '';
opacity: 0;
position: absolute;
display: block;
top: ${((clipboardPulseSize - clipboardSize) / 2) * -1}px;
left: ${((clipboardPulseSize - clipboardSize) / 2) * -1}px;
width: ${clipboardPulseSize}px;
height: ${clipboardPulseSize}px;
border-radius: 120%;
box-sizing: border-box;
background-color: #BFCCD6;
z-index: 0;
}
&:focus:before {
animation: ${clipboardFx} 1.25s cubic-bezier(0.215, 0.61, 0.355, 1);
}
`;
export default class CopyPasteContents extends Component {
state = {
content: ''
};
getInnerContents = (ref) => {
if (!ref) {
return;
}
this.setState({content: ref.textContent.trim()});
};
setAnchorRef = (ref) => {
this.anchorRef = ref;
};
handleCopy = () => {
const input = document.createElement('input');
input.setAttribute('value', this.state.content);
document.body.appendChild(input);
input.select();
document.execCommand('copy');
document.body.removeChild(input);
if (this.anchorRef) {
this.anchorRef.focus();
}
};
handlePreventDefault = (e) => {
e.preventDefault();
e.stopPropagation();
};
render() {
return (
<span className={hoverStyle}>
{this.props.text ? (
<Fragment>
<span ref={this.getInnerContents}>
{this.props.text}
</span>
{this.props.children}
</Fragment>
) : (
<span ref={this.getInnerContents}>
{this.props.children}
</span>
)}
{this.state.content.length > 0 ? (
<a
onMouseDown={this.handlePreventDefault}
ref={this.setAnchorRef}
tabIndex="0"
onClick={this.handleCopy}
className={classnames('clipboard-btn', clipboardBtn)}
>
<Icon icon="clipboard" size={10} />
</a>
) : ''}
</span>
);
}
}
CopyPasteContents.propTypes = {
children: PropTypes.node,
text: PropTypes.node
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment