UNPKG

36 kBJavaScriptView Raw
1'use strict';
2
3exports.__esModule = true;
4
5var _extends2 = require('babel-runtime/helpers/extends');
6
7var _extends3 = _interopRequireDefault(_extends2);
8
9var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
10
11var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
12
13var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
14
15var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
16
17var _inherits2 = require('babel-runtime/helpers/inherits');
18
19var _inherits3 = _interopRequireDefault(_inherits2);
20
21var _typeof2 = require('babel-runtime/helpers/typeof');
22
23var _typeof3 = _interopRequireDefault(_typeof2);
24
25var _class, _temp;
26
27var _react = require('react');
28
29var _react2 = _interopRequireDefault(_react);
30
31var _reactDom = require('react-dom');
32
33var _propTypes = require('prop-types');
34
35var _propTypes2 = _interopRequireDefault(_propTypes);
36
37var _classnames = require('classnames');
38
39var _classnames2 = _interopRequireDefault(_classnames);
40
41var _reactLifecyclesCompat = require('react-lifecycles-compat');
42
43var _subMenu = require('./sub-menu');
44
45var _subMenu2 = _interopRequireDefault(_subMenu);
46
47var _configProvider = require('../../config-provider');
48
49var _configProvider2 = _interopRequireDefault(_configProvider);
50
51var _util = require('../../util');
52
53var _util2 = require('./util');
54
55function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
56
57var bindCtx = _util.func.bindCtx;
58var pickOthers = _util.obj.pickOthers,
59 isNil = _util.obj.isNil;
60
61var noop = function noop() {};
62var MENUITEM_OVERFLOWED_CLASSNAME = 'menuitem-overflowed';
63
64var getIndicatorsItem = function getIndicatorsItem(items, isPlaceholder) {
65 var _cx;
66
67 var prefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
68 var renderMore = arguments[3];
69
70 var moreCls = (0, _classnames2.default)((_cx = {}, _cx[prefix + 'menu-more'] = true, _cx));
71
72 var style = {};
73 // keep placehold to get width
74 if (isPlaceholder) {
75 style.visibility = 'hidden';
76 style.display = 'inline-block';
77 // indicators which not in use, just display: none
78 } else if (items && items.length === 0) {
79 style.display = 'none';
80 style.visibility = 'unset';
81 }
82
83 if (renderMore && typeof renderMore === 'function') {
84 var moreNode = renderMore(items);
85 var renderMoreCls = (0, _classnames2.default)(moreCls, moreNode.props && moreNode.props.className);
86
87 return _react2.default.isValidElement(moreNode) ? _react2.default.cloneElement(moreNode, {
88 style: style,
89 className: renderMoreCls
90 }) : moreNode;
91 }
92
93 return _react2.default.createElement(
94 _subMenu2.default,
95 { label: '\xB7\xB7\xB7', noIcon: true, className: moreCls, style: style },
96 items
97 );
98};
99
100var addIndicators = function addIndicators(_ref) {
101 var children = _ref.children,
102 lastVisibleIndex = _ref.lastVisibleIndex,
103 prefix = _ref.prefix,
104 renderMore = _ref.renderMore;
105
106 var arr = [];
107
108 _react2.default.Children.forEach(children, function (child, index) {
109 if (!child) {
110 return;
111 }
112 var overflowedItems = [];
113
114 if (index > lastVisibleIndex) {
115 child = _react2.default.cloneElement(child, {
116 key: child.key || 'more-' + index,
117 style: { display: 'none' },
118 className: (child && child.className || '') + ' ' + MENUITEM_OVERFLOWED_CLASSNAME
119 });
120 }
121
122 if (index === lastVisibleIndex + 1) {
123 overflowedItems = children.slice(lastVisibleIndex + 1).map(function (c, i) {
124 return _react2.default.cloneElement(c, {
125 key: c.key || 'more-' + index + '-' + i
126 });
127 });
128 arr.push(getIndicatorsItem(overflowedItems, false, prefix, renderMore));
129 }
130
131 arr.push(child);
132 });
133
134 arr.push(getIndicatorsItem([], true, prefix, renderMore));
135
136 return arr;
137};
138
139var getNewChildren = function getNewChildren(_ref2) {
140 var children = _ref2.children,
141 root = _ref2.root,
142 mode = _ref2.mode,
143 lastVisibleIndex = _ref2.lastVisibleIndex,
144 hozInLine = _ref2.hozInLine,
145 prefix = _ref2.prefix,
146 renderMore = _ref2.renderMore;
147
148 var k2n = {};
149 var p2n = {};
150
151 var arr = hozInLine ? addIndicators({
152 children: children,
153 lastVisibleIndex: lastVisibleIndex,
154 prefix: prefix,
155 renderMore: renderMore
156 }) : children;
157
158 var loop = function loop(children, posPrefix) {
159 var indexWrapper = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { index: 0 };
160 var inlineLevel = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
161
162 var keyArray = [];
163 return _react.Children.map(children, function (child) {
164 if (child && (typeof child.type === 'function' ||
165 // `React.forwardRef(render)` returns a forwarding
166 // object that includes `render` method, and the specific
167 // `child.type` will be an object instead of a class or
168 // function.
169 (0, _typeof3.default)(child.type) === 'object') && 'menuChildType' in child.type) {
170 var newChild = void 0;
171
172 var pos = void 0;
173 var props = { root: root };
174
175 if (['item', 'submenu', 'group'].indexOf(child.type.menuChildType) > -1) {
176 pos = posPrefix + '-' + indexWrapper.index++;
177 var key = typeof child.key === 'string' ? child.key : pos;
178
179 // filter out duplicate keys
180 if (keyArray.indexOf(key) > -1) {
181 return;
182 }
183
184 keyArray.push(key);
185
186 var level = pos.split('-').length - 1;
187 k2n[key] = p2n[pos] = {
188 key: key,
189 pos: pos,
190 mode: child.props.mode,
191 type: child.type.menuChildType,
192 disabled: child.props.disabled,
193 label: child.props.label || child.props.children
194 };
195
196 props.level = level;
197 props.inlineLevel = inlineLevel;
198 props._key = key;
199 props.groupIndent = child.type.menuChildType === 'group' ? 1 : 0;
200 }
201
202 // paddingLeft(or paddingRight in rtl) only make sense in inline mode
203 // parent know children's inlineLevel
204 // if parent's mode is popup, then children's inlineLevel must be 1;
205 // else inlineLevel should add 1
206 var childLevel = (child.props.mode || mode) === 'popup' ? 1 : inlineLevel + 1;
207
208 switch (child.type.menuChildType) {
209 case 'submenu':
210 newChild = (0, _react.cloneElement)(child, props, loop(child.props.children, pos, undefined, childLevel));
211 break;
212 case 'group':
213 newChild = (0, _react.cloneElement)(child, props, loop(child.props.children, posPrefix, indexWrapper, props.level));
214 break;
215 case 'item':
216 case 'divider':
217 newChild = (0, _react.cloneElement)(child, props);
218 break;
219 default:
220 newChild = child;
221 break;
222 }
223
224 return newChild;
225 }
226
227 return child;
228 });
229 };
230
231 var newChildren = loop(arr, '0');
232
233 return {
234 newChildren: newChildren,
235 _k2n: k2n,
236 _p2n: p2n
237 };
238};
239
240/**
241 * Menu
242 */
243var Menu = (_temp = _class = function (_Component) {
244 (0, _inherits3.default)(Menu, _Component);
245
246 function Menu(props) {
247 (0, _classCallCheck3.default)(this, Menu);
248
249 var _this = (0, _possibleConstructorReturn3.default)(this, _Component.call(this, props));
250
251 _this.getUpdateChildren = function () {
252 var _this$state = _this.state,
253 root = _this$state.root,
254 lastVisibleIndex = _this$state.lastVisibleIndex;
255
256
257 return getNewChildren((0, _extends3.default)({
258 root: root,
259 lastVisibleIndex: lastVisibleIndex
260 }, _this.props));
261 };
262
263 _this.menuContentRef = function (ref) {
264 _this.menuContent = ref;
265 };
266
267 _this.menuHeaderRef = function (ref) {
268 _this.menuHeader = ref;
269 };
270
271 _this.menuFooterRef = function (ref) {
272 _this.menuFooter = ref;
273 };
274
275 var _this$props = _this.props,
276 prefix = _this$props.prefix,
277 children = _this$props.children,
278 selectedKeys = _this$props.selectedKeys,
279 defaultSelectedKeys = _this$props.defaultSelectedKeys,
280 focusedKey = _this$props.focusedKey,
281 focusable = _this$props.focusable,
282 autoFocus = _this$props.autoFocus,
283 hozInLine = _this$props.hozInLine,
284 renderMore = _this$props.renderMore;
285
286
287 _this.state = {
288 lastVisibleIndex: undefined
289 };
290
291 var _getNewChildren = getNewChildren((0, _extends3.default)({
292 root: _this
293 }, _this.props)),
294 newChildren = _getNewChildren.newChildren,
295 _k2n = _getNewChildren._k2n,
296 _p2n = _getNewChildren._p2n;
297
298 var tabbableKey = focusable ? (0, _util2.getFirstAvaliablelChildKey)('0', _p2n) : undefined;
299
300 _this.state = {
301 root: _this,
302 lastVisibleIndex: undefined,
303 newChildren: newChildren,
304 _k2n: _k2n,
305 _p2n: _p2n,
306 tabbableKey: tabbableKey,
307 openKeys: _this.getInitOpenKeys(props, _k2n, _p2n),
308 selectedKeys: (0, _util2.normalizeToArray)(selectedKeys || defaultSelectedKeys),
309 focusedKey: !isNil(_this.props.focusedKey) ? focusedKey : focusable && autoFocus ? tabbableKey : null
310 };
311
312 bindCtx(_this, ['handleOpen', 'handleSelect', 'handleItemClick', 'handleItemKeyDown', 'onBlur', 'adjustChildrenWidth']);
313
314 _this.popupNodes = [];
315 return _this;
316 }
317
318 Menu.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) {
319 var state = {};
320
321 if ('openKeys' in nextProps) {
322 state.openKeys = (0, _util2.normalizeToArray)(nextProps.openKeys);
323 // 从展开状态变为收起状态,才需要清空openKeys
324 } else if ('mode' in nextProps && nextProps.mode === 'popup' && prevState.lastMode === 'inline') {
325 state.openKeys = [];
326 }
327
328 if ('selectedKeys' in nextProps) {
329 state.selectedKeys = (0, _util2.normalizeToArray)(nextProps.selectedKeys);
330 }
331 if ('focusedKey' in nextProps) {
332 state.focusedKey = nextProps.focusedKey;
333 }
334
335 state.lastMode = nextProps.mode;
336
337 var _getNewChildren2 = getNewChildren((0, _extends3.default)({
338 root: prevState.root,
339 lastVisibleIndex: prevState.lastVisibleIndex
340 }, nextProps)),
341 newChildren = _getNewChildren2.newChildren,
342 _k2n = _getNewChildren2._k2n,
343 _p2n = _getNewChildren2._p2n;
344
345 state.newChildren = newChildren;
346 state._k2n = _k2n;
347 state._p2n = _p2n;
348
349 if (nextProps.focusable) {
350 if (prevState.tabbableKey in _k2n) {
351 if (prevState.focusedKey) {
352 state.tabbableKey = prevState.focusedKey;
353 }
354 } else {
355 state.tabbableKey = (0, _util2.getFirstAvaliablelChildKey)('0', _p2n);
356 }
357 }
358
359 return state;
360 };
361
362 Menu.prototype.componentDidMount = function componentDidMount() {
363 this.menuNode = (0, _reactDom.findDOMNode)(this);
364
365 this.adjustChildrenWidth();
366
367 if (this.props.hozInLine) {
368 _util.events.on(window, 'resize', this.adjustChildrenWidth);
369 }
370 };
371
372 Menu.prototype.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
373 if (prevState.lastVisibleIndex !== this.state.lastVisibleIndex) {
374 this.adjustChildrenWidth();
375 }
376 };
377
378 Menu.prototype.componentWillUnmount = function componentWillUnmount() {
379 _util.events.off(window, 'resize', this.adjustChildrenWidth);
380 };
381
382 Menu.prototype.adjustChildrenWidth = function adjustChildrenWidth() {
383 var _props = this.props,
384 direction = _props.direction,
385 prefix = _props.prefix,
386 header = _props.header,
387 footer = _props.footer,
388 hozInLine = _props.hozInLine;
389
390 if (direction !== 'hoz' || !hozInLine) {
391 return;
392 }
393
394 if (!this.menuNode && !this.menuContent) {
395 return;
396 }
397
398 var children = [],
399 spaceWidth = void 0;
400
401 if (header || footer) {
402 children = this.menuContent.children;
403 spaceWidth = (0, _util2.getWidth)(this.menuNode) - (0, _util2.getWidth)(this.menuHeader) - (0, _util2.getWidth)(this.menuFooter);
404 } else {
405 children = this.menuNode.children;
406 spaceWidth = (0, _util2.getWidth)(this.menuNode);
407 }
408
409 if (children.length < 2) {
410 return;
411 }
412
413 var currentSumWidth = 0,
414 lastVisibleIndex = -1;
415
416 var moreNode = '';
417
418 var menuItemNodes = [].slice.call(children).filter(function (node) {
419 if (node.className.split(' ').indexOf(prefix + 'menu-more') < 0) {
420 return true;
421 } else {
422 moreNode = node;
423 }
424 return false;
425 });
426
427 var overflowedItems = menuItemNodes.filter(function (c) {
428 return c.className.split(' ').indexOf(MENUITEM_OVERFLOWED_CLASSNAME) >= 0;
429 });
430
431 overflowedItems.forEach(function (c) {
432 _util.dom.setStyle(c, 'display', 'inline-block');
433 });
434
435 _util.dom.setStyle(moreNode, 'display', 'inline-block');
436 var moreWidth = (0, _util2.getWidth)(moreNode);
437
438 this.menuItemSizes = menuItemNodes.map(function (c) {
439 return (0, _util2.getWidth)(c);
440 });
441 var totalLen = this.menuItemSizes.length;
442
443 overflowedItems.forEach(function (c) {
444 _util.dom.setStyle(c, 'display', 'none');
445 });
446
447 this.menuItemSizes.forEach(function (liWidth, i) {
448 currentSumWidth += liWidth;
449 if (i >= totalLen - 1 && currentSumWidth <= spaceWidth || currentSumWidth + moreWidth <= spaceWidth) {
450 lastVisibleIndex++;
451 }
452 });
453
454 if (lastVisibleIndex >= totalLen - 1) {
455 _util.dom.setStyle(moreNode, 'display', 'none');
456 }
457
458 this.setState((0, _extends3.default)({
459 lastVisibleIndex: lastVisibleIndex
460 }, this.getUpdateChildren()));
461 };
462
463 Menu.prototype.onBlur = function onBlur(e) {
464 this.setState({
465 focusedKey: undefined
466 });
467
468 this.props.onBlur && this.props.onBlur(e);
469 };
470
471 Menu.prototype.getInitOpenKeys = function getInitOpenKeys(props, _k2n, _p2n) {
472 var initOpenKeys = void 0;
473
474 var openKeys = props.openKeys,
475 defaultOpenKeys = props.defaultOpenKeys,
476 defaultOpenAll = props.defaultOpenAll,
477 mode = props.mode,
478 openMode = props.openMode;
479
480 if (openKeys) {
481 initOpenKeys = openKeys;
482 } else if (defaultOpenAll && mode === 'inline' && openMode === 'multiple') {
483 initOpenKeys = Object.keys(_k2n).filter(function (key) {
484 return _k2n[key].type === 'submenu';
485 });
486 } else {
487 initOpenKeys = defaultOpenKeys;
488 }
489
490 return (0, _util2.normalizeToArray)(initOpenKeys);
491 };
492
493 Menu.prototype.handleOpen = function handleOpen(key, open, triggerType, e) {
494 var newOpenKeys = void 0;
495
496 var _props2 = this.props,
497 mode = _props2.mode,
498 openMode = _props2.openMode;
499 var _state = this.state,
500 openKeys = _state.openKeys,
501 _k2n = _state._k2n;
502
503 var index = openKeys.indexOf(key);
504 if (open && index === -1) {
505 if (mode === 'inline') {
506 if (openMode === 'single') {
507 newOpenKeys = openKeys.filter(function (k) {
508 return _k2n[k] && !(0, _util2.isSibling)(_k2n[key].pos, _k2n[k].pos);
509 });
510 newOpenKeys.push(key);
511 } else {
512 newOpenKeys = openKeys.concat(key);
513 }
514 } else {
515 newOpenKeys = openKeys.filter(function (k) {
516 return _k2n[k] && (0, _util2.isAncestor)(_k2n[key].pos, _k2n[k].pos);
517 });
518 newOpenKeys.push(key);
519 }
520 } else if (!open && index > -1) {
521 if (mode === 'inline') {
522 newOpenKeys = [].concat(openKeys.slice(0, index), openKeys.slice(index + 1));
523 } else if (triggerType === 'docClick') {
524 if (!this.popupNodes.concat(this.menuNode).some(function (node) {
525 return node.contains(e.target);
526 })) {
527 newOpenKeys = [];
528 }
529 } else {
530 newOpenKeys = openKeys.filter(function (k) {
531 return k !== key && _k2n[k] && !(0, _util2.isAncestor)(_k2n[k].pos, _k2n[key].pos);
532 });
533 }
534 }
535
536 if (newOpenKeys) {
537 if (isNil(this.props.openKeys)) {
538 this.setState((0, _extends3.default)({
539 openKeys: newOpenKeys
540 }, this.getUpdateChildren()));
541 }
542
543 this.props.onOpen(newOpenKeys, {
544 key: key,
545 open: open
546 });
547 }
548 };
549
550 Menu.prototype.getPath = function getPath(key, _k2n, _p2n) {
551 var keyPath = [];
552 var labelPath = [];
553
554 var pos = _k2n[key].pos;
555 var nums = pos.split('-');
556 for (var i = 1; i < nums.length - 1; i++) {
557 var parentNums = nums.slice(0, i + 1);
558 var parentPos = parentNums.join('-');
559 var parent = _p2n[parentPos];
560 keyPath.push(parent.key);
561 labelPath.push(parent.label);
562 }
563
564 return {
565 keyPath: keyPath,
566 labelPath: labelPath
567 };
568 };
569
570 Menu.prototype.handleSelect = function handleSelect(key, select, menuItem) {
571 var _state2 = this.state,
572 _k2n = _state2._k2n,
573 _p2n = _state2._p2n;
574
575 var pos = _k2n[key].pos;
576 var level = pos.split('-').length - 1;
577 if (this.props.shallowSelect && level > 1) {
578 return;
579 }
580
581 var newSelectedKeys = void 0;
582
583 var selectMode = this.props.selectMode;
584 var selectedKeys = this.state.selectedKeys;
585
586 var index = selectedKeys.indexOf(key);
587 if (select && index === -1) {
588 if (selectMode === 'single') {
589 newSelectedKeys = [key];
590 } else if (selectMode === 'multiple') {
591 newSelectedKeys = selectedKeys.concat(key);
592 }
593 } else if (!select && index > -1 && selectMode === 'multiple') {
594 newSelectedKeys = [].concat(selectedKeys.slice(0, index), selectedKeys.slice(index + 1));
595 }
596
597 if (newSelectedKeys) {
598 if (isNil(this.props.selectedKeys)) {
599 this.setState({
600 selectedKeys: newSelectedKeys
601 });
602 }
603
604 this.props.onSelect(newSelectedKeys, menuItem, (0, _extends3.default)({
605 key: key,
606 select: select,
607 label: _k2n[key].label
608 }, this.getPath(key, _k2n, _p2n)));
609 }
610 };
611
612 Menu.prototype.handleItemClick = function handleItemClick(key, item, e) {
613 var _k2n = this.state._k2n;
614
615 if (this.props.focusable) {
616 if (isNil(this.props.focusedKey)) {
617 this.setState({
618 focusedKey: key
619 });
620 }
621
622 this.props.onItemFocus(key, item, e);
623 }
624
625 if (item.props.type === 'item') {
626 if (item.props.parentMode === 'popup' && this.state.openKeys.length) {
627 if (isNil(this.props.openKeys)) {
628 this.setState({
629 openKeys: []
630 });
631 }
632
633 this.props.onOpen([], {
634 key: this.state.openKeys.sort(function (prevKey, nextKey) {
635 return _k2n[nextKey].pos.split('-').length - _k2n[prevKey].pos.split('-').length;
636 })[0],
637 open: false
638 });
639 }
640
641 this.props.onItemClick(key, item, e);
642 }
643 };
644
645 Menu.prototype.getAvailableKey = function getAvailableKey(pos, prev) {
646 var _p2n = this.state._p2n;
647
648 var ps = Object.keys(_p2n).filter(function (p) {
649 return (0, _util2.isAvailablePos)(pos, p, _p2n);
650 });
651 if (ps.length > 1) {
652 var index = ps.indexOf(pos);
653 var targetIndex = void 0;
654 if (prev) {
655 targetIndex = index === 0 ? ps.length - 1 : index - 1;
656 } else {
657 targetIndex = index === ps.length - 1 ? 0 : index + 1;
658 }
659
660 return _p2n[ps[targetIndex]].key;
661 }
662
663 return null;
664 };
665
666 Menu.prototype.getParentKey = function getParentKey(pos) {
667 return this.state._p2n[pos.slice(0, pos.length - 2)].key;
668 };
669
670 Menu.prototype.handleItemKeyDown = function handleItemKeyDown(key, type, item, e) {
671 if ([_util.KEYCODE.UP, _util.KEYCODE.DOWN, _util.KEYCODE.RIGHT, _util.KEYCODE.LEFT, _util.KEYCODE.ENTER, _util.KEYCODE.ESC, _util.KEYCODE.SPACE].indexOf(e.keyCode) > -1) {
672 e.preventDefault();
673 e.stopPropagation();
674 }
675
676 var focusedKey = this.state.focusedKey;
677 var _state3 = this.state,
678 _p2n = _state3._p2n,
679 _k2n = _state3._k2n;
680 var direction = this.props.direction;
681
682 var pos = _k2n[key].pos;
683 var level = pos.split('-').length - 1;
684 switch (e.keyCode) {
685 case _util.KEYCODE.UP:
686 {
687 var avaliableKey = this.getAvailableKey(pos, true);
688 if (avaliableKey) {
689 focusedKey = avaliableKey;
690 }
691 break;
692 }
693 case _util.KEYCODE.DOWN:
694 {
695 var _avaliableKey = void 0;
696 if (direction === 'hoz' && level === 1 && type === 'submenu') {
697 this.handleOpen(key, true);
698 _avaliableKey = (0, _util2.getFirstAvaliablelChildKey)(pos, _p2n);
699 } else {
700 _avaliableKey = this.getAvailableKey(pos, false);
701 }
702 if (_avaliableKey) {
703 focusedKey = _avaliableKey;
704 }
705 break;
706 }
707 case _util.KEYCODE.RIGHT:
708 {
709 var _avaliableKey2 = void 0;
710 if (direction === 'hoz' && level === 1) {
711 _avaliableKey2 = this.getAvailableKey(pos, false);
712 } else if (type === 'submenu') {
713 this.handleOpen(key, true);
714 _avaliableKey2 = (0, _util2.getFirstAvaliablelChildKey)(pos, _p2n);
715 }
716 if (_avaliableKey2) {
717 focusedKey = _avaliableKey2;
718 }
719 break;
720 }
721 case _util.KEYCODE.ENTER:
722 {
723 if (type === 'submenu') {
724 this.handleOpen(key, true);
725 var _avaliableKey3 = (0, _util2.getFirstAvaliablelChildKey)(pos, _p2n);
726 if (_avaliableKey3) {
727 focusedKey = _avaliableKey3;
728 }
729 }
730 break;
731 }
732 case _util.KEYCODE.LEFT:
733 {
734 if (direction === 'hoz' && level === 1) {
735 var _avaliableKey4 = this.getAvailableKey(pos, true);
736 if (_avaliableKey4) {
737 focusedKey = _avaliableKey4;
738 }
739 } else if (level > 1) {
740 var parentKey = this.getParentKey(pos);
741 this.handleOpen(parentKey, false);
742 focusedKey = parentKey;
743 }
744 break;
745 }
746 case _util.KEYCODE.ESC:
747 if (level > 1) {
748 var _parentKey = this.getParentKey(pos);
749 this.handleOpen(_parentKey, false);
750 focusedKey = _parentKey;
751 }
752 break;
753
754 case _util.KEYCODE.TAB:
755 focusedKey = null;
756 break;
757 default:
758 break;
759 }
760
761 if (focusedKey !== this.state.focusedKey) {
762 if (isNil(this.props.focusedKey)) {
763 this.setState({
764 focusedKey: focusedKey
765 });
766 }
767
768 this.props.onItemKeyDown(focusedKey, item, e);
769 this.props.onItemFocus(focusedKey, e);
770 }
771 };
772
773 Menu.prototype.render = function render() {
774 var _cx2;
775
776 var _props3 = this.props,
777 prefix = _props3.prefix,
778 className = _props3.className,
779 direction = _props3.direction,
780 hozAlign = _props3.hozAlign,
781 header = _props3.header,
782 footer = _props3.footer,
783 embeddable = _props3.embeddable,
784 selectMode = _props3.selectMode,
785 hozInLine = _props3.hozInLine,
786 rtl = _props3.rtl,
787 flatenContent = _props3.flatenContent;
788 var newChildren = this.state.newChildren;
789
790 var others = pickOthers(Object.keys(Menu.propTypes), this.props);
791
792 var newClassName = (0, _classnames2.default)((_cx2 = {}, _cx2[prefix + 'menu'] = true, _cx2[prefix + 'ver'] = direction === 'ver', _cx2[prefix + 'hoz'] = direction === 'hoz', _cx2[prefix + 'menu-embeddable'] = embeddable, _cx2[prefix + 'menu-nowrap'] = hozInLine, _cx2[prefix + 'menu-selectable-' + selectMode] = selectMode, _cx2[className] = !!className, _cx2));
793
794 var role = direction === 'hoz' ? 'menubar' : 'menu';
795 var ariaMultiselectable = void 0;
796 if ('selectMode' in this.props) {
797 role = 'listbox';
798 ariaMultiselectable = !!(selectMode === 'multiple');
799 }
800
801 var headerElement = header ? _react2.default.createElement(
802 'li',
803 { className: prefix + 'menu-header', ref: this.menuHeaderRef },
804 header
805 ) : null;
806 var itemsElement = !flatenContent && (header || footer) ? _react2.default.createElement(
807 'ul',
808 { className: prefix + 'menu-content', ref: this.menuContentRef },
809 newChildren
810 ) : newChildren;
811 var footerElement = footer ? _react2.default.createElement(
812 'li',
813 { className: prefix + 'menu-footer', ref: this.menuFooterRef },
814 footer
815 ) : null;
816 var shouldWrapItemsAndFooter = hozAlign === 'right' && !!header;
817
818 if (rtl) {
819 others.dir = 'rtl';
820 }
821
822 return _react2.default.createElement(
823 'ul',
824 (0, _extends3.default)({
825 role: role,
826 onBlur: this.onBlur,
827 className: newClassName,
828 onKeyDown: this.handleEnter,
829 'aria-multiselectable': ariaMultiselectable
830 }, others),
831 headerElement,
832 shouldWrapItemsAndFooter ? _react2.default.createElement(
833 'div',
834 { className: prefix + 'menu-hoz-right' },
835 itemsElement,
836 footerElement
837 ) : null,
838 !shouldWrapItemsAndFooter ? itemsElement : null,
839 !shouldWrapItemsAndFooter ? footerElement : null
840 );
841 };
842
843 return Menu;
844}(_react.Component), _class.isNextMenu = true, _class.propTypes = (0, _extends3.default)({}, _configProvider2.default.propTypes, {
845 prefix: _propTypes2.default.string,
846 pure: _propTypes2.default.bool,
847 rtl: _propTypes2.default.bool,
848 className: _propTypes2.default.string,
849 /**
850 * 菜单项和子菜单
851 */
852 children: _propTypes2.default.node,
853 /**
854 * 点击菜单项触发的回调函数
855 * @param {String} key 点击的菜单项的 key 值
856 * @param {Object} item 点击的菜单项对象
857 * @param {Object} event 点击的事件对象
858 */
859 onItemClick: _propTypes2.default.func,
860 /**
861 * 当前打开的子菜单的 key 值
862 */
863 openKeys: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.array]),
864 /**
865 * 初始打开的子菜单的 key 值
866 */
867 defaultOpenKeys: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.array]),
868 /**
869 * 初始展开所有的子菜单,只在 mode 设置为 'inline' 以及 openMode 设置为 'multiple' 下生效,优先级高于 defaultOpenKeys
870 */
871 defaultOpenAll: _propTypes2.default.bool,
872 /**
873 * 打开或关闭子菜单触发的回调函数
874 * @param {Array} key 打开的所有子菜单的 key 值
875 * @param {Object} extra 额外参数
876 * @param {String} extra.key 当前操作子菜单的 key 值
877 * @param {Boolean} extra.open 是否是打开
878 */
879 onOpen: _propTypes2.default.func,
880 /**
881 * 子菜单打开的模式
882 */
883 mode: _propTypes2.default.oneOf(['inline', 'popup']),
884 /**
885 * 子菜单打开的触发行为
886 */
887 triggerType: _propTypes2.default.oneOf(['click', 'hover']),
888 /**
889 * 展开内连子菜单的模式,同时可以展开一个子菜单还是多个子菜单,该属性仅在 mode 为 inline 时生效
890 */
891 openMode: _propTypes2.default.oneOf(['single', 'multiple']),
892 /**
893 * 内连子菜单缩进距离
894 */
895 inlineIndent: _propTypes2.default.number,
896 inlineArrowDirection: _propTypes2.default.oneOf(['down', 'right']),
897 /**
898 * 是否自动让弹层的宽度和菜单项保持一致,如果弹层的宽度比菜单项小则和菜单项保持一致,如果宽度大于菜单项则不做处理
899 */
900 popupAutoWidth: _propTypes2.default.bool,
901 /**
902 * 弹层的对齐方式
903 */
904 popupAlign: _propTypes2.default.oneOf(['follow', 'outside']),
905 /**
906 * 弹层自定义 props
907 */
908 popupProps: _propTypes2.default.oneOfType([_propTypes2.default.object, _propTypes2.default.func]),
909 /**
910 * 弹出子菜单自定义 className
911 */
912 popupClassName: _propTypes2.default.string,
913 /**
914 * 弹出子菜单自定义 style
915 */
916 popupStyle: _propTypes2.default.object,
917 /**
918 * 当前选中菜单项的 key 值
919 */
920 selectedKeys: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.array]),
921 /**
922 * 初始选中菜单项的 key 值
923 */
924 defaultSelectedKeys: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.array]),
925 /**
926 * 选中或取消选中菜单项触发的回调函数
927 * @param {Array} selectedKeys 选中的所有菜单项的值
928 * @param {Object} item 选中或取消选中的菜单项
929 * @param {Object} extra 额外参数
930 * @param {Boolean} extra.select 是否是选中
931 * @param {Array} extra.key 菜单项的 key
932 * @param {Object} extra.label 菜单项的文本
933 * @param {Array} extra.keyPath 菜单项 key 的路径
934 */
935 onSelect: _propTypes2.default.func,
936 /**
937 * 选中模式,单选还是多选,默认无值,不可选
938 */
939 selectMode: _propTypes2.default.oneOf(['single', 'multiple']),
940 /**
941 * 是否只能选择第一层菜单项(不能选择子菜单中的菜单项)
942 */
943 shallowSelect: _propTypes2.default.bool,
944 /**
945 * 是否显示选中图标,如果设置为 false 需配合配置平台设置选中时的背景色以示区分
946 */
947 hasSelectedIcon: _propTypes2.default.bool,
948 labelToggleChecked: _propTypes2.default.bool,
949 /**
950 * 是否将选中图标居右,仅当 hasSelectedIcon 为true 时生效。
951 * 注意:SubMenu 上的选中图标一直居左,不受此API控制
952 */
953 isSelectIconRight: _propTypes2.default.bool,
954 /**
955 * 菜单第一层展示方向
956 */
957 direction: _propTypes2.default.oneOf(['ver', 'hoz']),
958 /**
959 * 横向菜单条 item 和 footer 的对齐方向,在 direction 设置为 'hoz' 并且 header 存在时生效
960 */
961 hozAlign: _propTypes2.default.oneOf(['left', 'right']),
962 /**
963 * 横向菜单模式下,是否维持在一行,即超出一行折叠成 SubMenu 显示, 仅在 direction='hoz' mode='popup' 时生效
964 */
965 hozInLine: _propTypes2.default.bool,
966 renderMore: _propTypes2.default.func,
967 /**
968 * 自定义菜单头部
969 */
970 header: _propTypes2.default.node,
971 /**
972 * 自定义菜单尾部
973 */
974 footer: _propTypes2.default.node,
975 /**
976 * 是否自动获得焦点
977 */
978 autoFocus: _propTypes2.default.bool,
979 /**
980 * 当前获得焦点的子菜单或菜单项 key 值
981 */
982 focusedKey: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number, _propTypes2.default.object]),
983 focusable: _propTypes2.default.bool,
984 onItemFocus: _propTypes2.default.func,
985 onBlur: _propTypes2.default.func,
986 /**
987 * 是否开启嵌入式模式,一般用于Layout的布局中,开启后没有默认背景、外层border、box-shadow,可以配合`<Menu style={{lineHeight: '100px'}}>` 自定义高度
988 * @version 1.18
989 */
990 embeddable: _propTypes2.default.bool,
991 onItemKeyDown: _propTypes2.default.func,
992 expandAnimation: _propTypes2.default.bool,
993 itemClassName: _propTypes2.default.string,
994 /**
995 * 可配置的icons,包括 select 等
996 */
997 icons: _propTypes2.default.object,
998 // content 是否为单层模式,目前主要在有 header 或 footer 的时候有意义
999 flatenContent: _propTypes2.default.bool
1000}), _class.defaultProps = {
1001 prefix: 'next-',
1002 pure: false,
1003 defaultOpenKeys: [],
1004 defaultOpenAll: false,
1005 onOpen: noop,
1006 mode: 'inline',
1007 triggerType: 'click',
1008 openMode: 'multiple',
1009 inlineIndent: 20,
1010 inlineArrowDirection: 'down',
1011 popupAutoWidth: false,
1012 popupAlign: 'follow',
1013 popupProps: {},
1014 defaultSelectedKeys: [],
1015 onSelect: noop,
1016 shallowSelect: false,
1017 hasSelectedIcon: true,
1018 isSelectIconRight: false,
1019 labelToggleChecked: true,
1020 direction: 'ver',
1021 hozAlign: 'left',
1022 hozInLine: false,
1023 autoFocus: false,
1024 focusable: true,
1025 embeddable: false,
1026 onItemFocus: noop,
1027 onItemKeyDown: noop,
1028 onItemClick: noop,
1029 expandAnimation: true,
1030 icons: {}
1031}, _temp);
1032Menu.displayName = 'Menu';
1033exports.default = (0, _reactLifecyclesCompat.polyfill)(Menu);
1034module.exports = exports['default'];
\No newline at end of file