aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website/ts/components/ui/drop_down.tsx
diff options
context:
space:
mode:
authorBrandon Millman <brandon.millman@gmail.com>2018-02-01 07:30:09 +0800
committerBrandon Millman <brandon.millman@gmail.com>2018-02-01 07:30:09 +0800
commit03cb7233dc5b8556952b4481f87a292e0fca1acf (patch)
tree4c203211a7ce7b0f44ebc45bb6c40621d4ee5b7e /packages/website/ts/components/ui/drop_down.tsx
parent3a1ca32ff172f735e4b69f125fea4237c83643f0 (diff)
parent6682abf89dcdf566f05f8d88cb6af06c4bb1f6a2 (diff)
downloaddexon-sol-tools-03cb7233dc5b8556952b4481f87a292e0fca1acf.tar
dexon-sol-tools-03cb7233dc5b8556952b4481f87a292e0fca1acf.tar.gz
dexon-sol-tools-03cb7233dc5b8556952b4481f87a292e0fca1acf.tar.bz2
dexon-sol-tools-03cb7233dc5b8556952b4481f87a292e0fca1acf.tar.lz
dexon-sol-tools-03cb7233dc5b8556952b4481f87a292e0fca1acf.tar.xz
dexon-sol-tools-03cb7233dc5b8556952b4481f87a292e0fca1acf.tar.zst
dexon-sol-tools-03cb7233dc5b8556952b4481f87a292e0fca1acf.zip
Merge branch 'development' into feature/testnet-faucets/order-dispenser
* development: (49 commits) Prettier Updated contract generation in 0x to new abi-gen CLI Add PR number to changelog Fix lint errors Removed deprecated CLI options Add protected keyword to underscore lint rule Remove unused prop Fix prettier Uppercase Networks enum values Make default gasPrice more readable Fix prettier mess Fix linter errors Shrink img Fix all setState calls after unmounted errors. Decided to create our own flag rather then using a cancellablePromise since there was little to be gained from this alternative Fix bug where we were return undefined instead of the empty object Default the derivation path to that found in the Ledger subprovider Add browser data to dialog info Add Rinkeby support Pass in whether we want the personal message prefix appended and never append it for Ledger. This fixes signing when Ledger is used and the backing node is not Parity Wholesale replace the tokenByAddress and de-dup properly ...
Diffstat (limited to 'packages/website/ts/components/ui/drop_down.tsx')
-rw-r--r--packages/website/ts/components/ui/drop_down.tsx108
1 files changed, 108 insertions, 0 deletions
diff --git a/packages/website/ts/components/ui/drop_down.tsx b/packages/website/ts/components/ui/drop_down.tsx
new file mode 100644
index 000000000..63b9eec0b
--- /dev/null
+++ b/packages/website/ts/components/ui/drop_down.tsx
@@ -0,0 +1,108 @@
+import * as _ from 'lodash';
+import Popover, { PopoverAnimationVertical } from 'material-ui/Popover';
+import * as React from 'react';
+import { MaterialUIPosition } from 'ts/types';
+
+const CHECK_CLOSE_POPOVER_INTERVAL_MS = 300;
+const DEFAULT_STYLE = {
+ fontSize: 14,
+};
+
+interface DropDownProps {
+ hoverActiveNode: React.ReactNode;
+ popoverContent: React.ReactNode;
+ anchorOrigin: MaterialUIPosition;
+ targetOrigin: MaterialUIPosition;
+ style?: React.CSSProperties;
+ zDepth?: number;
+}
+
+interface DropDownState {
+ isDropDownOpen: boolean;
+ anchorEl?: HTMLInputElement;
+}
+
+export class DropDown extends React.Component<DropDownProps, DropDownState> {
+ public static defaultProps: Partial<DropDownProps> = {
+ style: DEFAULT_STYLE,
+ zDepth: 1,
+ };
+ private _isHovering: boolean;
+ private _popoverCloseCheckIntervalId: number;
+ constructor(props: DropDownProps) {
+ super(props);
+ this.state = {
+ isDropDownOpen: false,
+ };
+ }
+ public componentDidMount() {
+ this._popoverCloseCheckIntervalId = window.setInterval(() => {
+ this._checkIfShouldClosePopover();
+ }, CHECK_CLOSE_POPOVER_INTERVAL_MS);
+ }
+ public componentWillUnmount() {
+ window.clearInterval(this._popoverCloseCheckIntervalId);
+ }
+ public componentWillReceiveProps(nextProps: DropDownProps) {
+ // HACK: If the popoverContent is updated to a different dimension and the users
+ // mouse is no longer above it, the dropdown can enter an inconsistent state where
+ // it believes the user is still hovering over it. In order to remedy this, we
+ // call hoverOff whenever the dropdown receives updated props. This is a hack
+ // because it will effectively close the dropdown on any prop update, barring
+ // dropdowns from having dynamic content.
+ this._onHoverOff();
+ }
+ public render() {
+ return (
+ <div
+ style={{ ...this.props.style, width: 'fit-content', height: '100%' }}
+ onMouseEnter={this._onHover.bind(this)}
+ onMouseLeave={this._onHoverOff.bind(this)}
+ >
+ {this.props.hoverActiveNode}
+ <Popover
+ open={this.state.isDropDownOpen}
+ anchorEl={this.state.anchorEl}
+ anchorOrigin={this.props.anchorOrigin}
+ targetOrigin={this.props.targetOrigin}
+ onRequestClose={this._closePopover.bind(this)}
+ useLayerForClickAway={false}
+ animation={PopoverAnimationVertical}
+ zDepth={this.props.zDepth}
+ >
+ <div onMouseEnter={this._onHover.bind(this)} onMouseLeave={this._onHoverOff.bind(this)}>
+ {this.props.popoverContent}
+ </div>
+ </Popover>
+ </div>
+ );
+ }
+ private _onHover(event: React.FormEvent<HTMLInputElement>) {
+ this._isHovering = true;
+ this._checkIfShouldOpenPopover(event);
+ }
+ private _checkIfShouldOpenPopover(event: React.FormEvent<HTMLInputElement>) {
+ if (this.state.isDropDownOpen) {
+ return; // noop
+ }
+
+ this.setState({
+ isDropDownOpen: true,
+ anchorEl: event.currentTarget,
+ });
+ }
+ private _onHoverOff() {
+ this._isHovering = false;
+ }
+ private _checkIfShouldClosePopover() {
+ if (!this.state.isDropDownOpen || this._isHovering) {
+ return; // noop
+ }
+ this._closePopover();
+ }
+ private _closePopover() {
+ this.setState({
+ isDropDownOpen: false,
+ });
+ }
+}