aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--package.json2
-rw-r--r--ui/app/app.js2
-rw-r--r--ui/app/components/account-dropdowns.js1
-rw-r--r--ui/app/components/dropdown.js6
-rw-r--r--ui/app/components/menu-droppo.js137
5 files changed, 145 insertions, 3 deletions
diff --git a/package.json b/package.json
index 98066a172..60987559e 100644
--- a/package.json
+++ b/package.json
@@ -91,7 +91,6 @@
"inject-css": "^0.1.1",
"jazzicon": "^1.2.0",
"loglevel": "^1.4.1",
- "menu-droppo": "2.0.1",
"metamask-logo": "^2.1.2",
"mississippi": "^1.2.0",
"mkdirp": "^0.5.1",
@@ -109,6 +108,7 @@
"pumpify": "^1.3.4",
"qrcode-npm": "0.0.3",
"react": "^15.0.2",
+ "react-addons-css-transition-group": "^15.6.0",
"react-dom": "^15.5.4",
"react-hyperscript": "^2.2.2",
"react-markdown": "^2.3.0",
diff --git a/ui/app/app.js b/ui/app/app.js
index 0592496fc..620b4617a 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -218,6 +218,7 @@ App.prototype.renderNetworkDropdown = function () {
const isOpen = state.isNetworkMenuOpen
return h(Dropdown, {
+ useCssTransition: true,
isOpen,
onClickOutside: (event) => {
const { classList } = event.target
@@ -355,6 +356,7 @@ App.prototype.renderDropdown = function () {
const isOpen = state.isMainMenuOpen
return h(Dropdown, {
+ useCssTransition: true,
isOpen: isOpen,
zIndex: 11,
onClickOutside: (event) => {
diff --git a/ui/app/components/account-dropdowns.js b/ui/app/components/account-dropdowns.js
index da92619e1..b23600e9b 100644
--- a/ui/app/components/account-dropdowns.js
+++ b/ui/app/components/account-dropdowns.js
@@ -65,6 +65,7 @@ class AccountDropdowns extends Component {
return h(
Dropdown,
{
+ useCssTransition: true, // Hardcoded because account selector is temporarily in app-header
style: {
marginLeft: '-238px',
marginTop: '38px',
diff --git a/ui/app/components/dropdown.js b/ui/app/components/dropdown.js
index 8cdfc13e8..34c7149ee 100644
--- a/ui/app/components/dropdown.js
+++ b/ui/app/components/dropdown.js
@@ -1,14 +1,14 @@
const Component = require('react').Component
const PropTypes = require('react').PropTypes
const h = require('react-hyperscript')
-const MenuDroppo = require('menu-droppo')
+const MenuDroppo = require('./menu-droppo')
const extend = require('xtend')
const noop = () => {}
class Dropdown extends Component {
render () {
- const { isOpen, onClickOutside, style, innerStyle, children } = this.props
+ const { isOpen, onClickOutside, style, innerStyle, children, useCssTransition } = this.props
const innerStyleDefaults = extend({
borderRadius: '4px',
@@ -20,6 +20,7 @@ class Dropdown extends Component {
return h(
MenuDroppo,
{
+ useCssTransition,
isOpen,
zIndex: 11,
onClickOutside,
@@ -43,6 +44,7 @@ class Dropdown extends Component {
Dropdown.defaultProps = {
isOpen: false,
onClick: noop,
+ useCssTransition: false,
}
Dropdown.propTypes = {
diff --git a/ui/app/components/menu-droppo.js b/ui/app/components/menu-droppo.js
new file mode 100644
index 000000000..a9370a7c8
--- /dev/null
+++ b/ui/app/components/menu-droppo.js
@@ -0,0 +1,137 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const findDOMNode = require('react-dom').findDOMNode
+const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
+
+module.exports = MenuDroppoComponent
+
+
+inherits(MenuDroppoComponent, Component)
+function MenuDroppoComponent() {
+ Component.call(this)
+}
+
+MenuDroppoComponent.prototype.render = function() {
+
+ const speed = this.props.speed || '300ms'
+ const useCssTransition = this.props.useCssTransition
+ const zIndex = ('zIndex' in this.props) ? this.props.zIndex : 0
+
+ this.manageListeners()
+
+ let style = this.props.style || {}
+ if (!('position' in style)) {
+ style.position = 'fixed'
+ }
+ style.zIndex = zIndex
+
+ return (
+ h('.menu-droppo-container', {
+ style,
+ }, [
+ h('style', `
+ .menu-droppo-enter {
+ transition: transform ${speed} ease-in-out;
+ transform: translateY(-200%);
+ }
+
+ .menu-droppo-enter.menu-droppo-enter-active {
+ transition: transform ${speed} ease-in-out;
+ transform: translateY(0%);
+ }
+
+ .menu-droppo-leave {
+ transition: transform ${speed} ease-in-out;
+ transform: translateY(0%);
+ }
+
+ .menu-droppo-leave.menu-droppo-leave-active {
+ transition: transform ${speed} ease-in-out;
+ transform: translateY(-200%);
+ }
+ `),
+
+ !!useCssTransition
+ ? h(ReactCSSTransitionGroup, {
+ className: 'css-transition-group',
+ transitionName: 'menu-droppo',
+ transitionEnterTimeout: parseInt(speed),
+ transitionLeaveTimeout: parseInt(speed),
+ }, this.renderPrimary())
+ : this.renderPrimary()
+ ])
+ )
+}
+
+MenuDroppoComponent.prototype.renderPrimary = function() {
+ const isOpen = this.props.isOpen
+ if (!isOpen) {
+ return null
+ return h('span', {
+ key: 'menu-droppo-null',
+ style: {
+ height: '0px',
+ }
+ })
+ }
+
+ let innerStyle = this.props.innerStyle || {}
+
+ return (
+ h('.menu-droppo', {
+ key: 'menu-droppo-drawer',
+ style: innerStyle,
+ },
+ [ this.props.children ])
+ )
+}
+
+MenuDroppoComponent.prototype.manageListeners = function() {
+ const isOpen = this.props.isOpen
+ const onClickOutside = this.props.onClickOutside
+
+ if (isOpen) {
+ this.outsideClickHandler = onClickOutside
+ } else if (isOpen) {
+ this.outsideClickHandler = null
+ }
+}
+
+MenuDroppoComponent.prototype.componentDidMount = function() {
+ if (this && document.body) {
+ this.globalClickHandler = this.globalClickOccurred.bind(this);
+ document.body.addEventListener('click', this.globalClickHandler)
+ var container = findDOMNode(this)
+ this.container = container
+ }
+}
+
+MenuDroppoComponent.prototype.componentWillUnmount = function() {
+ if (this && document.body) {
+ document.body.removeEventListener('click', this.globalClickHandler)
+ }
+}
+
+MenuDroppoComponent.prototype.globalClickOccurred = function(event) {
+ const target = event.target
+ const container = findDOMNode(this)
+ const isOpen = this.props.isOpen
+
+ if (target !== container &&
+ !isDescendant(this.container, event.target) &&
+ this.outsideClickHandler) {
+ this.outsideClickHandler(event)
+ }
+}
+
+function isDescendant(parent, child) {
+ var node = child.parentNode;
+ while (node != null) {
+ if (node == parent) {
+ return true;
+ }
+ node = node.parentNode;
+ }
+ return false;
+}