@6thquake/react-material
Version:
React components that implement Google's Material Design.
332 lines (278 loc) • 7.92 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
/**
* @ignore - do not document.
*/
import React from 'react';
import PropTypes from 'prop-types';
import withStyles from '../styles/withStyles';
import { findDOMNode } from 'react-dom';
import RcMenu, { Divider } from 'rc-menu';
import classNames from 'classnames';
import SubMenuBar from './SubMenuBar';
import MenuBarItem from './MenuBarItem';
import MenuBarItemGroup from './MenuBarItemGroup';
import styles from './styles';
const menuPrefixCls = 'rm-menu';
const effect = {
animationDuration: 0.3,
animationFillMode: 'both',
transformOrigin: '0 0'
};
function leave(node, done) {
done();
}
class OriginNavBar extends React.Component {
constructor(props) {
super(props);
this.inlineOpenKeys = [];
this.handleClick = e => {
this.handleOpenChange([]);
const {
onClick
} = this.props;
if (onClick) {
onClick(e);
}
};
this.handleOpenChange = openKeys => {
this.setOpenKeys(openKeys);
const {
onOpenChange
} = this.props;
if (onOpenChange) {
onOpenChange(openKeys);
}
};
let openKeys;
if ('defaultOpenKeys' in props) {
openKeys = props.defaultOpenKeys;
} else if ('openKeys' in props) {
openKeys = props.openKeys;
}
this.state = {
openKeys: openKeys || []
};
}
getChildContext() {
return {
inlineCollapsed: this.getInlineCollapsed(),
rMMenuTheme: this.props.theme
};
} // todo remove unsafe life
componentWillReceiveProps(nextProps, nextContext) {
// componentWillReceiveProps(nextProps, nextContext) {
const {
prefixCls
} = this.props;
if (this.props.mode === 'inline' && nextProps.mode !== 'inline') {
this.switchModeFromInline = true;
}
if ('openKeys' in nextProps) {
this.setState({
openKeys: nextProps.openKeys
});
return;
}
if (nextProps.inlineCollapsed && !this.props.inlineCollapsed || nextContext.siderCollapsed && !this.context.siderCollapsed) {
const menuNode = findDOMNode(this);
this.switchModeFromInline = !!this.state.openKeys.length && !!menuNode.querySelectorAll(`.${prefixCls}-submenu-open`).length;
this.inlineOpenKeys = this.state.openKeys;
this.setState({
openKeys: []
});
}
if (!nextProps.inlineCollapsed && this.props.inlineCollapsed || !nextContext.siderCollapsed && this.context.siderCollapsed) {
this.setState({
openKeys: this.inlineOpenKeys
});
this.inlineOpenKeys = [];
}
}
setOpenKeys(openKeys) {
if (!('openKeys' in this.props)) {
this.setState({
openKeys
});
}
}
getRealMenuMode() {
const inlineCollapsed = this.getInlineCollapsed();
if (this.switchModeFromInline && inlineCollapsed) {
return 'inline';
}
const {
mode
} = this.props;
return inlineCollapsed ? 'vertical' : mode;
}
getInlineCollapsed() {
const {
inlineCollapsed
} = this.props;
if (this.context.siderCollapsed !== undefined) {
return this.context.siderCollapsed;
}
return inlineCollapsed;
}
getMenuOpenAnimation(menuMode) {
const {
openAnimation,
openTransitionName
} = this.props;
let menuOpenAnimation = openAnimation || openTransitionName;
if (openAnimation === undefined && openTransitionName === undefined) {
switch (menuMode) {
case 'horizontal':
menuOpenAnimation = 'slide-up';
break;
case 'vertical':
case 'vertical-left':
case 'vertical-right':
// When mode switch from inline
// submenu should hide without animation
if (this.switchModeFromInline) {
menuOpenAnimation = '';
this.switchModeFromInline = false;
} else {
menuOpenAnimation = 'zoom-big';
}
break;
case 'inline':
menuOpenAnimation = {// leave: (node, done) => {
// this.switchModeFromInline = false;
// this.setState({});
// if (this.getRealMenuMode() === 'vertical') {
// return;
// }
// done();
// }
};
this.switchModeFromInline = false;
break;
default:
}
}
return menuOpenAnimation;
}
render() {
const {
prefixCls,
className,
theme
} = this.props;
const _this$props = this.props,
props = _objectWithoutPropertiesLoose(_this$props, ["classes"]);
const menuMode = this.getRealMenuMode();
const menuOpenAnimation = this.getMenuOpenAnimation(menuMode);
const menuClassName = classNames(className, `${prefixCls}-${theme}`, {
[`${prefixCls}-inline-collapsed`]: this.getInlineCollapsed()
});
const menuProps = {
openKeys: this.state.openKeys,
onOpenChange: this.handleOpenChange,
className: menuClassName,
mode: menuMode
};
if (menuMode !== 'inline') {
// closing vertical popup submenu after click it
menuProps.onClick = this.handleClick;
menuProps.openTransitionName = menuOpenAnimation;
} else {
menuProps.openAnimation = menuOpenAnimation;
}
const {
collapsedWidth
} = this.context;
if (this.getInlineCollapsed() && (collapsedWidth === 0 || collapsedWidth === '0' || collapsedWidth === '0px')) {
return null;
}
return React.createElement(RcMenu, _extends({}, props, menuProps, {
mode: "horizontal",
selectable: false
}));
}
}
OriginNavBar.Divider = Divider;
OriginNavBar.Item = MenuBarItem;
OriginNavBar.SubMenu = SubMenuBar;
OriginNavBar.ItemGroup = MenuBarItemGroup;
process.env.NODE_ENV !== "production" ? OriginNavBar.propTypes = {
/**
* @ignore
*/
className: PropTypes.string,
/**
* 初始选中的菜单项 key 数组
*/
defaultOpenKeys: PropTypes.arrayOf(PropTypes.string),
/**
* 初始展开的 SubMenu 菜单项 key 数组
*/
defaultSelectedKeys: PropTypes.arrayOf(PropTypes.string),
/**
* inline 时菜单是否收起状态
*/
inlineCollapsed: PropTypes.bool,
/**
* 菜单类型,现在支持垂直、水平、和内嵌模式三种
*/
mode: PropTypes.oneOf(['vertical', 'horizontal', 'inline']),
/**
* 是否允许多选
*/
multiple: PropTypes.bool,
/**
* 点击 MenuItem 调用此函数 ,参数 ({item, key, keyPath})
*/
onClick: PropTypes.func,
/**
* 取消选中时调用,仅在 multiple 生效,参数 ({item, key, selectedKeys})
*/
onDeselect: PropTypes.func,
/**
* SubMenu 展开/关闭的回调,参数 (openKeys)
*/
onOpenChange: PropTypes.func,
/**
* 被选中时调用,参数 ({item, key, selectedKeys})
*/
onSelect: PropTypes.func,
/**
* 当前展开的 SubMenu 菜单项 key 数组
*/
openKeys: PropTypes.arrayOf(PropTypes.string),
/**
* @ignore
*/
prefixCls: PropTypes.string,
/**
* 是否允许选中
*/
selectable: PropTypes.bool,
/**
* 当前选中的菜单项 key 数组
*/
selectedKeys: PropTypes.arrayOf(PropTypes.string),
/**
* 主题颜色
*/
theme: PropTypes.oneOf(['light', 'dark'])
} : void 0;
OriginNavBar.defaultProps = {
prefixCls: menuPrefixCls,
className: '',
theme: 'light'
};
OriginNavBar.childContextTypes = {
inlineCollapsed: PropTypes.bool,
rMMenuTheme: PropTypes.string
};
OriginNavBar.contextTypes = {
siderCollapsed: PropTypes.bool,
collapsedWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
};
export { SubMenuBar, MenuBarItem, MenuBarItemGroup };
export default withStyles(styles, {
name: 'RMOriginNavBar'
})(OriginNavBar);