Click to copy address or block hash (#82)

This commit is contained in:
Maciej Hirsz
2018-10-10 15:01:28 +02:00
committed by GitHub
parent 0f4049f665
commit 491b70fae9
4 changed files with 63 additions and 10 deletions
@@ -92,10 +92,10 @@ export default class Row extends React.Component<RowProps, RowState> {
{
label: 'Validator',
icon: nodeValidatorIcon,
width: 26,
width: 16,
setting: 'validator',
render: ({ validator }) => {
return validator ? <Tooltip text={validator}><span className="Node-Row-validator"><Identicon id={validator} size={16} /></span></Tooltip> : '-';
return validator ? <Tooltip text={validator} copy={true}><span className="Node-Row-validator"><Identicon id={validator} size={16} /></span></Tooltip> : '-';
}
},
{
@@ -179,7 +179,7 @@ export default class Row extends React.Component<RowProps, RowState> {
icon: blockHashIcon,
width: 154,
setting: 'blockhash',
render: ({ hash }) => <Truncate position="right" text={hash} />
render: ({ hash }) => <Truncate position="right" text={hash} copy={true} />
},
{
label: 'Block Time',
@@ -3,17 +3,18 @@ import { Tooltip } from '../';
namespace Truncate {
export interface Props {
text: string,
position?: Tooltip.Props['position']
text: string;
copy?: boolean;
position?: Tooltip.Props['position'];
}
}
class Truncate extends React.Component<Truncate.Props, {}> {
public render() {
const { text, position } = this.props;
const { text, position, copy } = this.props;
return (
<Tooltip text={text} position={position} className="Node-Row-Tooltip">
<Tooltip text={text} position={position} copy={copy} className="Node-Row-Tooltip">
<div className="Node-Row-truncate">{text}</div>
</Tooltip>
);
@@ -13,6 +13,8 @@
transform: translateX(-50%);
display: none;
box-shadow: 0 2px 10px rgba(0,0,0,0.5);
pointer-events: none;
transition: color 0.15s ease-in-out;
}
.Tooltip::after {
@@ -27,6 +29,7 @@
border-top: 6px #000 solid;
border-left: 6px transparent solid;
border-right: 6px transparent solid;
pointer-events: none;
}
.Tooltip-left {
@@ -51,6 +54,10 @@
margin: 0;
}
.Tooltip.Tooltip-copied {
color: #888;
}
.Tooltip-container {
position: relative;
}
+48 -3
View File
@@ -5,17 +5,34 @@ 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;
}
export class Tooltip extends React.Component<Tooltip.Props, {}> {
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<Tooltip.Props, Tooltip.State> {
public state = { copied: false };
private el: HTMLDivElement;
private timer: NodeJS.Timer;
public componentDidMount() {
if (this.props.onInit) {
@@ -23,8 +40,13 @@ export class Tooltip extends React.Component<Tooltip.Props, {}> {
}
}
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';
@@ -41,9 +63,13 @@ export class Tooltip extends React.Component<Tooltip.Props, {}> {
tooltipClass += ` Tooltip-${position}`;
}
if (copied) {
tooltipClass += ' Tooltip-copied';
}
return (
<div className={containerClass}>
<div className={tooltipClass} ref={this.onRef}>{text}</div>
<div className={containerClass} onClick={this.onClick}>
<div className={tooltipClass} ref={this.onRef}>{copied ? 'Copied to clipboard!' : text}</div>
{this.props.children}
</div>
);
@@ -56,4 +82,23 @@ export class Tooltip extends React.Component<Tooltip.Props, {}> {
private update = (text: string) => {
this.el.textContent = text;
}
private onClick = (event: React.MouseEvent<HTMLDivElement>) => {
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 });
}
}