UNPKG

10.7 kBJavaScriptView Raw
1import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
2import _extends from 'babel-runtime/helpers/extends';
3import _typeof from 'babel-runtime/helpers/typeof';
4import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
5import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
6import _inherits from 'babel-runtime/helpers/inherits';
7
8var _class, _temp;
9
10import React, { Component, Children, cloneElement } from 'react';
11import { findDOMNode } from 'react-dom';
12import PropTypes from 'prop-types';
13import cx from 'classnames';
14import Animate from '../../animate';
15import Icon from '../../icon';
16import { func, obj } from '../../util';
17import Item from './item';
18import SelectabelItem from './selectable-item';
19import PopupItem from './popup-item';
20import { getChildSelected } from './util';
21
22var Expand = Animate.Expand;
23var bindCtx = func.bindCtx;
24
25/**
26 * Menu.SubMenu
27 * @order 1
28 */
29
30var SubMenu = (_temp = _class = function (_Component) {
31 _inherits(SubMenu, _Component);
32
33 function SubMenu(props) {
34 _classCallCheck(this, SubMenu);
35
36 var _this = _possibleConstructorReturn(this, _Component.call(this, props));
37
38 bindCtx(_this, ['handleMouseEnter', 'handleMouseLeave', 'handleClick', 'handleOpen', 'afterLeave']);
39 return _this;
40 }
41
42 SubMenu.prototype.componentDidMount = function componentDidMount() {
43 this.itemNode = findDOMNode(this);
44 };
45
46 SubMenu.prototype.afterLeave = function afterLeave() {
47 var _props = this.props,
48 focused = _props.focused,
49 root = _props.root;
50 var focusable = root.props.focusable;
51
52 if (focusable && focused) {
53 this.itemNode.focus();
54 }
55 };
56
57 SubMenu.prototype.getOpen = function getOpen() {
58 var _props2 = this.props,
59 _key = _props2._key,
60 root = _props2.root;
61 var openKeys = root.state.openKeys;
62
63
64 return openKeys.indexOf(_key) > -1;
65 };
66
67 SubMenu.prototype.handleMouseEnter = function handleMouseEnter(e) {
68 this.handleOpen(true);
69
70 this.props.onMouseEnter && this.props.onMouseEnter(e);
71 };
72
73 SubMenu.prototype.handleMouseLeave = function handleMouseLeave(e) {
74 this.handleOpen(false);
75
76 this.props.onMouseLeave && this.props.onMouseLeave(e);
77 };
78
79 SubMenu.prototype.handleClick = function handleClick(e) {
80 var _props3 = this.props,
81 root = _props3.root,
82 selectable = _props3.selectable;
83 var selectMode = root.props.selectMode;
84
85 if (selectMode && selectable) {
86 e.stopPropagation();
87 }
88
89 var open = this.getOpen();
90 this.handleOpen(!open);
91 };
92
93 SubMenu.prototype.handleOpen = function handleOpen(open, triggerType, e) {
94 var _props4 = this.props,
95 _key = _props4._key,
96 root = _props4.root;
97
98 root.handleOpen(_key, open, triggerType, e);
99 };
100
101 SubMenu.prototype.passParentToChildren = function passParentToChildren(children) {
102 var _this2 = this;
103
104 var _props5 = this.props,
105 mode = _props5.mode,
106 root = _props5.root;
107
108
109 return Children.map(children, function (child) {
110 // to fix https://github.com/alibaba-fusion/next/issues/952
111 if (typeof child !== 'function' && (typeof child === 'undefined' ? 'undefined' : _typeof(child)) !== 'object') {
112 return child;
113 }
114
115 return cloneElement(child, {
116 parent: _this2,
117 parentMode: mode || root.props.mode
118 });
119 });
120 };
121
122 SubMenu.prototype.renderInline = function renderInline() {
123 var _cx, _cx2, _cx3, _cx4;
124
125 var _props6 = this.props,
126 _key = _props6._key,
127 level = _props6.level,
128 inlineLevel = _props6.inlineLevel,
129 root = _props6.root,
130 className = _props6.className,
131 selectableFromProps = _props6.selectable,
132 label = _props6.label,
133 children = _props6.children,
134 noIcon = _props6.noIcon,
135 subMenuContentClassName = _props6.subMenuContentClassName,
136 propsTriggerType = _props6.triggerType,
137 parentMode = _props6.parentMode;
138 var _root$props = root.props,
139 prefix = _root$props.prefix,
140 selectMode = _root$props.selectMode,
141 rootTriggerType = _root$props.triggerType,
142 inlineArrowDirection = _root$props.inlineArrowDirection,
143 expandAnimation = _root$props.expandAnimation,
144 rtl = _root$props.rtl;
145
146 var triggerType = propsTriggerType || rootTriggerType;
147 var open = this.getOpen();
148
149 var _root$state = root.state,
150 selectedKeys = _root$state.selectedKeys,
151 _k2n = _root$state._k2n;
152
153 var isChildSelected = getChildSelected({
154 _key: _key,
155 _k2n: _k2n,
156 selectMode: selectMode,
157 selectedKeys: selectedKeys
158 });
159
160 var others = obj.pickOthers(Object.keys(SubMenu.propTypes), this.props);
161
162 var liProps = {
163 className: cx((_cx = {}, _cx[prefix + 'menu-sub-menu-wrapper'] = true, _cx[className] = !!className, _cx))
164 };
165 var itemProps = {
166 'aria-expanded': open,
167 _key: _key,
168 level: level,
169 role: 'listitem',
170 inlineLevel: inlineLevel,
171 root: root,
172 type: 'submenu',
173 component: 'div',
174 parentMode: parentMode,
175 className: cx((_cx2 = {}, _cx2[prefix + 'opened'] = open, _cx2[prefix + 'child-selected'] = isChildSelected, _cx2))
176 };
177
178 if (typeof label === 'string') {
179 itemProps.title = label;
180 }
181
182 var arrorProps = {
183 type: inlineArrowDirection === 'right' ? 'arrow-right' : 'arrow-down',
184 className: cx((_cx3 = {}, _cx3[prefix + 'menu-icon-arrow'] = true, _cx3[prefix + 'menu-icon-arrow-down'] = inlineArrowDirection === 'down', _cx3[prefix + 'menu-icon-arrow-right'] = inlineArrowDirection === 'right', _cx3[prefix + 'open'] = open, _cx3))
185 };
186
187 var selectable = !!selectMode && selectableFromProps;
188 var NewItem = selectable ? SelectabelItem : Item;
189
190 if (triggerType === 'hover') {
191 liProps.onMouseEnter = this.handleMouseEnter;
192 liProps.onMouseLeave = this.handleMouseLeave;
193 } else if (selectable) {
194 arrorProps.onClick = this.handleClick;
195 } else {
196 itemProps.onClick = this.handleClick;
197 }
198
199 var newSubMenuContentClassName = cx((_cx4 = {}, _cx4[prefix + 'menu-sub-menu'] = true, _cx4[subMenuContentClassName] = !!subMenuContentClassName, _cx4));
200
201 var roleMenu = 'menu',
202 roleItem = 'menuitem';
203 if ('selectMode' in root.props) {
204 roleMenu = 'listbox';
205 roleItem = 'option';
206 }
207
208 var subMenu = open ? React.createElement(
209 'ul',
210 { role: roleMenu, dir: rtl ? 'rtl' : undefined, className: newSubMenuContentClassName },
211 this.passParentToChildren(children)
212 ) : null;
213
214 return React.createElement(
215 'li',
216 _extends({ role: roleItem }, others, liProps),
217 React.createElement(
218 NewItem,
219 itemProps,
220 React.createElement(
221 'span',
222 { className: prefix + 'menu-item-text' },
223 label
224 ),
225 noIcon ? null : React.createElement(Icon, arrorProps)
226 ),
227 expandAnimation ? React.createElement(
228 Expand,
229 { animationAppear: false, afterLeave: this.afterLeave },
230 subMenu
231 ) : subMenu
232 );
233 };
234
235 SubMenu.prototype.renderPopup = function renderPopup() {
236 var _cx5;
237
238 var _props7 = this.props,
239 children = _props7.children,
240 subMenuContentClassName = _props7.subMenuContentClassName,
241 noIcon = _props7.noIcon,
242 others = _objectWithoutProperties(_props7, ['children', 'subMenuContentClassName', 'noIcon']);
243
244 var root = this.props.root;
245 var _root$props2 = root.props,
246 prefix = _root$props2.prefix,
247 popupClassName = _root$props2.popupClassName,
248 popupStyle = _root$props2.popupStyle,
249 rtl = _root$props2.rtl;
250
251
252 var newClassName = cx((_cx5 = {}, _cx5[prefix + 'menu'] = true, _cx5[prefix + 'ver'] = true, _cx5[popupClassName] = !!popupClassName, _cx5[subMenuContentClassName] = !!subMenuContentClassName, _cx5));
253
254 others.rtl = rtl;
255
256 return React.createElement(
257 PopupItem,
258 _extends({}, others, { noIcon: noIcon, hasSubMenu: true }),
259 React.createElement(
260 'ul',
261 { role: 'menu', dir: rtl ? 'rtl' : undefined, className: newClassName, style: popupStyle },
262 this.passParentToChildren(children)
263 )
264 );
265 };
266
267 SubMenu.prototype.render = function render() {
268 var _props8 = this.props,
269 mode = _props8.mode,
270 root = _props8.root;
271
272 var newMode = mode || root.props.mode;
273
274 return newMode === 'popup' ? this.renderPopup() : this.renderInline();
275 };
276
277 return SubMenu;
278}(Component), _class.menuChildType = 'submenu', _class.propTypes = {
279 _key: PropTypes.string,
280 root: PropTypes.object,
281 level: PropTypes.number,
282 inlineLevel: PropTypes.number,
283 groupIndent: PropTypes.number,
284 /**
285 * 标签内容
286 */
287 label: PropTypes.node,
288 /**
289 * 是否可选,该属性仅在设置 Menu 组件 selectMode 属性后生效
290 */
291 selectable: PropTypes.bool,
292 /**
293 * 子菜单打开方式,如果设置会覆盖 Menu 上的同名属性
294 * @default Menu 的 mode 属性值
295 */
296 mode: PropTypes.oneOf(['inline', 'popup']),
297 /**
298 * 是否需要提示当前项可展开的 icon,默认是有的
299 */
300 noIcon: PropTypes.bool,
301 /**
302 * 菜单项或下一级子菜单
303 */
304 children: PropTypes.node,
305 onMouseEnter: PropTypes.func,
306 onMouseLeave: PropTypes.func,
307 subMenuContentClassName: PropTypes.string,
308 triggerType: PropTypes.oneOf(['click', 'hover']),
309 align: PropTypes.oneOf(['outside', 'follow']),
310 parentMode: PropTypes.oneOf(['inline', 'popup']),
311 parent: PropTypes.any
312}, _class.defaultProps = {
313 groupIndent: 0,
314 noIcon: false,
315 selectable: false
316}, _temp);
317SubMenu.displayName = 'SubMenu';
318export { SubMenu as default };
\No newline at end of file