12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- import {cloneElement, Component, isValidElement} from 'react';
- import ReactDOM from 'react-dom';
- import copy from 'copy-text-to-clipboard';
- import {addErrorMessage, addSuccessMessage} from 'app/actionCreators/indicator';
- import {t} from 'app/locale';
- type DefaultProps = {
- successMessage: string;
- errorMessage: string;
- hideMessages: boolean;
- };
- type Props = {
- /** Text to be copied on click */
- value: string;
- /** Hide children if browser does not support copy */
- hideUnsupported?: boolean;
- onSuccess?: () => void;
- onError?: () => void;
- } & DefaultProps;
- /**
- * copy-text-to-clipboard relies on `document.execCommand('copy')`
- */
- function isSupported() {
- const support = !!document.queryCommandSupported;
- return support && !!document.queryCommandSupported('copy');
- }
- class Clipboard extends Component<Props> {
- static defaultProps: DefaultProps = {
- hideMessages: false,
- successMessage: t('Copied to clipboard'),
- errorMessage: t('Error copying to clipboard'),
- };
- componentWillUnmount() {
- this.element?.removeEventListener('click', this.handleClick);
- }
- element?: ReturnType<typeof ReactDOM.findDOMNode>;
- handleClick = () => {
- const {value, hideMessages, successMessage, errorMessage, onSuccess, onError} =
- this.props;
- // Copy returns whether it succeeded to copy the text
- const success = copy(value);
- if (!success) {
- if (!hideMessages) {
- addErrorMessage(errorMessage);
- }
- onError?.();
- return;
- }
- if (!hideMessages) {
- addSuccessMessage(successMessage);
- }
- onSuccess?.();
- };
- handleMount = (ref: HTMLElement) => {
- if (!ref) {
- return;
- }
- // eslint-disable-next-line react/no-find-dom-node
- this.element = ReactDOM.findDOMNode(ref);
- this.element?.addEventListener('click', this.handleClick);
- };
- render() {
- const {children, hideUnsupported} = this.props;
- // Browser doesn't support `execCommand`
- if (hideUnsupported && !isSupported()) {
- return null;
- }
- if (!isValidElement(children)) {
- return null;
- }
- return cloneElement(children, {
- ref: this.handleMount,
- });
- }
- }
- export default Clipboard;
|