456 lines
13 KiB
JavaScript
456 lines
13 KiB
JavaScript
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
|
|
|
|
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
|
|
|
|
var _extends2 = require('babel-runtime/helpers/extends');
|
|
|
|
var _extends3 = _interopRequireDefault(_extends2);
|
|
|
|
var _react = require('react');
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _propTypes = require('prop-types');
|
|
|
|
var _propTypes2 = _interopRequireDefault(_propTypes);
|
|
|
|
var _createReactClass = require('create-react-class');
|
|
|
|
var _createReactClass2 = _interopRequireDefault(_createReactClass);
|
|
|
|
var _SubPopupMenu = require('./SubPopupMenu');
|
|
|
|
var _SubPopupMenu2 = _interopRequireDefault(_SubPopupMenu);
|
|
|
|
var _KeyCode = require('rc-util/lib/KeyCode');
|
|
|
|
var _KeyCode2 = _interopRequireDefault(_KeyCode);
|
|
|
|
var _classnames = require('classnames');
|
|
|
|
var _classnames2 = _interopRequireDefault(_classnames);
|
|
|
|
var _util = require('./util');
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
var guid = 0;
|
|
|
|
/* eslint react/no-is-mounted:0 */
|
|
|
|
var SubMenu = (0, _createReactClass2['default'])({
|
|
displayName: 'SubMenu',
|
|
|
|
propTypes: {
|
|
parentMenu: _propTypes2['default'].object,
|
|
title: _propTypes2['default'].node,
|
|
children: _propTypes2['default'].any,
|
|
selectedKeys: _propTypes2['default'].array,
|
|
openKeys: _propTypes2['default'].array,
|
|
onClick: _propTypes2['default'].func,
|
|
onOpenChange: _propTypes2['default'].func,
|
|
rootPrefixCls: _propTypes2['default'].string,
|
|
eventKey: _propTypes2['default'].string,
|
|
multiple: _propTypes2['default'].bool,
|
|
active: _propTypes2['default'].bool,
|
|
onSelect: _propTypes2['default'].func,
|
|
closeSubMenuOnMouseLeave: _propTypes2['default'].bool,
|
|
openSubMenuOnMouseEnter: _propTypes2['default'].bool,
|
|
onDeselect: _propTypes2['default'].func,
|
|
onDestroy: _propTypes2['default'].func,
|
|
onItemHover: _propTypes2['default'].func,
|
|
onMouseEnter: _propTypes2['default'].func,
|
|
onMouseLeave: _propTypes2['default'].func,
|
|
onTitleMouseEnter: _propTypes2['default'].func,
|
|
onTitleMouseLeave: _propTypes2['default'].func,
|
|
onTitleClick: _propTypes2['default'].func
|
|
},
|
|
|
|
mixins: [require('./SubMenuStateMixin')],
|
|
|
|
getDefaultProps: function getDefaultProps() {
|
|
return {
|
|
onMouseEnter: _util.noop,
|
|
onMouseLeave: _util.noop,
|
|
onTitleMouseEnter: _util.noop,
|
|
onTitleMouseLeave: _util.noop,
|
|
onTitleClick: _util.noop,
|
|
title: ''
|
|
};
|
|
},
|
|
getInitialState: function getInitialState() {
|
|
this.isSubMenu = 1;
|
|
return {
|
|
defaultActiveFirst: false
|
|
};
|
|
},
|
|
componentWillUnmount: function componentWillUnmount() {
|
|
var _props = this.props,
|
|
onDestroy = _props.onDestroy,
|
|
eventKey = _props.eventKey,
|
|
parentMenu = _props.parentMenu;
|
|
|
|
if (onDestroy) {
|
|
onDestroy(eventKey);
|
|
}
|
|
if (parentMenu.subMenuInstance === this) {
|
|
this.clearSubMenuTimers();
|
|
}
|
|
},
|
|
onDestroy: function onDestroy(key) {
|
|
this.props.onDestroy(key);
|
|
},
|
|
onKeyDown: function onKeyDown(e) {
|
|
var keyCode = e.keyCode;
|
|
var menu = this.menuInstance;
|
|
var isOpen = this.isOpen();
|
|
|
|
if (keyCode === _KeyCode2['default'].ENTER) {
|
|
this.onTitleClick(e);
|
|
this.setState({
|
|
defaultActiveFirst: true
|
|
});
|
|
return true;
|
|
}
|
|
|
|
if (keyCode === _KeyCode2['default'].RIGHT) {
|
|
if (isOpen) {
|
|
menu.onKeyDown(e);
|
|
} else {
|
|
this.triggerOpenChange(true);
|
|
this.setState({
|
|
defaultActiveFirst: true
|
|
});
|
|
}
|
|
return true;
|
|
}
|
|
if (keyCode === _KeyCode2['default'].LEFT) {
|
|
var handled = void 0;
|
|
if (isOpen) {
|
|
handled = menu.onKeyDown(e);
|
|
} else {
|
|
return undefined;
|
|
}
|
|
if (!handled) {
|
|
this.triggerOpenChange(false);
|
|
handled = true;
|
|
}
|
|
return handled;
|
|
}
|
|
|
|
if (isOpen && (keyCode === _KeyCode2['default'].UP || keyCode === _KeyCode2['default'].DOWN)) {
|
|
return menu.onKeyDown(e);
|
|
}
|
|
},
|
|
onOpenChange: function onOpenChange(e) {
|
|
this.props.onOpenChange(e);
|
|
},
|
|
onMouseEnter: function onMouseEnter(e) {
|
|
var props = this.props;
|
|
this.clearSubMenuLeaveTimer();
|
|
props.onMouseEnter({
|
|
key: props.eventKey,
|
|
domEvent: e
|
|
});
|
|
},
|
|
onMouseLeave: function onMouseLeave(e) {
|
|
var _this = this;
|
|
|
|
var props = this.props;
|
|
var parentMenu = props.parentMenu,
|
|
eventKey = props.eventKey;
|
|
|
|
parentMenu.subMenuInstance = this;
|
|
parentMenu.subMenuLeaveFn = function () {
|
|
// leave whole sub tree
|
|
// still active
|
|
if (props.mode !== 'inline') {
|
|
var isOpen = _this.isOpen();
|
|
if (isOpen && props.closeSubMenuOnMouseLeave && props.active) {
|
|
props.onItemHover({
|
|
key: eventKey,
|
|
item: _this,
|
|
hover: false,
|
|
trigger: 'mouseleave',
|
|
openChanges: [{
|
|
key: eventKey,
|
|
item: _this,
|
|
trigger: 'mouseleave',
|
|
open: false
|
|
}]
|
|
});
|
|
} else {
|
|
if (props.active) {
|
|
props.onItemHover({
|
|
key: eventKey,
|
|
item: _this,
|
|
hover: false,
|
|
trigger: 'mouseleave'
|
|
});
|
|
}
|
|
if (isOpen && props.closeSubMenuOnMouseLeave) {
|
|
_this.triggerOpenChange(false);
|
|
}
|
|
}
|
|
}
|
|
// trigger mouseleave
|
|
props.onMouseLeave({
|
|
key: eventKey,
|
|
domEvent: e
|
|
});
|
|
};
|
|
// prevent popup menu and submenu gap
|
|
parentMenu.subMenuLeaveTimer = setTimeout(parentMenu.subMenuLeaveFn, 100);
|
|
},
|
|
onTitleMouseEnter: function onTitleMouseEnter(domEvent) {
|
|
var props = this.props;
|
|
var parentMenu = props.parentMenu,
|
|
key = props.eventKey;
|
|
|
|
var item = this;
|
|
this.clearSubMenuTitleLeaveTimer();
|
|
if (parentMenu.menuItemInstance) {
|
|
parentMenu.menuItemInstance.clearMenuItemMouseLeaveTimer();
|
|
}
|
|
var openChanges = [];
|
|
if (props.openSubMenuOnMouseEnter) {
|
|
openChanges.push({
|
|
key: key,
|
|
item: item,
|
|
trigger: 'mouseenter',
|
|
open: true
|
|
});
|
|
}
|
|
props.onItemHover({
|
|
key: key,
|
|
item: item,
|
|
hover: true,
|
|
trigger: 'mouseenter',
|
|
openChanges: openChanges
|
|
});
|
|
this.setState({
|
|
defaultActiveFirst: false
|
|
});
|
|
props.onTitleMouseEnter({
|
|
key: key,
|
|
domEvent: domEvent
|
|
});
|
|
},
|
|
onTitleMouseLeave: function onTitleMouseLeave(e) {
|
|
var _this2 = this;
|
|
|
|
var props = this.props;
|
|
var parentMenu = props.parentMenu,
|
|
eventKey = props.eventKey;
|
|
|
|
parentMenu.subMenuInstance = this;
|
|
parentMenu.subMenuTitleLeaveFn = function () {
|
|
// leave whole sub tree
|
|
// still active
|
|
if (props.mode === 'inline' && props.active) {
|
|
props.onItemHover({
|
|
key: eventKey,
|
|
item: _this2,
|
|
hover: false,
|
|
trigger: 'mouseleave'
|
|
});
|
|
}
|
|
props.onTitleMouseLeave({
|
|
key: props.eventKey,
|
|
domEvent: e
|
|
});
|
|
};
|
|
parentMenu.subMenuTitleLeaveTimer = setTimeout(parentMenu.subMenuTitleLeaveFn, 100);
|
|
},
|
|
onTitleClick: function onTitleClick(e) {
|
|
var props = this.props;
|
|
|
|
props.onTitleClick({
|
|
key: props.eventKey,
|
|
domEvent: e
|
|
});
|
|
if (props.openSubMenuOnMouseEnter) {
|
|
return;
|
|
}
|
|
this.triggerOpenChange(!this.isOpen(), 'click');
|
|
this.setState({
|
|
defaultActiveFirst: false
|
|
});
|
|
},
|
|
onSubMenuClick: function onSubMenuClick(info) {
|
|
this.props.onClick(this.addKeyPath(info));
|
|
},
|
|
onSelect: function onSelect(info) {
|
|
this.props.onSelect(info);
|
|
},
|
|
onDeselect: function onDeselect(info) {
|
|
this.props.onDeselect(info);
|
|
},
|
|
getPrefixCls: function getPrefixCls() {
|
|
return this.props.rootPrefixCls + '-submenu';
|
|
},
|
|
getActiveClassName: function getActiveClassName() {
|
|
return this.getPrefixCls() + '-active';
|
|
},
|
|
getDisabledClassName: function getDisabledClassName() {
|
|
return this.getPrefixCls() + '-disabled';
|
|
},
|
|
getSelectedClassName: function getSelectedClassName() {
|
|
return this.getPrefixCls() + '-selected';
|
|
},
|
|
getOpenClassName: function getOpenClassName() {
|
|
return this.props.rootPrefixCls + '-submenu-open';
|
|
},
|
|
saveMenuInstance: function saveMenuInstance(c) {
|
|
this.menuInstance = c;
|
|
},
|
|
addKeyPath: function addKeyPath(info) {
|
|
return (0, _extends3['default'])({}, info, {
|
|
keyPath: (info.keyPath || []).concat(this.props.eventKey)
|
|
});
|
|
},
|
|
triggerOpenChange: function triggerOpenChange(open, type) {
|
|
var key = this.props.eventKey;
|
|
this.onOpenChange({
|
|
key: key,
|
|
item: this,
|
|
trigger: type,
|
|
open: open
|
|
});
|
|
},
|
|
clearSubMenuTimers: function clearSubMenuTimers() {
|
|
this.clearSubMenuLeaveTimer();
|
|
this.clearSubMenuTitleLeaveTimer();
|
|
},
|
|
clearSubMenuTitleLeaveTimer: function clearSubMenuTitleLeaveTimer() {
|
|
var parentMenu = this.props.parentMenu;
|
|
if (parentMenu.subMenuTitleLeaveTimer) {
|
|
clearTimeout(parentMenu.subMenuTitleLeaveTimer);
|
|
parentMenu.subMenuTitleLeaveTimer = null;
|
|
parentMenu.subMenuTitleLeaveFn = null;
|
|
}
|
|
},
|
|
clearSubMenuLeaveTimer: function clearSubMenuLeaveTimer() {
|
|
var parentMenu = this.props.parentMenu;
|
|
if (parentMenu.subMenuLeaveTimer) {
|
|
clearTimeout(parentMenu.subMenuLeaveTimer);
|
|
parentMenu.subMenuLeaveTimer = null;
|
|
parentMenu.subMenuLeaveFn = null;
|
|
}
|
|
},
|
|
isChildrenSelected: function isChildrenSelected() {
|
|
var ret = { find: false };
|
|
(0, _util.loopMenuItemRecusively)(this.props.children, this.props.selectedKeys, ret);
|
|
return ret.find;
|
|
},
|
|
isOpen: function isOpen() {
|
|
return this.props.openKeys.indexOf(this.props.eventKey) !== -1;
|
|
},
|
|
renderChildren: function renderChildren(children) {
|
|
var props = this.props;
|
|
var baseProps = {
|
|
mode: props.mode === 'horizontal' ? 'vertical' : props.mode,
|
|
visible: this.isOpen(),
|
|
level: props.level + 1,
|
|
inlineIndent: props.inlineIndent,
|
|
focusable: false,
|
|
onClick: this.onSubMenuClick,
|
|
onSelect: this.onSelect,
|
|
onDeselect: this.onDeselect,
|
|
onDestroy: this.onDestroy,
|
|
selectedKeys: props.selectedKeys,
|
|
eventKey: props.eventKey + '-menu-',
|
|
openKeys: props.openKeys,
|
|
openTransitionName: props.openTransitionName,
|
|
openAnimation: props.openAnimation,
|
|
onOpenChange: this.onOpenChange,
|
|
closeSubMenuOnMouseLeave: props.closeSubMenuOnMouseLeave,
|
|
defaultActiveFirst: this.state.defaultActiveFirst,
|
|
multiple: props.multiple,
|
|
prefixCls: props.rootPrefixCls,
|
|
id: this._menuId,
|
|
ref: this.saveMenuInstance
|
|
};
|
|
return _react2['default'].createElement(
|
|
_SubPopupMenu2['default'],
|
|
baseProps,
|
|
children
|
|
);
|
|
},
|
|
render: function render() {
|
|
var _classes;
|
|
|
|
var isOpen = this.isOpen();
|
|
this.haveOpen = this.haveOpen || isOpen;
|
|
var props = this.props;
|
|
var prefixCls = this.getPrefixCls();
|
|
var classes = (_classes = {}, (0, _defineProperty3['default'])(_classes, props.className, !!props.className), (0, _defineProperty3['default'])(_classes, prefixCls + '-' + props.mode, 1), _classes);
|
|
|
|
classes[this.getOpenClassName()] = isOpen;
|
|
classes[this.getActiveClassName()] = props.active;
|
|
classes[this.getDisabledClassName()] = props.disabled;
|
|
classes[this.getSelectedClassName()] = this.isChildrenSelected();
|
|
|
|
if (!this._menuId) {
|
|
if (props.eventKey) {
|
|
this._menuId = props.eventKey + '$Menu';
|
|
} else {
|
|
this._menuId = '$__$' + ++guid + '$Menu';
|
|
}
|
|
}
|
|
|
|
classes[prefixCls] = true;
|
|
classes[prefixCls + '-' + props.mode] = 1;
|
|
var mouseEvents = {};
|
|
var titleClickEvents = {};
|
|
var titleMouseEvents = {};
|
|
if (!props.disabled) {
|
|
mouseEvents = {
|
|
onMouseLeave: this.onMouseLeave,
|
|
onMouseEnter: this.onMouseEnter
|
|
};
|
|
titleClickEvents = {
|
|
onClick: this.onTitleClick
|
|
};
|
|
// only works in title, not outer li
|
|
titleMouseEvents = {
|
|
onMouseEnter: this.onTitleMouseEnter,
|
|
onMouseLeave: this.onTitleMouseLeave
|
|
};
|
|
}
|
|
var style = {};
|
|
if (props.mode === 'inline') {
|
|
style.paddingLeft = props.inlineIndent * props.level;
|
|
}
|
|
return _react2['default'].createElement(
|
|
'li',
|
|
(0, _extends3['default'])({ className: (0, _classnames2['default'])(classes) }, mouseEvents, { style: props.style }),
|
|
_react2['default'].createElement(
|
|
'div',
|
|
(0, _extends3['default'])({
|
|
style: style,
|
|
className: prefixCls + '-title'
|
|
}, titleMouseEvents, titleClickEvents, {
|
|
'aria-expanded': isOpen,
|
|
'aria-owns': this._menuId,
|
|
'aria-haspopup': 'true',
|
|
title: typeof props.title === 'string' ? props.title : undefined
|
|
}),
|
|
props.title,
|
|
_react2['default'].createElement('i', { className: prefixCls + '-arrow' })
|
|
),
|
|
this.renderChildren(props.children)
|
|
);
|
|
}
|
|
});
|
|
|
|
SubMenu.isSubMenu = 1;
|
|
|
|
exports['default'] = SubMenu;
|
|
module.exports = exports['default']; |