All files / packages/design-system/shared/components Copy.jsx

50% Statements 13/26
63.63% Branches 7/11
25% Functions 1/4
48% Lines 12/25

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107              1x 3x           3x 3x           3x           3x                                                                   3x 3x 3x                                                   6x 3x             6x                  
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license
 
import React from 'react';
import classnames from 'classnames';
import SvgIcon from '../../ui/shared/svg-icon/';
 
const isCopySupported = () =>
  document &&
  document.queryCommandSupported &&
  document.queryCommandSupported('copy');
 
class Copy extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      show: false
    };
  }
 
  componentDidMount() {
    this.setState({
      show: isCopySupported()
    });
  }
 
  componentWillUnmount() {
    window.clearTimeout(this.copyTimer);
  }
 
  copyToClipboard() {
    const range = document.createRange();
    const selection = window.getSelection();
    this.copyNode.innerText =
      typeof this.props.text === 'function'
        ? this.props.text()
        : this.props.text;
    range.selectNode(this.copyNode);
    selection.removeAllRanges();
    selection.addRange(range);
    document.execCommand('copy');
    if (selection.removeRange) {
      selection.removeRange(range);
    } else {
      selection.removeAllRanges();
    }
    this.setState(
      {
        copied: true
      },
      () => {
        this.copyTimer = window.setTimeout(() => {
          this.setState({
            copied: false
          });
        }, 1000);
      }
    );
  }
 
  renderButton() {
    const { copied } = this.state;
    const assistiveText = copied ? 'Copied' : '';
    return (
      <React.Fragment>
        <button
          className={classnames(
            'doc-copy-to-clipboard',
            'slds-button',
            this.props.className
          )}
          onClick={() => this.copyToClipboard()}
          aria-label="Copy to Clipboard"
          title="Copy to Clipboard"
        >
          <SvgIcon
            sprite="utility"
            symbol={copied ? 'check' : 'copy_to_clipboard'}
            className="slds-button__icon"
          />
        </button>
        <span aria-live="polite" className="slds-assistive-text">
          {assistiveText}
        </span>
      </React.Fragment>
    );
  }
 
  render() {
    if (!this.state.show) return null;
    return (
      <span className={this.props.containerClassName}>
        {this.renderButton()}
        <pre
          aria-hidden="true"
          className="slds-assistive-text"
          ref={node => {
            this.copyNode = node;
          }}
        />
      </span>
    );
  }
}
 
export default Copy;