diff options
Diffstat (limited to 'ui')
-rw-r--r-- | ui/app/components/dropdown.js | 2 | ||||
-rw-r--r-- | ui/app/components/menu-droppo.js | 137 |
2 files changed, 138 insertions, 1 deletions
diff --git a/ui/app/components/dropdown.js b/ui/app/components/dropdown.js index ef1a274c3..34c7149ee 100644 --- a/ui/app/components/dropdown.js +++ b/ui/app/components/dropdown.js @@ -1,7 +1,7 @@ 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 = () => {} 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; +} |