UNPKG

4.37 kBJavaScriptView Raw
1import React from 'react';
2import RcMenu, { Item, Divider, SubMenu, ItemGroup,SideContainer,MenuToggle } from './ExportMenu.js';
3import animation from './_util/openAnimation';
4import warning from './_util/warning';
5
6export interface SelectParam {
7 key: string;
8 keyPath: Array<string>;
9 item: any;
10 domEvent: any;
11 selectedKeys: Array<string>;
12}
13
14export interface ClickParam {
15 key: string;
16 keyPath: Array<string>;
17 item: any;
18 domEvent: any;
19}
20
21export interface MenuProps {
22 id?: string;
23 /** 主题颜色*/
24 theme?: 'light' | 'dark';
25 /** 菜单类型 enum: `vertical` `horizontal` `inline`*/
26 mode?: 'vertical' | 'horizontal' | 'inline';
27 /** 当前选中的菜单项 key 数组*/
28 selectedKeys?: Array<string>;
29 /** 初始选中的菜单项 key 数组*/
30 defaultSelectedKeys?: Array<string>;
31 /** 当前展开的菜单项 key 数组*/
32 openKeys?: Array<string>;
33 /** 初始展开的菜单项 key 数组*/
34 defaultOpenKeys?: Array<string>;
35 onOpenChange?: (openKeys: string[]) => void;
36 /**
37 * 被选中时调用
38 *
39 * @type {(item: any, key: string, selectedKeys: Array<string>) => void}
40 */
41 onSelect?: (param: SelectParam) => void;
42 /** 取消选中时调用*/
43 onDeselect?: (param: SelectParam) => void;
44 /** 点击 menuitem 调用此函数*/
45 onClick?: (param: ClickParam) => void;
46 /** 根节点样式*/
47 style?: React.CSSProperties;
48 openAnimation?: string | Object;
49 openTransitionName?: string | Object;
50 className?: string;
51 prefixCls?: string;
52}
53
54class Menu extends React.Component<MenuProps, any> {
55
56 static defaultProps = {
57 prefixCls: 'u-menu',
58 className: '',
59 theme: 'light', // or dark
60 };
61 switchModeFromInline: boolean;
62 constructor(props) {
63 super(props);
64
65 warning(
66 !('onOpen' in props || 'onClose' in props),
67 '`onOpen` and `onClose` are removed, please use `onOpenChange` instead.'
68 );
69
70 this.state = {
71 openKeys: [],
72 };
73 this.rcMenu = {};
74 }
75 componentWillReceiveProps(nextProps) {
76 if (this.props.mode === 'inline' &&
77 nextProps.mode !== 'inline') {
78 this.switchModeFromInline = true;
79 }
80 if ('openKeys' in nextProps) {
81 this.setOpenKeys(nextProps.openKeys);
82 }
83 }
84 handleClick = (e) => {
85 this.setOpenKeys([]);
86
87 const onClick = this.props.onClick;
88 if (onClick) {
89 onClick(e);
90 }
91 }
92 handleOpenChange = (openKeys: string[]) => {
93 this.setOpenKeys(openKeys);
94
95 const onOpenChange = this.props.onOpenChange;
96 if (onOpenChange) {
97 onOpenChange(openKeys);
98 }
99 }
100 setOpenKeys(openKeys) {
101 if (!('openKeys' in this.props)) {
102 this.setState({ openKeys });
103 }
104 }
105 render() {
106 let openAnimation = this.props.openAnimation || this.props.openTransitionName;
107 if (!openAnimation) {
108 switch (this.props.mode) {
109 case 'horizontal':
110 openAnimation = '';
111 break;
112 case 'vertical':
113 // When mode switch from inline
114 // submenu should hide without animation
115 if (this.switchModeFromInline) {
116 openAnimation = animation;
117 this.switchModeFromInline = false;
118 } else {
119 openAnimation = 'zoom-big';
120 }
121 break;
122 case 'inline':
123 openAnimation = animation;
124 break;
125 default:
126 }
127 }
128
129 let props = {};
130 const className = `${this.props.className} ${this.props.prefixCls}-${this.props.theme}`;
131 if (this.props.mode !== 'inline') {
132 // 这组属性的目的是
133 // 弹出型的菜单需要点击后立即关闭
134 // 另外,弹出型的菜单的受控模式没有使用场景
135 props = {
136 openKeys: this.state.openKeys,
137 onClick: this.handleClick,
138 onOpenChange: this.handleOpenChange,
139 openTransitionName: openAnimation,
140 className,
141 };
142 } else {
143 props = {
144 openAnimation,
145 className,
146 };
147 }
148 return <RcMenu ref={(el) => this.rcMenu = el} {...this.props} {...props} />;
149 }
150}
151Menu.Divider = Divider;
152Menu.Item = Item;
153Menu.SubMenu = SubMenu;
154Menu.ItemGroup = ItemGroup;
155Menu.MenuToggle = MenuToggle;
156Menu.SideContainer = SideContainer;
157export default Menu;
\No newline at end of file