import * as React from 'react'; import './Tooltip.css'; export namespace Tooltip { export interface Props { text: string; copy?: boolean; inline?: boolean; className?: string; position?: 'left' | 'right' | 'center'; onInit?: (update: UpdateCallback) => void; } export interface State { copied: boolean; } export type UpdateCallback = (text: string) => void; } function copyToClipboard(text: string) { const el = document.createElement('textarea'); el.value = text; document.body.appendChild(el); el.select(); document.execCommand('copy'); document.body.removeChild(el); } export class Tooltip extends React.Component { public state = { copied: false }; private el: HTMLDivElement; private timer: NodeJS.Timer; public componentDidMount() { if (this.props.onInit) { this.props.onInit(this.update); } } public componentWillUnmount() { clearTimeout(this.timer); } public render() { const { text, inline, className, position } = this.props; const { copied } = this.state; let containerClass = 'Tooltip-container'; let tooltipClass = 'Tooltip'; if (className) { containerClass += ' ' + className; } if (inline) { containerClass += ' Tooltip-container-inline'; } if (position && position !== 'center') { tooltipClass += ` Tooltip-${position}`; } if (copied) { tooltipClass += ' Tooltip-copied'; } return (
{copied ? 'Copied to clipboard!' : text}
{this.props.children}
); } private onRef = (el: HTMLDivElement) => { this.el = el; }; private update = (text: string) => { this.el.textContent = text; }; private onClick = (event: React.MouseEvent) => { if (this.props.copy !== true) { return; } copyToClipboard(this.props.text); event.stopPropagation(); clearTimeout(this.timer); this.setState({ copied: true }); this.timer = setTimeout(this.restore, 2000); }; private restore = () => { this.setState({ copied: false }); }; }