import React, { Component, Children, cloneElement } from 'react';
import { findDOMNode } from 'react-dom';
import PropTypes from 'prop-types';
import cx from 'classnames';
import SubMenu from './sub-menu';
import ConfigProvider from '../../config-provider';
import { func, obj, dom, events, KEYCODE } from '../../util';
import { getWidth } from './util';
const { bindCtx } = func;
const { pickOthers, isNil } = obj;
const noop = () => {};
const MENUITEM_OVERFLOWED_CLASSNAME = 'menuitem-overflowed';
/**
* Menu
*/
export default class Menu extends Component {
static isNextMenu = true;
static propTypes = {
...ConfigProvider.propTypes,
prefix: PropTypes.string,
pure: PropTypes.bool,
rtl: PropTypes.bool,
className: PropTypes.string,
/**
* 菜单项和子菜单
*/
children: PropTypes.node,
/**
* 点击菜单项触发的回调函数
* @param {String} key 点击的菜单项的 key 值
* @param {Object} item 点击的菜单项对象
* @param {Object} event 点击的事件对象
*/
onItemClick: PropTypes.func,
/**
* 当前打开的子菜单的 key 值
*/
openKeys: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
/**
* 初始打开的子菜单的 key 值
*/
defaultOpenKeys: PropTypes.oneOfType([
PropTypes.string,
PropTypes.array,
]),
/**
* 初始展开所有的子菜单,只在 mode 设置为 'inline' 以及 openMode 设置为 'multiple' 下生效,优先级高于 defaultOpenKeys
*/
defaultOpenAll: PropTypes.bool,
/**
* 打开或关闭子菜单触发的回调函数
* @param {String} key 打开的所有子菜单的 key 值
* @param {Object} extra 额外参数
* @param {String} extra.key 当前操作子菜单的 key 值
* @param {Boolean} extra.open 是否是打开
*/
onOpen: PropTypes.func,
/**
* 子菜单打开的模式
*/
mode: PropTypes.oneOf(['inline', 'popup']),
/**
* 子菜单打开的触发行为
*/
triggerType: PropTypes.oneOf(['click', 'hover']),
/**
* 展开内连子菜单的模式,同时可以展开一个子菜单还是多个子菜单,该属性仅在 mode 为 inline 时生效
*/
openMode: PropTypes.oneOf(['single', 'multiple']),
/**
* 内连子菜单缩进距离
*/
inlineIndent: PropTypes.number,
inlineArrowDirection: PropTypes.oneOf(['down', 'right']),
/**
* 是否自动让弹层的宽度和菜单项保持一致,如果弹层的宽度比菜单项小则和菜单项保持一致,如果宽度大于菜单项则不做处理
*/
popupAutoWidth: PropTypes.bool,
/**
* 弹层的对齐方式
*/
popupAlign: PropTypes.oneOf(['follow', 'outside']),
/**
* 弹层自定义 props
*/
popupProps: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
/**
* 弹出子菜单自定义 className
*/
popupClassName: PropTypes.string,
/**
* 弹出子菜单自定义 style
*/
popupStyle: PropTypes.object,
/**
* 当前选中菜单项的 key 值
*/
selectedKeys: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
/**
* 初始选中菜单项的 key 值
*/
defaultSelectedKeys: PropTypes.oneOfType([
PropTypes.string,
PropTypes.array,
]),
/**
* 选中或取消选中菜单项触发的回调函数
* @param {Array} selectedKeys 选中的所有菜单项的值
* @param {Object} item 选中或取消选中的菜单项
* @param {Object} extra 额外参数
* @param {Boolean} extra.select 是否是选中
* @param {Array} extra.key 菜单项的 key
* @param {Object} extra.label 菜单项的文本
* @param {Array} extra.keyPath 菜单项 key 的路径
*/
onSelect: PropTypes.func,
/**
* 选中模式,单选还是多选,默认无值,不可选
*/
selectMode: PropTypes.oneOf(['single', 'multiple']),
/**
* 是否只能选择第一层菜单项(不能选择子菜单中的菜单项)
*/
shallowSelect: PropTypes.bool,
/**
* 是否显示选中图标,如果设置为 false 需配合配置平台设置选中时的背景色以示区分
*/
hasSelectedIcon: PropTypes.bool,
labelToggleChecked: PropTypes.bool,
/**
* 是否将选中图标居右,仅当 hasSelectedIcon 为true 时生效。
* 注意:SubMenu 上的选中图标一直居左,不受此API控制
*/
isSelectIconRight: PropTypes.bool,
/**
* 菜单第一层展示方向
*/
direction: PropTypes.oneOf(['ver', 'hoz']),
/**
* 横向菜单条 item 和 footer 的对齐方向,在 direction 设置为 'hoz' 并且 header 存在时生效
*/
hozAlign: PropTypes.oneOf(['left', 'right']),
/**
* 横向菜单模式下,是否维持在一行,即超出一行折叠成 SubMenu 显示, 仅在 direction='hoz' mode='popup' 时生效
*/
hozInLine: PropTypes.bool,
renderMore: PropTypes.func,
/**
* 自定义菜单头部
*/
header: PropTypes.node,
/**
* 自定义菜单尾部
*/
footer: PropTypes.node,
/**
* 是否自动获得焦点
*/
autoFocus: PropTypes.bool,
/**
* 当前获得焦点的子菜单或菜单项 key 值
*/
focusedKey: PropTypes.string,
focusable: PropTypes.bool,
onItemFocus: PropTypes.func,
onBlur: PropTypes.func,
/**
* 是否开启嵌入式模式,一般用于Layout的布局中,开启后没有默认背景、外层border、box-shadow,可以配合`
) : (
this.newChildren
);
const footerElement = footer ? (
{footer}
) : null;
const shouldWrapItemsAndFooter = hozAlign === 'right' && !!header;
if (rtl) {
others.dir = 'rtl';
}
return (
);
}
}