diff --git a/client/src/core-components/drop-down.js b/client/src/core-components/drop-down.js index ba2dd31a..c608b498 100644 --- a/client/src/core-components/drop-down.js +++ b/client/src/core-components/drop-down.js @@ -4,6 +4,7 @@ const _ = require('lodash'); const {Motion, spring} = require('react-motion'); const callback = require('lib-core/callback'); +const Menu = require('core-components/menu'); const Icon = require('core-components/icon'); const DropDown = React.createClass({ @@ -11,11 +12,7 @@ const DropDown = React.createClass({ propTypes: { defaultSelectedIndex: React.PropTypes.number, selectedIndex: React.PropTypes.number, - - items: React.PropTypes.arrayOf(React.PropTypes.shape({ - content: React.PropTypes.string.isRequired, - icon: React.PropTypes.string - })).isRequired + items: Menu.propTypes.items }, getDefaultProps() { @@ -53,9 +50,7 @@ const DropDown = React.createClass({ return (
-
- {this.renderItem(selectedItem)} -
+ {this.renderCurrentItem(selectedItem)} {this.renderList} @@ -65,35 +60,30 @@ const DropDown = React.createClass({ renderList({opacity, translateY}) { let style = { opacity: opacity, transform: `translateY(${translateY}px)`}; + let menuProps = { + items: this.props.items, + onItemClick: this.handleItemClick, + onMouseDown: this.handleListMouseDown + }; return (
- +
); }, - renderListItem(item, index) { - return ( -
  • - {this.renderItem(item)} -
  • - ); - }, + renderCurrentItem(item) { + var iconNode = null; - renderItem(item) { - return ( - - {(item.icon) ? this.renderIcon(item.icon) : null}{item.content} - - ); - }, + if (item.icon) { + iconNode = ; + } - renderIcon(icon) { return ( - +
    + {iconNode}{item.content} +
    ); }, @@ -108,15 +98,6 @@ const DropDown = React.createClass({ return classNames(classes); }, - getItemProps(index) { - return { - className: 'drop-down--list-item', - onClick: this.handleItemClick.bind(this, index), - onMouseDown: this.handleItemMouseDown, - key: index - }; - }, - handleBlur() { this.setState({ opened: false @@ -142,7 +123,7 @@ const DropDown = React.createClass({ } }, - handleItemMouseDown(event) { + handleListMouseDown(event) { event.preventDefault(); }, diff --git a/client/src/core-components/drop-down.scss b/client/src/core-components/drop-down.scss index f7b5d3ac..74eb1270 100644 --- a/client/src/core-components/drop-down.scss +++ b/client/src/core-components/drop-down.scss @@ -7,41 +7,24 @@ user-select: none; cursor: pointer; - &--current { + &--current-item { background-color: $light-grey; border-radius: 4px 4px 0 0; color: $primary-black; padding: 6px; } + &--current-item-icon { + margin-right: 8px; + margin-bottom: 2px; + } + &--list-container { - background-color: white; position: absolute; width: 150px; z-index: 5; } - &--list { - color: $dark-grey; - margin: 0; - padding: 0; - list-style-type: none; - - &-item { - padding: 8px; - - &:hover { - background-color: $primary-red; - color: white; - } - } - } - - &--icon { - margin-right: 8px; - margin-bottom: 2px; - } - &_closed { .drop-down--list-container { diff --git a/client/src/core-components/menu.js b/client/src/core-components/menu.js index e69de29b..3b144174 100644 --- a/client/src/core-components/menu.js +++ b/client/src/core-components/menu.js @@ -0,0 +1,97 @@ +const React = require('react'); +const _ = require('lodash'); +const classNames = require('classnames'); + +const Icon = require('core-components/icon'); + +const Menu = React.createClass({ + + propTypes: { + type: React.PropTypes.oneOf(['primary', 'secondary']), + items: React.PropTypes.arrayOf(React.PropTypes.shape({ + content: React.PropTypes.string.isRequired, + icon: React.PropTypes.string + })).isRequired, + selectedIndex: React.PropTypes.number + }, + + getDefaultProps() { + return { + type: 'primary', + selectedIndex: 0 + }; + }, + + render() { + return ( +
      + {this.props.items.map(this.renderListItem)} +
    + ) + }, + + renderListItem(item, index) { + return ( +
  • + {this.renderItem(item)} +
  • + ); + }, + + renderItem(item) { + return ( + + {(item.icon) ? this.renderIcon(item.icon) : null}{item.content} + + ); + }, + + renderIcon(icon) { + return ( + + ); + }, + + getProps() { + var props = _.clone(this.props); + + props.className = this.getClass(); + props.type = null; + + return props; + }, + + getClass() { + let classes = { + 'menu': true, + 'menu_secondary': (this.props.type === 'secondary') + }; + + return classNames(classes); + }, + + getItemProps(index) { + return { + className: this.getItemClass(index), + onClick: this.handleItemClick.bind(this, index), + key: index + }; + }, + + getItemClass(index) { + let classes = { + 'menu--list-item': true, + 'menu--list-item_selected': (this.props.selectedIndex === index) + }; + + return classNames(classes); + }, + + handleItemClick(index) { + if (this.props.onItemClick) { + this.props.onItemClick(index); + } + } +}); + +export default Menu; \ No newline at end of file diff --git a/client/src/core-components/menu.scss b/client/src/core-components/menu.scss new file mode 100644 index 00000000..6e9f10aa --- /dev/null +++ b/client/src/core-components/menu.scss @@ -0,0 +1,23 @@ +@import "../scss/vars"; + +.menu { + background-color: white; + color: $dark-grey; + margin: 0; + padding: 0; + list-style-type: none; + + &--list-item { + padding: 8px; + + &:hover { + background-color: $primary-red; + color: white; + } + } + + &--icon { + margin-right: 8px; + margin-bottom: 2px; + } +} \ No newline at end of file