yqcloud-ui
Version:
An enterprise-class UI design language and React-based implementation
339 lines (301 loc) • 10.5 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getActiveKey = getActiveKey;
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('../util/KeyCode');
var _KeyCode2 = _interopRequireDefault(_KeyCode);
var _createChainedFunction = require('../util/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 updateActiveKey(store, menuId, activeKey) {
var state = store.getState();
store.setState({
activeKey: (0, _extends3['default'])({}, state.activeKey, (0, _defineProperty3['default'])({}, menuId, activeKey))
});
}
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) {
var array = this.instanceArray[index];
if (!array || !(array instanceof Array)) {
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: {}
};
},
componentWillReceiveProps: function componentWillReceiveProps(nextProps) {
if (nextProps.children) {
this.instanceArray = this.instanceArray.slice(0, nextProps.children.length);
}
var activeKey = void 0;
var originalActiveKey = this.getStore().getState().activeKey[this.getEventKey()];
activeKey = getActiveKey(nextProps, originalActiveKey);
// fix: this.setState(), parent.render(),
if (activeKey !== originalActiveKey) {
updateActiveKey(this.getStore(), this.getEventKey(), activeKey);
}
},
shouldComponentUpdate: function shouldComponentUpdate(nextProps) {
return this.props.visible || nextProps.visible;
},
componentDidUpdate: function componentDidUpdate() {
if (this.activeItem && this.activeItem.__isMounted !== false) {
(0, _domScrollIntoView2['default'])(_reactDom2['default'].findDOMNode(this.activeItem), _reactDom2['default'].findDOMNode(this), {
onlyScrollIfNeeded: true
});
this.activeItem = undefined;
}
},
componentWillMount: function componentWillMount() {
this.instanceArray = [];
},
// all keyboard events callbacks run from here at first
onKeyDown: function onKeyDown(e, callback) {
var keyCode = e.keyCode;
var handled = void 0;
this.getFlatInstanceArray().forEach(function (obj) {
if (obj && obj.props.active && obj.onKeyDown) {
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();
updateActiveKey(this.getStore(), this.getEventKey(), activeItem.props.eventKey);
this.activeItem = activeItem;
if (typeof callback === 'function') {
callback(activeItem);
}
return 1;
} else if (activeItem === undefined) {
e.preventDefault();
updateActiveKey(this.getStore(), this.getEventKey(), null);
return 1;
}
},
onItemHover: function onItemHover(e) {
var key = e.key,
hover = e.hover;
updateActiveKey(this.getStore(), this.getEventKey(), hover ? key : null);
},
getEventKey: function getEventKey() {
// when eventKey not available ,it's menu and return menu id '0-menu-'
return this.props.eventKey || '0-menu-';
},
getStore: function getStore() {
var store = this.store || this.props.store;
return store;
},
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.getStore().getState();
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,
// customized ref function, need to be invoked manually in child's componentDidMount
manualRef: childProps.disabled ? undefined : (0, _createChainedFunction2['default'])(child.ref, saveRef.bind(this, i, subIndex)),
eventKey: key,
active: !childProps.disabled && isActive,
multiple: props.multiple,
onClick: this.onClick,
onItemHover: this.onItemHover,
openTransitionName: this.getOpenTransitionName(),
openAnimation: props.openAnimation,
subMenuOpenDelay: props.subMenuOpenDelay,
subMenuCloseDelay: props.subMenuCloseDelay,
forceSubMenuRender: props.forceSubMenuRender,
onOpenChange: this.onOpenChange,
onDeselect: this.onDeselect,
onSelect: this.onSelect
}, extraProps);
if (props.mode === 'inline') {
newChildProps.triggerSubMenuAction = 'click';
}
return _react2['default'].cloneElement(child, newChildProps);
},
renderRoot: function renderRoot(props) {
var _this = this;
var className = (0, _classnames2['default'])(props.prefixCls, props.className, props.prefixCls + '-' + props.mode);
var domProps = {
className: className,
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, {
virtualizedOptions: props.virtualizedOptions,
virtualized: props.virtualized
}), _react2['default'].Children.map(props.children, function (c, i, subIndex) {
return _this.renderMenuItem(c, i, subIndex, props.eventKey || '0-menu-');
}))
/*eslint-enable */
);
},
step: function step(direction) {
var children = this.getFlatInstanceArray();
var activeKey = this.getStore().getState().activeKey[this.getEventKey()];
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;