2018-02-07 18:06:07 +00:00
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import React from 'react';
|
2017-10-30 18:38:41 +00:00
|
|
|
import Clipboard from 'clipboard';
|
2019-01-16 17:35:34 +00:00
|
|
|
import classNames from 'classnames';
|
2020-08-26 15:28:53 +00:00
|
|
|
import { withTranslation } from 'react-i18next';
|
2019-01-16 17:35:34 +00:00
|
|
|
|
2020-04-29 22:34:37 +00:00
|
|
|
import ShareIcon from '../../../images/share.svg';
|
2017-10-30 18:38:41 +00:00
|
|
|
|
|
|
|
class CopyableInput extends React.Component {
|
2017-10-30 21:24:43 +00:00
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this.onMouseLeaveHandler = this.onMouseLeaveHandler.bind(this);
|
|
|
|
}
|
|
|
|
|
2017-10-30 18:38:41 +00:00
|
|
|
componentDidMount() {
|
|
|
|
this.clipboard = new Clipboard(this.input, {
|
|
|
|
target: () => this.input
|
|
|
|
});
|
2017-10-30 21:24:43 +00:00
|
|
|
|
|
|
|
this.clipboard.on('success', (e) => {
|
|
|
|
this.tooltip.classList.add('tooltipped');
|
|
|
|
this.tooltip.classList.add('tooltipped-n');
|
|
|
|
});
|
2017-10-30 18:38:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
componentWillUnmount() {
|
|
|
|
this.clipboard.destroy();
|
|
|
|
}
|
|
|
|
|
2017-10-30 21:24:43 +00:00
|
|
|
onMouseLeaveHandler() {
|
|
|
|
this.tooltip.classList.remove('tooltipped');
|
|
|
|
this.tooltip.classList.remove('tooltipped-n');
|
|
|
|
}
|
|
|
|
|
2017-10-30 18:38:41 +00:00
|
|
|
render() {
|
|
|
|
const {
|
|
|
|
label,
|
2018-10-18 18:10:37 +00:00
|
|
|
value,
|
|
|
|
hasPreviewLink
|
2017-10-30 18:38:41 +00:00
|
|
|
} = this.props;
|
2019-01-16 17:35:34 +00:00
|
|
|
const copyableInputClass = classNames({
|
|
|
|
'copyable-input': true,
|
|
|
|
'copyable-input--with-preview': hasPreviewLink
|
|
|
|
});
|
2017-10-30 18:38:41 +00:00
|
|
|
return (
|
2019-01-16 17:35:34 +00:00
|
|
|
<div className={copyableInputClass}>
|
2017-10-30 21:24:43 +00:00
|
|
|
<div
|
2017-10-30 21:38:30 +00:00
|
|
|
className="copyable-input__value-container tooltipped-no-delay"
|
2020-08-26 15:28:53 +00:00
|
|
|
aria-label={this.props.t('CopyableInput.CopiedARIA')}
|
2017-10-30 21:24:43 +00:00
|
|
|
ref={(element) => { this.tooltip = element; }}
|
|
|
|
onMouseLeave={this.onMouseLeaveHandler}
|
|
|
|
>
|
2018-05-09 01:35:18 +00:00
|
|
|
<label className="copyable-input__label" htmlFor={`copyable-input__value-${label}`}>
|
2018-10-18 18:10:37 +00:00
|
|
|
<div className="copyable-input__label-container">
|
2019-01-16 17:35:34 +00:00
|
|
|
{label}
|
2018-10-18 18:10:37 +00:00
|
|
|
</div>
|
2018-05-09 00:57:16 +00:00
|
|
|
<input
|
|
|
|
type="text"
|
|
|
|
className="copyable-input__value"
|
2018-05-09 01:35:18 +00:00
|
|
|
id={`copyable-input__value-${label}`}
|
2018-05-09 00:57:16 +00:00
|
|
|
value={value}
|
|
|
|
ref={(element) => { this.input = element; }}
|
|
|
|
readOnly
|
|
|
|
/>
|
|
|
|
</label>
|
2017-10-30 18:38:41 +00:00
|
|
|
</div>
|
2019-01-16 17:35:34 +00:00
|
|
|
{hasPreviewLink &&
|
|
|
|
<a
|
|
|
|
target="_blank"
|
2019-01-16 22:56:18 +00:00
|
|
|
rel="noopener noreferrer"
|
2019-01-16 17:35:34 +00:00
|
|
|
href={value}
|
|
|
|
className="copyable-input__preview"
|
2020-08-26 15:28:53 +00:00
|
|
|
aria-label={this.props.t('CopyableInput.CopiedARIA', { label })}
|
2019-01-16 17:35:34 +00:00
|
|
|
>
|
2020-05-05 23:03:58 +00:00
|
|
|
<ShareIcon focusable="false" aria-hidden="true" />
|
2019-01-16 17:35:34 +00:00
|
|
|
</a>
|
|
|
|
}
|
2017-10-30 18:38:41 +00:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CopyableInput.propTypes = {
|
|
|
|
label: PropTypes.string.isRequired,
|
2018-10-18 18:10:37 +00:00
|
|
|
value: PropTypes.string.isRequired,
|
2020-08-26 15:28:53 +00:00
|
|
|
hasPreviewLink: PropTypes.bool,
|
|
|
|
t: PropTypes.func.isRequired
|
2018-10-18 18:10:37 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
CopyableInput.defaultProps = {
|
|
|
|
hasPreviewLink: false
|
2017-10-30 18:38:41 +00:00
|
|
|
};
|
|
|
|
|
2020-08-26 15:28:53 +00:00
|
|
|
export default withTranslation()(CopyableInput);
|