diff options
author | Brandon Millman <brandon.millman@gmail.com> | 2018-02-01 07:30:09 +0800 |
---|---|---|
committer | Brandon Millman <brandon.millman@gmail.com> | 2018-02-01 07:30:09 +0800 |
commit | 03cb7233dc5b8556952b4481f87a292e0fca1acf (patch) | |
tree | 4c203211a7ce7b0f44ebc45bb6c40621d4ee5b7e /packages/website/ts/components/ui/drop_down.tsx | |
parent | 3a1ca32ff172f735e4b69f125fea4237c83643f0 (diff) | |
parent | 6682abf89dcdf566f05f8d88cb6af06c4bb1f6a2 (diff) | |
download | dexon-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.tsx | 108 |
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, + }); + } +} |