MyCrypto/common/components/ui/DropdownShell.tsx
skubakdj c9c147db52 Wallet Decrypt - Web3 (MetaMask / Mist) (#303)
* add support for web3, disabled, and hidden in node dropdown header

* add web3 node config actions

* add web3 wallet actions

* add web3 node support

* add web3 wallet & web3 wallet ui selection

* add web3 wallet & config sagas

* add web3 transaction support to SendTransaction tab

* add web3 node check & reset to redux store

* remove comments from Web3.tsx

* update comment

* correct spacing display issue in Web3 component

* convert getTransactionCount response to string

* disable web3 wallets in offline mode

* implement sendCallRequest method on Web3 node

* remove unused vars

* make typescript happy

* convert wallet constants to enum & apply to wallet action files

* update wallet reducer to use TypeKeys enum

* remove unnecessary console log

* remove unnecessary await

* make token balance math more readable

* use NewTabLink in Web3.tsx, allow NewTabLink to accept className

* move web3.ts to non-deterministic folder

* update imports & method names, implement message signing

* add web3 wallet export

* use bufferToHex
2017-11-09 19:30:20 -08:00

103 lines
2.2 KiB
TypeScript

import React, { Component } from 'react';
import classnames from 'classnames';
interface Props {
ariaLabel: string;
disabled?: boolean;
size?: string;
color?: string;
renderLabel(): any;
renderOptions(): any;
}
interface State {
expanded: boolean;
}
export default class DropdownComponent extends Component<Props, State> {
public static defaultProps = {
color: 'default',
size: 'sm'
};
public state: State = {
expanded: false
};
private dropdown: HTMLElement | null;
public componentDidMount() {
document.addEventListener('click', this.clickOffHandler);
}
public componentWillUnmount() {
document.removeEventListener('click', this.clickOffHandler);
}
public render() {
const {
ariaLabel,
color,
disabled,
size,
renderOptions,
renderLabel
} = this.props;
const { expanded } = this.state;
const toggleClasses = classnames([
'dropdown-toggle',
'btn',
`btn-${color}`,
`btn-${size}`
]);
return (
<span
className={`dropdown ${expanded || disabled ? 'open' : ''}`}
ref={el => (this.dropdown = el)}
>
<a
tabIndex={0}
aria-haspopup="true"
aria-expanded={expanded}
aria-label={ariaLabel}
className={toggleClasses}
onClick={this.toggle}
>
{renderLabel()}
{!disabled && <i className="caret" />}
</a>
{expanded && !disabled && renderOptions()}
</span>
);
}
public toggle = () => {
this.setState({ expanded: !this.state.expanded });
};
public open = () => {
this.setState({ expanded: true });
};
public close = () => {
this.setState({ expanded: false });
};
private clickOffHandler = (ev: MouseEvent) => {
// Only calculate if dropdown is open & we have the ref
if (!this.state.expanded || !this.dropdown) {
return;
}
// If it's an element that's not inside of the dropdown, close it up
if (
this.dropdown !== ev.target &&
ev.target instanceof HTMLElement &&
!this.dropdown.contains(ev.target)
) {
this.setState({ expanded: false });
}
};
}