import "./clipboard.scss"; import React from "react"; import { findDOMNode } from "react-dom"; import { autobind } from "../../../common/utils"; import { Notifications } from "../notifications"; import { copyToClipboard } from "../../utils/copyToClipboard"; import logger from "../../../main/logger"; import { cssNames } from "../../utils"; export interface CopyToClipboardProps { resetSelection?: boolean; showNotification?: boolean; cssSelectorLimit?: string; // allows to copy partial content with css-selector in children-element context getNotificationMessage?(copiedText: string): React.ReactNode; } export const defaultProps: Partial = { getNotificationMessage(copiedText: string) { return

Copied to clipboard: {copiedText}

; } }; export class Clipboard extends React.Component { static displayName = "Clipboard"; static defaultProps = defaultProps as object; get rootElem(): HTMLElement { // eslint-disable-next-line react/no-find-dom-node return findDOMNode(this) as HTMLElement; } get rootReactElem(): React.ReactElement> { return React.Children.only(this.props.children) as React.ReactElement; } @autobind() onClick(evt: React.MouseEvent) { if (this.rootReactElem.props.onClick) { this.rootReactElem.props.onClick(evt); // pass event to children-root-element if any } const { showNotification, resetSelection, getNotificationMessage, cssSelectorLimit } = this.props; const contentElem = this.rootElem.querySelector(cssSelectorLimit) || this.rootElem; if (contentElem) { const { copiedText, copied } = copyToClipboard(contentElem, { resetSelection }); if (copied && showNotification) { Notifications.ok(getNotificationMessage(copiedText)); } } } render() { try { const rootElem = this.rootReactElem; return React.cloneElement(rootElem, { className: cssNames(Clipboard.displayName, rootElem.props.className), onClick: this.onClick, }); } catch (err) { logger.error(`Invalid usage components/CopyToClick usage. Children must contain root html element.`, { err: String(err) }); return this.rootReactElem; } } }