[Ivan Diaz] - Add menu component and implement it in dropdown
This commit is contained in:
parent
07a7915bad
commit
6033e4afba
|
@ -4,6 +4,7 @@ const _ = require('lodash');
|
||||||
const {Motion, spring} = require('react-motion');
|
const {Motion, spring} = require('react-motion');
|
||||||
const callback = require('lib-core/callback');
|
const callback = require('lib-core/callback');
|
||||||
|
|
||||||
|
const Menu = require('core-components/menu');
|
||||||
const Icon = require('core-components/icon');
|
const Icon = require('core-components/icon');
|
||||||
|
|
||||||
const DropDown = React.createClass({
|
const DropDown = React.createClass({
|
||||||
|
@ -11,11 +12,7 @@ const DropDown = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
defaultSelectedIndex: React.PropTypes.number,
|
defaultSelectedIndex: React.PropTypes.number,
|
||||||
selectedIndex: React.PropTypes.number,
|
selectedIndex: React.PropTypes.number,
|
||||||
|
items: Menu.propTypes.items
|
||||||
items: React.PropTypes.arrayOf(React.PropTypes.shape({
|
|
||||||
content: React.PropTypes.string.isRequired,
|
|
||||||
icon: React.PropTypes.string
|
|
||||||
})).isRequired
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps() {
|
getDefaultProps() {
|
||||||
|
@ -53,9 +50,7 @@ const DropDown = React.createClass({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={this.getClass()}>
|
<div className={this.getClass()}>
|
||||||
<div className="drop-down--current" onBlur={this.handleBlur} onClick={this.handleClick} tabIndex="0" ref="current">
|
{this.renderCurrentItem(selectedItem)}
|
||||||
{this.renderItem(selectedItem)}
|
|
||||||
</div>
|
|
||||||
<Motion defaultStyle={animation.defaultStyle} style={animation.style}>
|
<Motion defaultStyle={animation.defaultStyle} style={animation.style}>
|
||||||
{this.renderList}
|
{this.renderList}
|
||||||
</Motion>
|
</Motion>
|
||||||
|
@ -65,35 +60,30 @@ const DropDown = React.createClass({
|
||||||
|
|
||||||
renderList({opacity, translateY}) {
|
renderList({opacity, translateY}) {
|
||||||
let style = { opacity: opacity, transform: `translateY(${translateY}px)`};
|
let style = { opacity: opacity, transform: `translateY(${translateY}px)`};
|
||||||
|
let menuProps = {
|
||||||
|
items: this.props.items,
|
||||||
|
onItemClick: this.handleItemClick,
|
||||||
|
onMouseDown: this.handleListMouseDown
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="drop-down--list-container" style={style}>
|
<div className="drop-down--list-container" style={style}>
|
||||||
<ul className="drop-down--list">
|
<Menu {...menuProps} />
|
||||||
{this.props.items.map(this.renderListItem)}
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
renderListItem(item, index) {
|
renderCurrentItem(item) {
|
||||||
return (
|
var iconNode = null;
|
||||||
<li {...this.getItemProps(index)}>
|
|
||||||
{this.renderItem(item)}
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
renderItem(item) {
|
if (item.icon) {
|
||||||
return (
|
iconNode = <Icon className="drop-down--current-item-icon" name={item.icon} />;
|
||||||
<span>
|
}
|
||||||
{(item.icon) ? this.renderIcon(item.icon) : null}{item.content}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
renderIcon(icon) {
|
|
||||||
return (
|
return (
|
||||||
<Icon className="drop-down--icon" name={icon} />
|
<div className="drop-down--current-item" onBlur={this.handleBlur} onClick={this.handleClick} tabIndex="0">
|
||||||
|
{iconNode}{item.content}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -108,15 +98,6 @@ const DropDown = React.createClass({
|
||||||
return classNames(classes);
|
return classNames(classes);
|
||||||
},
|
},
|
||||||
|
|
||||||
getItemProps(index) {
|
|
||||||
return {
|
|
||||||
className: 'drop-down--list-item',
|
|
||||||
onClick: this.handleItemClick.bind(this, index),
|
|
||||||
onMouseDown: this.handleItemMouseDown,
|
|
||||||
key: index
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
handleBlur() {
|
handleBlur() {
|
||||||
this.setState({
|
this.setState({
|
||||||
opened: false
|
opened: false
|
||||||
|
@ -142,7 +123,7 @@ const DropDown = React.createClass({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
handleItemMouseDown(event) {
|
handleListMouseDown(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -7,41 +7,24 @@
|
||||||
user-select: none;
|
user-select: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&--current {
|
&--current-item {
|
||||||
background-color: $light-grey;
|
background-color: $light-grey;
|
||||||
border-radius: 4px 4px 0 0;
|
border-radius: 4px 4px 0 0;
|
||||||
color: $primary-black;
|
color: $primary-black;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&--current-item-icon {
|
||||||
|
margin-right: 8px;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
&--list-container {
|
&--list-container {
|
||||||
background-color: white;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 150px;
|
width: 150px;
|
||||||
z-index: 5;
|
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 {
|
&_closed {
|
||||||
|
|
||||||
.drop-down--list-container {
|
.drop-down--list-container {
|
||||||
|
|
|
@ -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 (
|
||||||
|
<ul {...this.getProps()}>
|
||||||
|
{this.props.items.map(this.renderListItem)}
|
||||||
|
</ul>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
renderListItem(item, index) {
|
||||||
|
return (
|
||||||
|
<li {...this.getItemProps(index)}>
|
||||||
|
{this.renderItem(item)}
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
renderItem(item) {
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
{(item.icon) ? this.renderIcon(item.icon) : null}{item.content}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
renderIcon(icon) {
|
||||||
|
return (
|
||||||
|
<Icon className="menu--icon" name={icon} />
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
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;
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue