Add IconMenu component

old
Javi Velasco 2015-10-17 22:25:15 +02:00
parent 14e2c95554
commit c96e218683
7 changed files with 149 additions and 7 deletions

View File

@ -0,0 +1,70 @@
import React from 'react';
import FontIcon from '../font_icon';
import Menu from './menu';
import Ripple from '../ripple';
import style from './style.icon_menu';
export default React.createClass({
displayName: 'IconMenu',
propTypes: {
className: React.PropTypes.string,
icon: React.PropTypes.string,
iconRipple: React.PropTypes.bool,
menuRipple: React.PropTypes.bool,
onClick: React.PropTypes.func,
onSelect: React.PropTypes.func,
position: React.PropTypes.string,
selectable: React.PropTypes.bool
},
getDefaultProps () {
return {
className: '',
icon: 'more-vert',
iconRipple: true,
menuRipple: true,
position: 'auto',
selectable: false
};
},
handleButtonClick () {
this.refs.menu.show();
if (this.props.onClick) this.props.onClick();
},
handleMouseDown (event) {
if (this.props.iconRipple) {
this.refs.ripple.start(event);
}
},
render () {
let className = style.root;
if (this.props.className) className += ` ${this.props.className}`;
return (
<div className={className}>
<FontIcon
className={style.icon}
onClick={this.handleButtonClick}
onMouseDown={this.handleMouseDown}
value={this.props.icon}
/>
<Menu
ref='menu'
onHide={this.props.onHide}
onSelect={this.props.onSelect}
onShow={this.props.onShow}
position={this.props.position}
ripple={this.props.menuRipple}
selectable={this.props.selectable}
>
{ this.props.children }
</Menu>
{ this.props.iconRipple ? <Ripple ref='ripple' className={style.ripple} spread={2.4} centered /> : null }
</div>
);
}
});

View File

@ -1,5 +1,6 @@
module.exports = {
Menu: require('./menu'),
MenuItem: require('./menu_item'),
MenuDivider: require('./menu_divider')
MenuDivider: require('./menu_divider'),
IconMenu: require('./icon_menu')
};

View File

@ -19,11 +19,13 @@ export default React.createClass({
propTypes: {
active: React.PropTypes.bool,
className: React.PropTypes.string,
onHide: React.PropTypes.func,
onSelect: React.PropTypes.func,
onShow: React.PropTypes.func,
outline: React.PropTypes.bool,
position: React.PropTypes.string,
ripple: React.PropTypes.bool,
selectable: React.PropTypes.bool,
outline: React.PropTypes.bool,
value: React.PropTypes.any
},
@ -31,9 +33,9 @@ export default React.createClass({
return {
active: false,
outline: true,
position: POSITION.STATIC,
ripple: true,
selectable: true,
position: POSITION.STATIC
selectable: true
};
},
@ -79,7 +81,10 @@ export default React.createClass({
componentDidUpdate (prevProps, prevState) {
if (prevState.active && !this.state.active) {
if (this.props.onHide) this.props.onHide();
utils.events.removeEventsFromDocument({click: this.handleDocumentClick});
} else if (!prevState.active && this.state.active && this.props.onShow) {
this.props.onShow();
}
},
@ -93,7 +98,7 @@ export default React.createClass({
const {top, left, height, width} = ReactDOM.findDOMNode(this).parentNode.getBoundingClientRect();
const {height: wh, width: ww} = utils.getViewport();
const toTop = top < ((wh / 2) - height / 2);
const toLeft = left > ((ww / 2) - width / 2);
const toLeft = left < ((ww / 2) - width / 2);
return `${toTop ? 'top' : 'bottom'}-${toLeft ? 'left' : 'right'}`;
},
@ -124,7 +129,7 @@ export default React.createClass({
let { value, onClick } = item.props;
this.setState({value: value, active: false, rippled: this.props.ripple}, () => {
if (onClick) onClick();
if (this.props.onSelect) this.props.onSelect({}, this);
if (this.props.onSelect) this.props.onSelect(value, this);
});
},

View File

@ -0,0 +1,18 @@
@import "../variables";
.root {
position: relative;
display: inline-block;
text-align: center;
}
.icon {
font-size: 2.3 * $unit;
vertical-align: middle;
cursor: pointer;
}
.ripple {
opacity: .1;
transition-duration: 650ms;
}

View File

@ -45,5 +45,5 @@ $menu-item-font-size: 1.6 * $unit;
}
.ripple {
opacity: .15;
opacity: .1;
}

View File

@ -0,0 +1,46 @@
import React from 'react';
import { MenuItem, IconMenu } from '../../components/menu';
export default React.createClass({
displayName: 'IconMenuTest',
handleShow () {
console.log('Showing menu...');
},
handleHide () {
console.log('Hiding menu...');
},
handleSelect (value, instance) {
console.log('Option selected', value, instance);
},
handleItem () {
console.log('Refresh clicked');
},
render () {
return (
<div>
<h5>Icon Menus</h5>
<p>Although a menu can be used indepently with any component, we are providing a common use case with the icon menu.</p>
<IconMenu
icon='more-vert'
position='auto'
iconRipple={true}
menuRipple={true}
onShow={this.handleShow}
onHide={this.handleHide}
onSelect={this.handleSelect}
selectable={false}
>
<MenuItem onClick={this.handleItem} value='refresh' caption='Refresh' />
<MenuItem value='help' caption='Help & Feedback' />
<MenuItem value='settings' caption='Settings' />
<MenuItem value='signout' caption='Sign out' disabled />
</IconMenu>
</div>
);
}
});

View File

@ -8,6 +8,7 @@ import Checkbox from './components/checkbox';
import Dialog from './components/dialog';
import Drawer from './components/drawer';
import Dropdown from './components/dropdown';
import IconMenu from './components/icon_menu';
import Input from './components/input';
import Menu from './components/menu';
import Pickers from './components/pickers';
@ -32,6 +33,7 @@ const Test = React.createClass({
<Dialog />
<Drawer />
<Dropdown />
<IconMenu />
<Input />
<Menu />
<Pickers />