Autoinject theme to Menu component
parent
767d16b047
commit
f88ddde727
|
@ -1,80 +1,88 @@
|
|||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { themr } from 'react-css-themr';
|
||||
import { IconButton } from '../button';
|
||||
import Menu from './Menu';
|
||||
import { MENU } from '../identifiers.js';
|
||||
import InjectIconButton from '../button/IconButton.js';
|
||||
import InjectMenu from './Menu.js';
|
||||
|
||||
class IconMenu extends React.Component {
|
||||
static propTypes = {
|
||||
children: React.PropTypes.node,
|
||||
className: React.PropTypes.string,
|
||||
icon: React.PropTypes.oneOfType([
|
||||
React.PropTypes.string,
|
||||
React.PropTypes.element
|
||||
]),
|
||||
iconRipple: React.PropTypes.bool,
|
||||
menuRipple: React.PropTypes.bool,
|
||||
onClick: React.PropTypes.func,
|
||||
onHide: React.PropTypes.func,
|
||||
onSelect: React.PropTypes.func,
|
||||
onShow: React.PropTypes.func,
|
||||
position: React.PropTypes.string,
|
||||
selectable: React.PropTypes.bool,
|
||||
selected: React.PropTypes.any,
|
||||
theme: React.PropTypes.shape({
|
||||
icon: React.PropTypes.string.isRequired,
|
||||
iconMenu: React.PropTypes.string.isRequired
|
||||
})
|
||||
};
|
||||
const factory = (IconButton, Menu) => {
|
||||
class IconMenu extends React.Component {
|
||||
static propTypes = {
|
||||
children: React.PropTypes.node,
|
||||
className: React.PropTypes.string,
|
||||
icon: React.PropTypes.oneOfType([
|
||||
React.PropTypes.string,
|
||||
React.PropTypes.element
|
||||
]),
|
||||
iconRipple: React.PropTypes.bool,
|
||||
menuRipple: React.PropTypes.bool,
|
||||
onClick: React.PropTypes.func,
|
||||
onHide: React.PropTypes.func,
|
||||
onSelect: React.PropTypes.func,
|
||||
onShow: React.PropTypes.func,
|
||||
position: React.PropTypes.string,
|
||||
selectable: React.PropTypes.bool,
|
||||
selected: React.PropTypes.any,
|
||||
theme: React.PropTypes.shape({
|
||||
icon: React.PropTypes.string.isRequired,
|
||||
iconMenu: React.PropTypes.string.isRequired
|
||||
})
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
className: '',
|
||||
icon: 'more_vert',
|
||||
iconRipple: true,
|
||||
menuRipple: true,
|
||||
position: 'auto',
|
||||
selectable: false
|
||||
};
|
||||
static defaultProps = {
|
||||
className: '',
|
||||
icon: 'more_vert',
|
||||
iconRipple: true,
|
||||
menuRipple: true,
|
||||
position: 'auto',
|
||||
selectable: false
|
||||
};
|
||||
|
||||
state = {
|
||||
active: false
|
||||
state = {
|
||||
active: false
|
||||
}
|
||||
|
||||
handleButtonClick = (event) => {
|
||||
this.setState({ active: !this.state.active });
|
||||
if (this.props.onClick) this.props.onClick(event);
|
||||
};
|
||||
|
||||
handleMenuHide = () => {
|
||||
this.setState({ active: false });
|
||||
if (this.props.onHide) this.props.onHide();
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className={classnames(this.props.theme.iconMenu, this.props.className)}>
|
||||
<IconButton
|
||||
className={this.props.theme.icon}
|
||||
icon={this.props.icon}
|
||||
onClick={this.handleButtonClick}
|
||||
ripple={this.props.iconRipple}
|
||||
/>
|
||||
<Menu
|
||||
ref='menu'
|
||||
active={this.state.active}
|
||||
onHide={this.handleMenuHide}
|
||||
onSelect={this.props.onSelect}
|
||||
onShow={this.props.onShow}
|
||||
position={this.props.position}
|
||||
ripple={this.props.menuRipple}
|
||||
selectable={this.props.selectable}
|
||||
selected={this.props.selected}
|
||||
>
|
||||
{this.props.children}
|
||||
</Menu>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
handleButtonClick = (event) => {
|
||||
this.setState({ active: !this.state.active });
|
||||
if (this.props.onClick) this.props.onClick(event);
|
||||
};
|
||||
return IconMenu;
|
||||
};
|
||||
|
||||
handleMenuHide = () => {
|
||||
this.setState({ active: false });
|
||||
if (this.props.onHide) this.props.onHide();
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className={classnames(this.props.theme.iconMenu, this.props.className)}>
|
||||
<IconButton
|
||||
className={this.props.theme.icon}
|
||||
icon={this.props.icon}
|
||||
onClick={this.handleButtonClick}
|
||||
ripple={this.props.iconRipple}
|
||||
/>
|
||||
<Menu
|
||||
ref='menu'
|
||||
active={this.state.active}
|
||||
onHide={this.handleMenuHide}
|
||||
onSelect={this.props.onSelect}
|
||||
onShow={this.props.onShow}
|
||||
position={this.props.position}
|
||||
ripple={this.props.menuRipple}
|
||||
selectable={this.props.selectable}
|
||||
selected={this.props.selected}
|
||||
>
|
||||
{this.props.children}
|
||||
</Menu>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default themr('ToolboxMenu')(IconMenu);
|
||||
const IconMenu = factory(InjectIconButton, InjectMenu);
|
||||
export default themr(MENU)(IconMenu);
|
||||
export { factory as iconMenuFactory };
|
||||
export { IconMenu };
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { themr } from 'react-css-themr';
|
||||
import classnames from 'classnames';
|
||||
import MenuItem from './MenuItem';
|
||||
import { themr } from 'react-css-themr';
|
||||
import { MENU } from '../identifiers.js';
|
||||
import { events, utils } from '../utils';
|
||||
import InjectMenuItem from './MenuItem.js';
|
||||
|
||||
const POSITION = {
|
||||
AUTO: 'auto',
|
||||
|
@ -14,193 +15,200 @@ const POSITION = {
|
|||
BOTTOM_RIGHT: 'bottomRight'
|
||||
};
|
||||
|
||||
class Menu extends React.Component {
|
||||
static propTypes = {
|
||||
active: React.PropTypes.bool,
|
||||
children: React.PropTypes.node,
|
||||
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,
|
||||
selected: React.PropTypes.any,
|
||||
theme: React.PropTypes.shape({
|
||||
active: React.PropTypes.string.isRequired,
|
||||
bottomLeft: React.PropTypes.string.isRequired,
|
||||
bottomRight: React.PropTypes.string.isRequired,
|
||||
menu: React.PropTypes.string.isRequired,
|
||||
menuInner: React.PropTypes.string.isRequired,
|
||||
outline: React.PropTypes.string.isRequired,
|
||||
rippled: React.PropTypes.string.isRequired,
|
||||
static: React.PropTypes.string.isRequired,
|
||||
topLeft: React.PropTypes.string.isRequired,
|
||||
topRight: React.PropTypes.string.isRequired
|
||||
})
|
||||
};
|
||||
const factory = (MenuItem) => {
|
||||
class Menu extends React.Component {
|
||||
static propTypes = {
|
||||
active: React.PropTypes.bool,
|
||||
children: React.PropTypes.node,
|
||||
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,
|
||||
selected: React.PropTypes.any,
|
||||
theme: React.PropTypes.shape({
|
||||
active: React.PropTypes.string.isRequired,
|
||||
bottomLeft: React.PropTypes.string.isRequired,
|
||||
bottomRight: React.PropTypes.string.isRequired,
|
||||
menu: React.PropTypes.string.isRequired,
|
||||
menuInner: React.PropTypes.string.isRequired,
|
||||
outline: React.PropTypes.string.isRequired,
|
||||
rippled: React.PropTypes.string.isRequired,
|
||||
static: React.PropTypes.string.isRequired,
|
||||
topLeft: React.PropTypes.string.isRequired,
|
||||
topRight: React.PropTypes.string.isRequired
|
||||
})
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
active: false,
|
||||
outline: true,
|
||||
position: POSITION.STATIC,
|
||||
ripple: true,
|
||||
selectable: true
|
||||
};
|
||||
static defaultProps = {
|
||||
active: false,
|
||||
outline: true,
|
||||
position: POSITION.STATIC,
|
||||
ripple: true,
|
||||
selectable: true
|
||||
};
|
||||
|
||||
state = {
|
||||
active: this.props.active,
|
||||
rippled: false
|
||||
};
|
||||
state = {
|
||||
active: this.props.active,
|
||||
rippled: false
|
||||
};
|
||||
|
||||
componentDidMount () {
|
||||
this.positionTimeoutHandle = setTimeout(() => {
|
||||
const { width, height } = this.refs.menu.getBoundingClientRect();
|
||||
const position = this.props.position === POSITION.AUTO ? this.calculatePosition() : this.props.position;
|
||||
this.setState({ position, width, height });
|
||||
});
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
if (this.props.position !== nextProps.position) {
|
||||
const position = nextProps.position === POSITION.AUTO ? this.calculatePosition() : nextProps.position;
|
||||
this.setState({ position });
|
||||
componentDidMount () {
|
||||
this.positionTimeoutHandle = setTimeout(() => {
|
||||
const { width, height } = this.refs.menu.getBoundingClientRect();
|
||||
const position = this.props.position === POSITION.AUTO ? this.calculatePosition() : this.props.position;
|
||||
this.setState({ position, width, height });
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.props.active && nextProps.active && !this.state.active) {
|
||||
this.show();
|
||||
}
|
||||
componentWillReceiveProps (nextProps) {
|
||||
if (this.props.position !== nextProps.position) {
|
||||
const position = nextProps.position === POSITION.AUTO ? this.calculatePosition() : nextProps.position;
|
||||
this.setState({ position });
|
||||
}
|
||||
|
||||
if (this.props.active && !nextProps.active && this.state.active) {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
if (!this.props.active && nextProps.active && !this.state.active) {
|
||||
this.show();
|
||||
}
|
||||
|
||||
shouldComponentUpdate (nextProps, nextState) {
|
||||
if (!this.state.active && nextState.active && this.props.position === POSITION.AUTO) {
|
||||
const position = this.calculatePosition();
|
||||
if (this.state.position !== position) {
|
||||
this.setState({ position, active: false }, () => {
|
||||
this.activateTimeoutHandle = setTimeout(() => {this.setState({active: true}); }, 20);
|
||||
});
|
||||
return false;
|
||||
if (this.props.active && !nextProps.active && this.state.active) {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
componentWillUpdate (nextProps, nextState) {
|
||||
if (!this.state.active && nextState.active) {
|
||||
events.addEventsToDocument({click: this.handleDocumentClick});
|
||||
shouldComponentUpdate (nextProps, nextState) {
|
||||
if (!this.state.active && nextState.active && this.props.position === POSITION.AUTO) {
|
||||
const position = this.calculatePosition();
|
||||
if (this.state.position !== position) {
|
||||
this.setState({ position, active: false }, () => {
|
||||
this.activateTimeoutHandle = setTimeout(() => {this.setState({active: true}); }, 20);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate (prevProps, prevState) {
|
||||
if (prevState.active && !this.state.active) {
|
||||
if (this.props.onHide) this.props.onHide();
|
||||
events.removeEventsFromDocument({click: this.handleDocumentClick});
|
||||
} else if (!prevState.active && this.state.active && this.props.onShow) {
|
||||
this.props.onShow();
|
||||
componentWillUpdate (nextProps, nextState) {
|
||||
if (!this.state.active && nextState.active) {
|
||||
events.addEventsToDocument({click: this.handleDocumentClick});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
if (this.state.active) {
|
||||
events.removeEventsFromDocument({click: this.handleDocumentClick});
|
||||
componentDidUpdate (prevProps, prevState) {
|
||||
if (prevState.active && !this.state.active) {
|
||||
if (this.props.onHide) this.props.onHide();
|
||||
events.removeEventsFromDocument({click: this.handleDocumentClick});
|
||||
} else if (!prevState.active && this.state.active && this.props.onShow) {
|
||||
this.props.onShow();
|
||||
}
|
||||
}
|
||||
clearTimeout(this.positionTimeoutHandle);
|
||||
clearTimeout(this.activateTimeoutHandle);
|
||||
}
|
||||
|
||||
handleDocumentClick = (event) => {
|
||||
if (this.state.active && !events.targetIsDescendant(event, ReactDOM.findDOMNode(this))) {
|
||||
this.setState({active: false, rippled: false});
|
||||
}
|
||||
};
|
||||
|
||||
handleSelect = (item) => {
|
||||
const { value, onClick } = item.props;
|
||||
this.setState({ active: false, rippled: this.props.ripple }, () => {
|
||||
if (onClick) onClick();
|
||||
if (this.props.onSelect) this.props.onSelect(value);
|
||||
});
|
||||
};
|
||||
|
||||
calculatePosition () {
|
||||
const parentNode = ReactDOM.findDOMNode(this).parentNode;
|
||||
if (!parentNode) return;
|
||||
const {top, left, height, width} = parentNode.getBoundingClientRect();
|
||||
const {height: wh, width: ww} = utils.getViewport();
|
||||
const toTop = top < ((wh / 2) - height / 2);
|
||||
const toLeft = left < ((ww / 2) - width / 2);
|
||||
return `${toTop ? 'top' : 'bottom'}${toLeft ? 'Left' : 'Right'}`;
|
||||
}
|
||||
|
||||
getMenuStyle () {
|
||||
const { width, height, position } = this.state;
|
||||
if (position !== POSITION.STATIC) {
|
||||
componentWillUnmount () {
|
||||
if (this.state.active) {
|
||||
return { clip: `rect(0 ${width}px ${height}px 0)` };
|
||||
} else if (position === POSITION.TOP_RIGHT) {
|
||||
return { clip: `rect(0 ${width}px 0 ${width}px)` };
|
||||
} else if (position === POSITION.BOTTOM_RIGHT) {
|
||||
return { clip: `rect(${height}px ${width}px ${height}px ${width}px)` };
|
||||
} else if (position === POSITION.BOTTOM_LEFT) {
|
||||
return { clip: `rect(${height}px 0 ${height}px 0)` };
|
||||
} else if (position === POSITION.TOP_LEFT) {
|
||||
return { clip: 'rect(0 0 0 0)' };
|
||||
events.removeEventsFromDocument({click: this.handleDocumentClick});
|
||||
}
|
||||
clearTimeout(this.positionTimeoutHandle);
|
||||
clearTimeout(this.activateTimeoutHandle);
|
||||
}
|
||||
|
||||
handleDocumentClick = (event) => {
|
||||
if (this.state.active && !events.targetIsDescendant(event, ReactDOM.findDOMNode(this))) {
|
||||
this.setState({active: false, rippled: false});
|
||||
}
|
||||
};
|
||||
|
||||
handleSelect = (item) => {
|
||||
const { value, onClick } = item.props;
|
||||
this.setState({ active: false, rippled: this.props.ripple }, () => {
|
||||
if (onClick) onClick();
|
||||
if (this.props.onSelect) this.props.onSelect(value);
|
||||
});
|
||||
};
|
||||
|
||||
calculatePosition () {
|
||||
const parentNode = ReactDOM.findDOMNode(this).parentNode;
|
||||
if (!parentNode) return;
|
||||
const {top, left, height, width} = parentNode.getBoundingClientRect();
|
||||
const {height: wh, width: ww} = utils.getViewport();
|
||||
const toTop = top < ((wh / 2) - height / 2);
|
||||
const toLeft = left < ((ww / 2) - width / 2);
|
||||
return `${toTop ? 'top' : 'bottom'}${toLeft ? 'Left' : 'Right'}`;
|
||||
}
|
||||
|
||||
getMenuStyle () {
|
||||
const { width, height, position } = this.state;
|
||||
if (position !== POSITION.STATIC) {
|
||||
if (this.state.active) {
|
||||
return { clip: `rect(0 ${width}px ${height}px 0)` };
|
||||
} else if (position === POSITION.TOP_RIGHT) {
|
||||
return { clip: `rect(0 ${width}px 0 ${width}px)` };
|
||||
} else if (position === POSITION.BOTTOM_RIGHT) {
|
||||
return { clip: `rect(${height}px ${width}px ${height}px ${width}px)` };
|
||||
} else if (position === POSITION.BOTTOM_LEFT) {
|
||||
return { clip: `rect(${height}px 0 ${height}px 0)` };
|
||||
} else if (position === POSITION.TOP_LEFT) {
|
||||
return { clip: 'rect(0 0 0 0)' };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getRootStyle () {
|
||||
if (this.state.position !== POSITION.STATIC) {
|
||||
return { width: this.state.width, height: this.state.height };
|
||||
}
|
||||
}
|
||||
|
||||
renderItems () {
|
||||
return React.Children.map(this.props.children, (item) => {
|
||||
if (!item) return item;
|
||||
if (item.type === MenuItem) {
|
||||
return React.cloneElement(item, {
|
||||
ripple: item.props.ripple || this.props.ripple,
|
||||
selected: typeof item.props.value !== 'undefined' && this.props.selectable && item.props.value === this.props.selected,
|
||||
onClick: this.handleSelect.bind(this, item)
|
||||
});
|
||||
} else {
|
||||
return React.cloneElement(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
show () {
|
||||
const { width, height } = this.refs.menu.getBoundingClientRect();
|
||||
this.setState({active: true, width, height});
|
||||
}
|
||||
|
||||
hide () {
|
||||
this.setState({active: false});
|
||||
}
|
||||
|
||||
render () {
|
||||
const { theme } = this.props;
|
||||
const outlineStyle = { width: this.state.width, height: this.state.height };
|
||||
const className = classnames([theme.menu, theme[this.state.position]], {
|
||||
[theme.active]: this.state.active,
|
||||
[theme.rippled]: this.state.rippled
|
||||
}, this.props.className);
|
||||
|
||||
return (
|
||||
<div data-react-toolbox='menu' className={className} style={this.getRootStyle()}>
|
||||
{this.props.outline ? <div className={theme.outline} style={outlineStyle}></div> : null}
|
||||
<ul ref='menu' className={theme.menuInner} style={this.getMenuStyle()}>
|
||||
{this.renderItems()}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
getRootStyle () {
|
||||
if (this.state.position !== POSITION.STATIC) {
|
||||
return { width: this.state.width, height: this.state.height };
|
||||
}
|
||||
}
|
||||
return Menu;
|
||||
};
|
||||
|
||||
renderItems () {
|
||||
return React.Children.map(this.props.children, (item) => {
|
||||
if (!item) return item;
|
||||
if (item.type === MenuItem) {
|
||||
return React.cloneElement(item, {
|
||||
ripple: item.props.ripple || this.props.ripple,
|
||||
selected: typeof item.props.value !== 'undefined' && this.props.selectable && item.props.value === this.props.selected,
|
||||
onClick: this.handleSelect.bind(this, item)
|
||||
});
|
||||
} else {
|
||||
return React.cloneElement(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
show () {
|
||||
const { width, height } = this.refs.menu.getBoundingClientRect();
|
||||
this.setState({active: true, width, height});
|
||||
}
|
||||
|
||||
hide () {
|
||||
this.setState({active: false});
|
||||
}
|
||||
|
||||
render () {
|
||||
const { theme } = this.props;
|
||||
const outlineStyle = { width: this.state.width, height: this.state.height };
|
||||
const className = classnames([theme.menu, theme[this.state.position]], {
|
||||
[theme.active]: this.state.active,
|
||||
[theme.rippled]: this.state.rippled
|
||||
}, this.props.className);
|
||||
|
||||
return (
|
||||
<div data-react-toolbox='menu' className={className} style={this.getRootStyle()}>
|
||||
{this.props.outline ? <div className={theme.outline} style={outlineStyle}></div> : null}
|
||||
<ul ref='menu' className={theme.menuInner} style={this.getMenuStyle()}>
|
||||
{this.renderItems()}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default themr('ToolboxMenu')(Menu);
|
||||
const Menu = factory(InjectMenuItem);
|
||||
export default themr(MENU)(Menu);
|
||||
export { factory as menuFactory };
|
||||
export { Menu };
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
import React from 'react';
|
||||
import React, { PropTypes } from 'react';
|
||||
import { themr } from 'react-css-themr';
|
||||
import { MENU } from '../identifiers.js';
|
||||
|
||||
const MenuDivider = ({ theme }) => (
|
||||
<hr data-react-toolbox='menu-divider' className={theme.menuDivider}/>
|
||||
);
|
||||
|
||||
MenuDivider.propTypes = {
|
||||
theme: React.PropTypes.shape({
|
||||
menuDivider: React.PropTypes.string.isRequired
|
||||
theme: PropTypes.shape({
|
||||
menuDivider: PropTypes.string.isRequired
|
||||
})
|
||||
};
|
||||
|
||||
export default themr('ToolboxMenu')(MenuDivider);
|
||||
export default themr(MENU)(MenuDivider);
|
||||
export { MenuDivider };
|
||||
|
|
|
@ -1,62 +1,68 @@
|
|||
import React from 'react';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { themr } from 'react-css-themr';
|
||||
import FontIcon from '../font_icon';
|
||||
import Ripple from '../ripple';
|
||||
import { MENU } from '../identifiers.js';
|
||||
import FontIcon from '../font_icon/FontIcon.js';
|
||||
import rippleFactory from '../ripple/Ripple.js';
|
||||
|
||||
class MenuItem extends React.Component {
|
||||
static propTypes = {
|
||||
caption: React.PropTypes.string.isRequired,
|
||||
children: React.PropTypes.any,
|
||||
className: React.PropTypes.string,
|
||||
disabled: React.PropTypes.bool,
|
||||
icon: React.PropTypes.oneOfType([
|
||||
React.PropTypes.string,
|
||||
React.PropTypes.element
|
||||
]),
|
||||
onClick: React.PropTypes.func,
|
||||
selected: React.PropTypes.bool,
|
||||
shortcut: React.PropTypes.string,
|
||||
theme: React.PropTypes.shape({
|
||||
caption: React.PropTypes.string.isRequired,
|
||||
disabled: React.PropTypes.string.isRequired,
|
||||
icon: React.PropTypes.string.isRequired,
|
||||
menuItem: React.PropTypes.string.isRequired,
|
||||
selected: React.PropTypes.string.isRequired,
|
||||
shortcut: React.PropTypes.string.isRequired
|
||||
})
|
||||
};
|
||||
const factory = (ripple) => {
|
||||
class MenuItem extends Component {
|
||||
static propTypes = {
|
||||
caption: PropTypes.string.isRequired,
|
||||
children: PropTypes.any,
|
||||
className: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
icon: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.element
|
||||
]),
|
||||
onClick: PropTypes.func,
|
||||
selected: PropTypes.bool,
|
||||
shortcut: PropTypes.string,
|
||||
theme: PropTypes.shape({
|
||||
caption: PropTypes.string.isRequired,
|
||||
disabled: PropTypes.string.isRequired,
|
||||
icon: PropTypes.string.isRequired,
|
||||
menuItem: PropTypes.string.isRequired,
|
||||
selected: PropTypes.string.isRequired,
|
||||
shortcut: PropTypes.string.isRequired
|
||||
})
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
className: '',
|
||||
disabled: false,
|
||||
selected: false
|
||||
};
|
||||
static defaultProps = {
|
||||
className: '',
|
||||
disabled: false,
|
||||
selected: false
|
||||
};
|
||||
|
||||
handleClick = (event) => {
|
||||
if (this.props.onClick && !this.props.disabled) {
|
||||
this.props.onClick(event, this);
|
||||
handleClick = (event) => {
|
||||
if (this.props.onClick && !this.props.disabled) {
|
||||
this.props.onClick(event, this);
|
||||
}
|
||||
};
|
||||
|
||||
render () {
|
||||
const {icon, caption, children, shortcut, selected, disabled, theme, ...others} = this.props;
|
||||
const className = classnames(theme.menuItem, {
|
||||
[theme.selected]: selected,
|
||||
[theme.disabled]: disabled
|
||||
}, this.props.className);
|
||||
|
||||
return (
|
||||
<li {...others} data-react-toolbox='menu-item' className={className} onClick={this.handleClick}>
|
||||
{icon ? <FontIcon value={icon} className={theme.icon}/> : null}
|
||||
<span className={theme.caption}>{caption}</span>
|
||||
{shortcut ? <small className={theme.shortcut}>{shortcut}</small> : null}
|
||||
{children}
|
||||
</li>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
render () {
|
||||
const {icon, caption, children, shortcut, selected, disabled, theme, ...others} = this.props;
|
||||
const className = classnames(theme.menuItem, {
|
||||
[theme.selected]: selected,
|
||||
[theme.disabled]: disabled
|
||||
}, this.props.className);
|
||||
|
||||
return (
|
||||
<li {...others} data-react-toolbox='menu-item' className={className} onClick={this.handleClick}>
|
||||
{icon ? <FontIcon value={icon} className={theme.icon}/> : null}
|
||||
<span className={theme.caption}>{caption}</span>
|
||||
{shortcut ? <small className={theme.shortcut}>{shortcut}</small> : null}
|
||||
{children}
|
||||
</li>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const RawMenuItem = themr('ToolboxMenu')(MenuItem);
|
||||
export default themr('ToolboxMenu')(Ripple({})(MenuItem));
|
||||
export {RawMenuItem as RawMenuItem};
|
||||
return ripple(MenuItem);
|
||||
};
|
||||
|
||||
const MenuItem = factory(rippleFactory({}));
|
||||
export default themr(MENU)(MenuItem);
|
||||
export { factory as menuItemFactory };
|
||||
export { MenuItem };
|
||||
|
|
|
@ -1,4 +1,20 @@
|
|||
export Menu from './Menu';
|
||||
export MenuItem from './MenuItem';
|
||||
export MenuDivider from './MenuDivider';
|
||||
export IconMenu from './IconMenu';
|
||||
import { themr } from 'react-css-themr';
|
||||
import { MENU } from '../identifiers.js';
|
||||
import { IconButton } from '../button';
|
||||
import { MenuDivider } from './MenuDivider.js';
|
||||
import { menuItemFactory } from './MenuItem.js';
|
||||
import { menuFactory } from './Menu.js';
|
||||
import { iconMenuFactory } from './IconMenu.js';
|
||||
import themedRippleFactory from '../ripple';
|
||||
import theme from './theme.scss';
|
||||
|
||||
const applyTheme = (Component) => themr(MENU, theme)(Component);
|
||||
const ThemedMenuDivider = applyTheme(MenuDivider);
|
||||
const ThemedMenuItem = applyTheme(menuItemFactory(themedRippleFactory({})));
|
||||
const ThemedMenu = applyTheme(menuFactory(ThemedMenuItem));
|
||||
const ThemedIconMenu = applyTheme(iconMenuFactory(IconButton, ThemedMenu));
|
||||
|
||||
export { ThemedMenuDivider as MenuDivider };
|
||||
export { ThemedMenuItem as MenuItem };
|
||||
export { ThemedMenu as Menu };
|
||||
export { ThemedIconMenu as IconMenu };
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import '../components/commons.scss';
|
||||
|
||||
import ToolboxMenu from '../components/menu/theme.scss';
|
||||
import ToolboxNavigation from '../components/navigation/theme.scss';
|
||||
import ToolboxProgress from '../components/progress_bar/theme.scss';
|
||||
import ToolboxRadio from '../components/radio/theme.scss';
|
||||
|
@ -13,7 +12,6 @@ import ToolboxTimePicker from '../components/time_picker/theme.scss';
|
|||
import ToolboxTooltip from '../components/tooltip/theme.scss';
|
||||
|
||||
export default {
|
||||
ToolboxMenu,
|
||||
ToolboxNavigation,
|
||||
ToolboxProgress,
|
||||
ToolboxRadio,
|
||||
|
|
Loading…
Reference in New Issue