Skip to content

Commit 67cb1a0

Browse files
committed
feat(Menu): add render more
1 parent 633361c commit 67cb1a0

File tree

2 files changed

+189
-1
lines changed

2 files changed

+189
-1
lines changed

docs/menu/demo/render-more.md

+179
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# 自定义渲染更多
2+
3+
- order: 10
4+
5+
展示渲染更多 `renderMore` 用法
6+
7+
:::lang=en-us
8+
# Menu render more
9+
10+
- order: 10
11+
12+
Demo the usage of `renderMore`.
13+
:::
14+
15+
---
16+
17+
````jsx
18+
import { Menu, Box, Typography } from '@alifd/next';
19+
20+
const { SubMenu, Item, PopupItem, Divider } = Menu;
21+
const popupProps = {
22+
align: 'tc bc',
23+
triggerType: 'click'
24+
};
25+
const ds = [{
26+
title: '库存管理',
27+
children: [{
28+
title: '部门库存管理',
29+
link: ''
30+
},{
31+
title: '小二库存管理',
32+
link: ''
33+
}]
34+
}, {
35+
title: '功能模块管理',
36+
children: [{
37+
title: '功能模块管理',
38+
link: ''
39+
},{
40+
title: '卡片管理',
41+
link: ''
42+
},{
43+
title: '首页布局',
44+
link: ''
45+
},{
46+
title: '页面管理',
47+
link: ''
48+
}]
49+
}, {
50+
title: '系统管理',
51+
children: [{
52+
title: '角色管理',
53+
link: ''
54+
},{
55+
title: '标签管理',
56+
link: ''
57+
},{
58+
title: '字典管理',
59+
link: ''
60+
}]
61+
}];
62+
63+
const Panel = props => {
64+
const { dataSource, ...others } = props;
65+
66+
return <div className="my-custom-content" {...others}>
67+
<Box direction="row">
68+
{dataSource.map((item, i) => {
69+
return <Menu embeddable key={i}>
70+
<Menu.Item><div className="title">{item.title}</div></Menu.Item>
71+
<Divider />
72+
{item.dataSource.map((child, g) => {
73+
const a = child.children && child.children.map((c, j) => {
74+
return <Menu.Item key={j}><a href={c.link}>{c.title}</a></Menu.Item>
75+
})
76+
return [<div className="sub-title" key={`title-${g}`}>{child.title}</div>, ...a]
77+
})}
78+
</Menu>
79+
})}
80+
</Box>
81+
</div>;
82+
}
83+
84+
85+
const SubPanel = props => {
86+
const { dataSource, ...others } = props;
87+
88+
return <div className="my-custom-content" {...others}>
89+
<Box direction="row">
90+
{dataSource.map((item, i) => {
91+
return <Menu embeddable key={i}>
92+
<div className="sub-title">{item.title}</div>
93+
{item.children.map((child, j) => {
94+
return <Menu.Item key={j}><a href={child.link}>{child.title}</a></Menu.Item>
95+
})}
96+
</Menu>
97+
})}
98+
</Box>
99+
</div>;
100+
}
101+
ReactDOM.render(
102+
<Menu hozInLine direction="hoz" mode="popup" className="my-hoz-menu" popupClassName="my-hoz-menu" popupProps={popupProps}
103+
renderMore={(more) => {
104+
const newDs = more.map((item, i) => {
105+
const data = item.props.children.props;
106+
return {
107+
title: item.props.label,
108+
dataSource: data.dataSource
109+
}
110+
});
111+
112+
return <PopupItem triggerType="click" key="0-more" label="更多" >
113+
<Panel dataSource={newDs}/>
114+
</PopupItem>
115+
}}>
116+
<PopupItem key="0" label="Popup item 1" noIcon>
117+
<SubPanel dataSource={ds}/>
118+
</PopupItem>
119+
<PopupItem key="1" label="Popup item 2" noIcon>
120+
<SubPanel dataSource={ds}/>
121+
</PopupItem>
122+
<PopupItem key="2" label="Popup item 3" noIcon>
123+
<SubPanel dataSource={ds}/>
124+
</PopupItem>
125+
<PopupItem key="3" label="Popup item 4" noIcon>
126+
<SubPanel dataSource={ds}/>
127+
</PopupItem>
128+
<PopupItem key="4" label="Popup item 5" noIcon>
129+
<SubPanel dataSource={ds}/>
130+
</PopupItem>
131+
<PopupItem key="5" label="Popup item 6" noIcon>
132+
<SubPanel dataSource={ds}/>
133+
</PopupItem>
134+
<PopupItem key="6" label="Popup item 7" noIcon>
135+
<SubPanel dataSource={ds}/>
136+
</PopupItem>
137+
<PopupItem key="7" label="Popup item 8" noIcon>
138+
<SubPanel dataSource={ds}/>
139+
</PopupItem>
140+
<PopupItem key="8" label="Popup item 9" noIcon>
141+
<SubPanel dataSource={ds}/>
142+
</PopupItem>
143+
</Menu>
144+
, mountNode);
145+
````
146+
147+
````css
148+
.my-custom-menu {
149+
width: 200px;
150+
border: 1px solid #ccc;
151+
padding: 0;
152+
box-shadow: none;
153+
z-index: 1000;
154+
text-align: left;
155+
}
156+
157+
.my-custom-content {
158+
background: #fff;
159+
border: 1px solid #ccc;
160+
text-align: center;
161+
font-size: 20px;
162+
text-align: left;
163+
}
164+
165+
ul {
166+
list-style: none;
167+
padding-inline-start: 10px;
168+
}
169+
.title {
170+
font-size: 16px;
171+
font-weight: bold;
172+
}
173+
.sub-title {
174+
font-size: 12px;
175+
font-weight: normal;
176+
color: #999;
177+
padding-left: 20px;
178+
}
179+
````

src/menu/view/menu.jsx

+10-1
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ export default class Menu extends Component {
147147
* 横向菜单模式下,是否维持在一行,即超出一行折叠成 SubMenu 显示, 仅在 direction='hoz' mode='popup' 时生效
148148
*/
149149
hozInLine: PropTypes.bool,
150+
renderMore: PropTypes.func,
150151
/**
151152
* 自定义菜单头部
152153
*/
@@ -411,7 +412,7 @@ export default class Menu extends Component {
411412
}
412413

413414
getIndicatorsItem(items, isPlaceholder) {
414-
const { prefix } = this.props;
415+
const { prefix, renderMore } = this.props;
415416
const moreCls = cx({
416417
[`${prefix}menu-more`]: true,
417418
});
@@ -420,9 +421,17 @@ export default class Menu extends Component {
420421
// keep placehold to get width
421422
if (isPlaceholder) {
422423
style.visibility = 'hidden';
424+
style.display = 'unset';
423425
// indicators which not in use, just display: none
424426
} else if (items && items.length === 0) {
425427
style.display = 'none';
428+
style.visibility = 'unset';
429+
}
430+
431+
if (renderMore && typeof renderMore === 'function') {
432+
return React.cloneElement(renderMore(items), {
433+
style,
434+
});
426435
}
427436

428437
return (

0 commit comments

Comments
 (0)