357 lines
10 KiB
JavaScript
357 lines
10 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 _reactDom = require('react-dom');
|
|
|
|
var _reactDom2 = _interopRequireDefault(_reactDom);
|
|
|
|
var _KeyCode = require('rc-util/lib/KeyCode');
|
|
|
|
var _KeyCode2 = _interopRequireDefault(_KeyCode);
|
|
|
|
var _createChainedFunction = require('rc-util/lib/createChainedFunction');
|
|
|
|
var _createChainedFunction2 = _interopRequireDefault(_createChainedFunction);
|
|
|
|
var _classnames = require('classnames');
|
|
|
|
var _classnames2 = _interopRequireDefault(_classnames);
|
|
|
|
var _domScrollIntoView = require('dom-scroll-into-view');
|
|
|
|
var _domScrollIntoView2 = _interopRequireDefault(_domScrollIntoView);
|
|
|
|
var _util = require('./util');
|
|
|
|
var _DOMWrap = require('./DOMWrap');
|
|
|
|
var _DOMWrap2 = _interopRequireDefault(_DOMWrap);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
function allDisabled(arr) {
|
|
if (!arr.length) {
|
|
return true;
|
|
}
|
|
return arr.every(function (c) {
|
|
return !!c.props.disabled;
|
|
});
|
|
}
|
|
|
|
function getActiveKey(props, originalActiveKey) {
|
|
var activeKey = originalActiveKey;
|
|
var children = props.children,
|
|
eventKey = props.eventKey;
|
|
|
|
if (activeKey) {
|
|
var found = void 0;
|
|
(0, _util.loopMenuItem)(children, function (c, i) {
|
|
if (c && !c.props.disabled && activeKey === (0, _util.getKeyFromChildrenIndex)(c, eventKey, i)) {
|
|
found = true;
|
|
}
|
|
});
|
|
if (found) {
|
|
return activeKey;
|
|
}
|
|
}
|
|
activeKey = null;
|
|
if (props.defaultActiveFirst) {
|
|
(0, _util.loopMenuItem)(children, function (c, i) {
|
|
if (!activeKey && c && !c.props.disabled) {
|
|
activeKey = (0, _util.getKeyFromChildrenIndex)(c, eventKey, i);
|
|
}
|
|
});
|
|
return activeKey;
|
|
}
|
|
return activeKey;
|
|
}
|
|
|
|
function saveRef(index, subIndex, c) {
|
|
if (c) {
|
|
if (subIndex !== undefined) {
|
|
this.instanceArray[index] = this.instanceArray[index] || [];
|
|
this.instanceArray[index][subIndex] = c;
|
|
} else {
|
|
this.instanceArray[index] = c;
|
|
}
|
|
}
|
|
}
|
|
|
|
var MenuMixin = {
|
|
propTypes: {
|
|
focusable: _propTypes2['default'].bool,
|
|
multiple: _propTypes2['default'].bool,
|
|
style: _propTypes2['default'].object,
|
|
defaultActiveFirst: _propTypes2['default'].bool,
|
|
visible: _propTypes2['default'].bool,
|
|
activeKey: _propTypes2['default'].string,
|
|
selectedKeys: _propTypes2['default'].arrayOf(_propTypes2['default'].string),
|
|
defaultSelectedKeys: _propTypes2['default'].arrayOf(_propTypes2['default'].string),
|
|
defaultOpenKeys: _propTypes2['default'].arrayOf(_propTypes2['default'].string),
|
|
openKeys: _propTypes2['default'].arrayOf(_propTypes2['default'].string),
|
|
children: _propTypes2['default'].any
|
|
},
|
|
|
|
getDefaultProps: function getDefaultProps() {
|
|
return {
|
|
prefixCls: 'rc-menu',
|
|
className: '',
|
|
mode: 'vertical',
|
|
level: 1,
|
|
inlineIndent: 24,
|
|
visible: true,
|
|
focusable: true,
|
|
style: {}
|
|
};
|
|
},
|
|
getInitialState: function getInitialState() {
|
|
var props = this.props;
|
|
return {
|
|
activeKey: getActiveKey(props, props.activeKey)
|
|
};
|
|
},
|
|
componentWillReceiveProps: function componentWillReceiveProps(nextProps) {
|
|
var props = void 0;
|
|
if ('activeKey' in nextProps) {
|
|
props = {
|
|
activeKey: getActiveKey(nextProps, nextProps.activeKey)
|
|
};
|
|
} else {
|
|
var originalActiveKey = this.state.activeKey;
|
|
var activeKey = getActiveKey(nextProps, originalActiveKey);
|
|
// fix: this.setState(), parent.render(),
|
|
if (activeKey !== originalActiveKey) {
|
|
props = {
|
|
activeKey: activeKey
|
|
};
|
|
}
|
|
}
|
|
if (props) {
|
|
this.setState(props);
|
|
}
|
|
},
|
|
shouldComponentUpdate: function shouldComponentUpdate(nextProps) {
|
|
return this.props.visible || nextProps.visible;
|
|
},
|
|
componentWillMount: function componentWillMount() {
|
|
this.instanceArray = [];
|
|
},
|
|
|
|
|
|
// all keyboard events callbacks run from here at first
|
|
onKeyDown: function onKeyDown(e, callback) {
|
|
var _this = this;
|
|
|
|
var keyCode = e.keyCode;
|
|
var handled = void 0;
|
|
this.getFlatInstanceArray().forEach(function (obj) {
|
|
if (obj && obj.props.active) {
|
|
handled = obj.onKeyDown(e);
|
|
}
|
|
});
|
|
if (handled) {
|
|
return 1;
|
|
}
|
|
var activeItem = null;
|
|
if (keyCode === _KeyCode2['default'].UP || keyCode === _KeyCode2['default'].DOWN) {
|
|
activeItem = this.step(keyCode === _KeyCode2['default'].UP ? -1 : 1);
|
|
}
|
|
if (activeItem) {
|
|
e.preventDefault();
|
|
this.setState({
|
|
activeKey: activeItem.props.eventKey
|
|
}, function () {
|
|
(0, _domScrollIntoView2['default'])(_reactDom2['default'].findDOMNode(activeItem), _reactDom2['default'].findDOMNode(_this), {
|
|
onlyScrollIfNeeded: true
|
|
});
|
|
if (callback) {
|
|
callback(activeItem);
|
|
}
|
|
});
|
|
return 1;
|
|
} else if (activeItem === undefined) {
|
|
e.preventDefault();
|
|
this.setState({
|
|
activeKey: null
|
|
});
|
|
return 1;
|
|
}
|
|
},
|
|
getOpenChangesOnItemHover: function getOpenChangesOnItemHover(e) {
|
|
var mode = this.props.mode;
|
|
var key = e.key,
|
|
hover = e.hover,
|
|
trigger = e.trigger;
|
|
|
|
var activeKey = this.state.activeKey;
|
|
if (!trigger || hover || this.props.closeSubMenuOnMouseLeave || !e.item.isSubMenu || mode === 'inline') {
|
|
this.setState({
|
|
activeKey: hover ? key : null
|
|
});
|
|
} else {}
|
|
// keep active for sub menu for click active
|
|
// empty
|
|
|
|
// clear last open status
|
|
if (hover && mode !== 'inline') {
|
|
var activeItem = this.getFlatInstanceArray().filter(function (c) {
|
|
return c && c.props.eventKey === activeKey;
|
|
})[0];
|
|
if (activeItem && activeItem.isSubMenu && activeItem.props.eventKey !== key) {
|
|
return {
|
|
item: activeItem,
|
|
originalEvent: e,
|
|
key: activeItem.props.eventKey,
|
|
open: false
|
|
};
|
|
}
|
|
}
|
|
return [];
|
|
},
|
|
getFlatInstanceArray: function getFlatInstanceArray() {
|
|
var instanceArray = this.instanceArray;
|
|
var hasInnerArray = instanceArray.some(function (a) {
|
|
return Array.isArray(a);
|
|
});
|
|
if (hasInnerArray) {
|
|
instanceArray = [];
|
|
this.instanceArray.forEach(function (a) {
|
|
if (Array.isArray(a)) {
|
|
instanceArray.push.apply(instanceArray, a);
|
|
} else {
|
|
instanceArray.push(a);
|
|
}
|
|
});
|
|
this.instanceArray = instanceArray;
|
|
}
|
|
return instanceArray;
|
|
},
|
|
renderCommonMenuItem: function renderCommonMenuItem(child, i, subIndex, extraProps) {
|
|
var state = this.state;
|
|
var props = this.props;
|
|
var key = (0, _util.getKeyFromChildrenIndex)(child, props.eventKey, i);
|
|
var childProps = child.props;
|
|
var isActive = key === state.activeKey;
|
|
var newChildProps = (0, _extends3['default'])({
|
|
mode: props.mode,
|
|
level: props.level,
|
|
inlineIndent: props.inlineIndent,
|
|
renderMenuItem: this.renderMenuItem,
|
|
rootPrefixCls: props.prefixCls,
|
|
index: i,
|
|
parentMenu: this,
|
|
ref: childProps.disabled ? undefined : (0, _createChainedFunction2['default'])(child.ref, saveRef.bind(this, i, subIndex)),
|
|
eventKey: key,
|
|
closeSubMenuOnMouseLeave: props.closeSubMenuOnMouseLeave,
|
|
onItemHover: this.onItemHover,
|
|
active: !childProps.disabled && isActive,
|
|
multiple: props.multiple,
|
|
onClick: this.onClick,
|
|
openTransitionName: this.getOpenTransitionName(),
|
|
openAnimation: props.openAnimation,
|
|
onOpenChange: this.onOpenChange,
|
|
onDeselect: this.onDeselect,
|
|
onDestroy: this.onDestroy,
|
|
onSelect: this.onSelect
|
|
}, extraProps);
|
|
if (props.mode === 'inline') {
|
|
newChildProps.closeSubMenuOnMouseLeave = newChildProps.openSubMenuOnMouseEnter = false;
|
|
}
|
|
return _react2['default'].cloneElement(child, newChildProps);
|
|
},
|
|
renderRoot: function renderRoot(props) {
|
|
var _classes;
|
|
|
|
this.instanceArray = [];
|
|
var classes = (_classes = {}, (0, _defineProperty3['default'])(_classes, props.prefixCls, 1), (0, _defineProperty3['default'])(_classes, props.prefixCls + '-' + props.mode, 1), (0, _defineProperty3['default'])(_classes, props.className, !!props.className), _classes);
|
|
var domProps = {
|
|
className: (0, _classnames2['default'])(classes),
|
|
role: 'menu',
|
|
'aria-activedescendant': ''
|
|
};
|
|
if (props.id) {
|
|
domProps.id = props.id;
|
|
}
|
|
if (props.focusable) {
|
|
domProps.tabIndex = '0';
|
|
domProps.onKeyDown = this.onKeyDown;
|
|
}
|
|
return (
|
|
// ESLint is not smart enough to know that the type of `children` was checked.
|
|
/* eslint-disable */
|
|
_react2['default'].createElement(
|
|
_DOMWrap2['default'],
|
|
(0, _extends3['default'])({
|
|
style: props.style,
|
|
tag: 'ul',
|
|
hiddenClassName: props.prefixCls + '-hidden',
|
|
visible: props.visible
|
|
}, domProps),
|
|
_react2['default'].Children.map(props.children, this.renderMenuItem)
|
|
)
|
|
/*eslint-enable */
|
|
|
|
);
|
|
},
|
|
step: function step(direction) {
|
|
var children = this.getFlatInstanceArray();
|
|
var activeKey = this.state.activeKey;
|
|
var len = children.length;
|
|
if (!len) {
|
|
return null;
|
|
}
|
|
if (direction < 0) {
|
|
children = children.concat().reverse();
|
|
}
|
|
// find current activeIndex
|
|
var activeIndex = -1;
|
|
children.every(function (c, ci) {
|
|
if (c && c.props.eventKey === activeKey) {
|
|
activeIndex = ci;
|
|
return false;
|
|
}
|
|
return true;
|
|
});
|
|
if (!this.props.defaultActiveFirst && activeIndex !== -1) {
|
|
if (allDisabled(children.slice(activeIndex, len - 1))) {
|
|
return undefined;
|
|
}
|
|
}
|
|
var start = (activeIndex + 1) % len;
|
|
var i = start;
|
|
for (;;) {
|
|
var child = children[i];
|
|
if (!child || child.props.disabled) {
|
|
i = (i + 1 + len) % len;
|
|
// complete a loop
|
|
if (i === start) {
|
|
return null;
|
|
}
|
|
} else {
|
|
return child;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
exports['default'] = MenuMixin;
|
|
module.exports = exports['default']; |