import { Menu } from '@alifd/next';
const { SubMenu, Item, Group, Divider } = Menu;
ReactDOM.render(
<Menu className="my-menu" defaultOpenKeys="sub-menu">
<Item key="1">Option 1</Item>
<Item disabled key="2">Disabled option 2</Item>
<Divider key="divider" />
<Group label="Group">
<Item key="group-1">Group option 1</Item>
<Item key="group-2">Group option 2</Item>
</Group>
<Divider />
<SubMenu key="sub-menu" label="Sub menu">
<Item key="sub-1">Sub option 1</Item>
<Item key="sub-2">Sub option 2</Item>
<Item disabled key="sub-3">
<a href="https://www.taobao.com/" target="__blank">Disabled Option Link 3</a>
</Item>
<Item key="sub-4">
<a href="https://www.taobao.com/" target="__blank">Option Link 4</a>
</Item>
</SubMenu>
<Item key="3" helper="CTRL+P">Option 3</Item>
<Item disabled key="4">
<a href="https://www.taobao.com/" target="__blank">Disabled Option Link</a>
</Item>
<Item key="5">
<a href="https://www.taobao.com/" target="__blank">Option Link</a>
</Item>
</Menu>
, mountNode);
.my-menu {
width: 200px;
}
展示最基本的用法。
import { Menu } from '@alifd/next';
const { SubMenu, Item } = Menu;
ReactDOM.render(
<Menu defaultOpenKeys="1" className="my-menu" openMode="single">
<SubMenu key="0" label="Sub menu 1">
<Item key="0-0">Sub option 1</Item>
<Item key="0-1">Sub option 2</Item>
<Item key="0-2">Sub option 3</Item>
</SubMenu>
<SubMenu key="1" label="Sub menu 2">
<Item key="1-0">Sub option 1</Item>
<Item key="1-1">Sub option 2</Item>
<Item key="1-2">Sub option 3</Item>
</SubMenu>
<SubMenu key="2" label="Sub menu 3">
<Item key="2-0">Sub option 1</Item>
<Item key="2-1">Sub option 2</Item>
<Item key="2-2">Sub option 3</Item>
</SubMenu>
<SubMenu key="3" label="Sub menu 4">
<Item key="3-0">Sub option 1</Item>
<Item key="3-1">Sub option 2</Item>
<Item key="3-2">Sub option 3</Item>
</SubMenu>
</Menu>
, mountNode);
.my-menu {
width: 200px;
}
通过设置 openMode 为 'single',可以让菜单同时只能展开一个内连子菜单,默认为可以同时展开多个。
import { Menu } from '@alifd/next';
const { SubMenu, Item, Divider } = Menu;
ReactDOM.render(
<Menu className="my-menu" mode="popup">
<Item key="1">Option 1</Item>
<Item key="2">Option 2</Item>
<Item key="3">Option 3</Item>
<Divider key="divider" />
<SubMenu key="sub-1" label="Popup menu 1">
<Item key="popup-1-1">Popup option 1</Item>
<Item key="popup-1-2">Popup option 2</Item>
</SubMenu>
<SubMenu key="sub-2" label="Popup menu 2">
<Item key="popup-2-1">Popup option 1</Item>
<Item key="popup-2-2">Popup option 2</Item>
</SubMenu>
</Menu>
, mountNode);
.my-menu {
width: 200px;
}
展示弹出菜单的用法。
import { Menu } from '@alifd/next';
const { SubMenu, Item, Divider } = Menu;
ReactDOM.render(
<Menu className="my-menu" mode="popup" triggerType="hover">
<Item key="1">Option 1</Item>
<Item key="2">Option 2</Item>
<Item key="3">Option 3</Item>
<Divider key="divider" />
<SubMenu key="sub-1" label="Popup menu 1">
<Item key="popup-1-1">Popup option 1</Item>
<Item key="popup-1-2">Popup option 2</Item>
</SubMenu>
<SubMenu key="sub-2" label="Popup menu 2">
<Item key="popup-2-1">Popup option 1</Item>
<Item key="popup-2-2">Popup option 2</Item>
</SubMenu>
</Menu>
, mountNode);
.my-menu {
width: 200px;
}
可以设置 triggerType 为 'hover',来 hover 打开子菜单,默认点击打开子菜单。
import { Menu } from '@alifd/next';
const { SubMenu, Item, Divider } = Menu;
ReactDOM.render(
<Menu className="my-menu" mode="popup" popupAlign="outside">
<Item key="1">Option 1</Item>
<Item key="2">Option 2</Item>
<Item key="3">Option 3</Item>
<Divider key="divider" />
<SubMenu key="sub-1" label="Popup menu 1">
<Item key="popup-1-1">Popup option 1</Item>
<Item key="popup-1-2">Popup option 2</Item>
</SubMenu>
<SubMenu key="sub-2" label="Popup menu 2">
<Item key="popup-2-1">Popup option 1</Item>
<Item key="popup-2-2">Popup option 2</Item>
</SubMenu>
</Menu>
, mountNode);
.my-menu {
width: 200px;
}
可以通过设置 popupAlign 为 'outside',使弹出菜单和父级菜单对齐。
import { Menu } from '@alifd/next';
const { PopupItem } = Menu;
class Demo extends React.Component {
render() {
const popupProps = {
target: () => ReactDOM.findDOMNode(this),
offset: [-1, 0],
animation: false
};
return (
<Menu className="my-custom-menu" popupProps={popupProps}>
<PopupItem key="0" label="Popup item 1">
<div className="my-custom-content">Custom content 1</div>
</PopupItem>
<PopupItem key="1" label="Popup item 2">
<div className="my-custom-content">Custom content 2</div>
</PopupItem>
<PopupItem key="2" label="Popup item 3">
<div className="my-custom-content">Custom content 3</div>
</PopupItem>
<PopupItem key="3" label="Popup item 4">
<div className="my-custom-content">Custom content 4</div>
</PopupItem>
</Menu>
);
}
}
ReactDOM.render(<Demo />, mountNode);
.my-custom-menu {
width: 200px;
border: 1px solid #ccc;
padding: 0;
box-shadow: none;
z-index: 1000;
}
.my-custom-content {
width: 400px;
height: 200px;
background: #fff;
border: 1px solid #ccc;
line-height: 200px;
text-align: center;
font-size: 20px;
}
自定义菜单弹出内容。
import { Switch, Menu } from '@alifd/next';
const { SubMenu, Item } = Menu;
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
multiple: false,
subMenuSelectable: false,
shallowSelect: false,
isSelectIconRight: false,
selectedKeys: ['1']
};
[
'handleMultipleChange', 'handleSubMenuSelectableChange',
'handleShallowSelectChange', 'handleSelect', 'handleIconDirectionChange'
].forEach(method => {
this[method] = this[method].bind(this);
});
}
handleMultipleChange() {
this.setState({
multiple: !this.state.multiple,
selectedKeys: []
});
}
handleIconDirectionChange() {
this.setState({
isSelectIconRight: !this.state.isSelectIconRight,
selectedKeys: []
});
}
handleSubMenuSelectableChange() {
this.setState({
subMenuSelectable: !this.state.subMenuSelectable,
selectedKeys: []
});
}
handleShallowSelectChange() {
this.setState({
shallowSelect: !this.state.shallowSelect,
selectedKeys: []
});
}
handleSelect(selectedKeys, ...others) {
this.setState({
selectedKeys
});
console.log(selectedKeys, ...others);
}
render() {
const { multiple, subMenuSelectable, shallowSelect, selectedKeys, isSelectIconRight } = this.state;
const selectMode = multiple ? 'multiple' : 'single';
return (
<div>
<div>
<span className="my-switch-label">Multiple </span>
<Switch value={multiple} onChange={this.handleMultipleChange} />
</div>
<div>
<span className="my-switch-label">isSelectIconRight </span>
<Switch value={multiple} onChange={this.handleIconDirectionChange} />
</div>
<div>
<span className="my-switch-label">Label of submenu selectable </span>
<Switch value={multiple} onChange={this.handleSubMenuSelectableChange} />
</div>
<div>
<span className="my-switch-label">Only first level selectable </span>
<Switch value={multiple} onChange={this.handleShallowSelectChange} />
</div>
<Menu isSelectIconRight={isSelectIconRight} className="my-select-menu" defaultOpenKeys={['sub']} selectMode={selectMode} selectedKeys={selectedKeys} shallowSelect={shallowSelect} onSelect={this.handleSelect}>
<Item key="1">Option 1</Item>
<Item disabled key="2">Disabled option 2</Item>
<SubMenu key="sub" label="Sub menu" selectable={subMenuSelectable}>
<Item key="sub-1">Sub option 1</Item>
<Item key="sub-2">Sub option 2</Item>
</SubMenu>
<Item key="3">Option 3</Item>
</Menu>
</div>
);
}
}
ReactDOM.render(<Demo />, mountNode);
.my-switch-label {
vertical-align: super;
}
.my-select-menu {
margin-top: 10px;
width: 200px;
}
展示菜单项选择用法。
import { Menu } from '@alifd/next';
const { CheckboxItem, RadioItem, Divider } = Menu;
const sexs = ['male', 'female'];
const balls = ['football', 'basketball', 'volleyball'];
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
sex: 'male',
balls: []
};
this.handleSexCheck = this.handleSexCheck.bind(this);
this.handleBallCheck = this.handleBallCheck.bind(this);
}
handleSexCheck(key) {
this.setState({
sex: key
});
}
handleBallCheck(key, check) {
let newKeys;
const index = this.state.balls.indexOf(key);
if (check && index === -1) {
newKeys = this.state.balls.concat(key);
} else if (!check && index > -1) {
newKeys = [
...this.state.balls.slice(0, index),
...this.state.balls.slice(index + 1)
];
}
if (newKeys) {
this.setState({
balls: newKeys
});
}
}
render() {
return (
<Menu className="my-menu">
{sexs.map(sex => (
<RadioItem key={sex} checked={this.state.sex === sex} onChange={this.handleSexCheck.bind(this, sex)}>
{sex}
</RadioItem>
))}
<Divider key="divider" />
{balls.map(ball => (
<CheckboxItem key={ball} checked={this.state.balls.indexOf(ball) > -1} onChange={this.handleBallCheck.bind(this, ball)}>
{ball}
</CheckboxItem>
))}
</Menu>
);
}
}
ReactDOM.render(<Demo />, mountNode);
.my-menu {
width: 200px;
}
展示自定义组合菜单项可选的用法。
import { Menu } from '@alifd/next';
const { SubMenu, Item } = Menu;
ReactDOM.render(
<Menu hozInLine direction="hoz" mode="popup" className="my-hoz-menu" popupClassName="my-hoz-menu" popupAutoWidth>
<Item key="1">First</Item>
<Item key="2">Second</Item>
<SubMenu label="Sub Nav">
<Item key="sub-12">Sub option 1</Item>
<Item key="sub-22">Sub option 2</Item>
<SubMenu label="Sub Sub Nav">
<Item key="sub-sub-122">Sub sub option 1</Item>
<Item key="sub-sub-222">Sub sub option 2</Item>
</SubMenu>
</SubMenu>
<SubMenu label="Sub Nav">
<Item key="sub-1">Sub option 1</Item>
<Item key="sub-2">Sub option 2</Item>
<SubMenu label="Sub Sub Nav">
<Item key="sub-sub-1">Sub sub option 1</Item>
<Item key="sub-sub-2">Sub sub option 2</Item>
</SubMenu>
</SubMenu>
<Item key="3">Third</Item>
</Menu>
, mountNode);
.my-hoz-menu .next-menu-item {
width: 160px;
}
.my-hoz-menu .next-menu-item.next-menu-more {
width: 60px;
}
展示横向导航菜单条的用法。
import { Menu } from '@alifd/next';
const { SubMenu, Item, Divider } = Menu;
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedKeys: []
};
this.handleSelect = this.handleSelect.bind(this);
}
handleSelect(selectedKeys) {
selectedKeys = selectedKeys.filter(key => {
return ['sub-1', 'sub-2'].indexOf(key) > -1;
});
this.setState({
selectedKeys
});
}
createContextMenu = e => {
e.preventDefault();
const target = e.target;
const { top, left } = target.getBoundingClientRect();
Menu.create({
target: e.target,
offset: [e.clientX - left, e.clientY - top],
className: 'context-menu',
popupClassName: 'context-menu',
onItemClick: console.log,
selectedKeys: this.state.selectedKeys,
selectMode: 'multiple',
onSelect: this.handleSelect,
children: [
<Item key="1">Option 1</Item>,
<Item key="2">Option 2</Item>,
<Item key="3">Option 3</Item>,
<Divider key="divider-1" />,
<SubMenu key="sub-menu" label="Sub menu">
<Item key="sub-1">Sub option 1</Item>
<Item key="sub-2">Sub option 2</Item>
</SubMenu>,
<Item key="4">Option 4</Item>,
<Divider key="divider-2" />,
<Item key="5">Option 5</Item>
]
});
};
render() {
return (
<div className="context-demo" onContextMenu={this.createContextMenu}>
Right click here to see the context menu!
</div>
);
}
}
ReactDOM.render(<Demo />, mountNode);
.context-demo {
width: 500px;
height: 200px;
line-height: 200px;
text-align: center;
background: #DDD;
border: 1px solid black;
}
.context-menu {
width: 120px;
}
展示如何创建自定义的上下文菜单。
import { Menu, Box, Typography } from '@alifd/next';
const { SubMenu, Item, PopupItem, Divider } = Menu;
const popupProps = {
align: 'tc bc',
triggerType: 'click'
};
const ds = [{
title: '库存管理',
children: [{
title: '部门库存管理',
link: ''
},{
title: '小二库存管理',
link: ''
}]
}, {
title: '功能模块管理',
children: [{
title: '功能模块管理',
link: ''
},{
title: '卡片管理',
link: ''
},{
title: '首页布局',
link: ''
},{
title: '页面管理',
link: ''
}]
}, {
title: '系统管理',
children: [{
title: '角色管理',
link: ''
},{
title: '标签管理',
link: ''
},{
title: '字典管理',
link: ''
}]
}];
const Panel = props => {
const { dataSource, ...others } = props;
return (<div className="my-custom-content3" {...others}>
<Box direction="row">
{dataSource.map((item, i) => {
return (<Menu embeddable key={i}>
<Menu.Item><div className="title">{item.title}</div></Menu.Item>
<Divider />
{item.dataSource.map((child, g) => {
const a = child.children && child.children.map((c, j) => {
return <Menu.Item key={j}><a href={c.link}>{c.title}</a></Menu.Item>;
});
return [<div className="sub-title" key={`title-${g}`}>{child.title}</div>, ...a];
})}
</Menu>);
})}
</Box>
</div>);
};
const SubPanel = props => {
const { dataSource, ...others } = props;
return (<div className="my-custom-content2" {...others}>
<Box direction="row">
{dataSource.map((item, i) => {
return (<Menu embeddable key={i}>
<div className="sub-title">{item.title}</div>
{item.children.map((child, j) => {
return <Menu.Item key={j}><a href={child.link}>{child.title}</a></Menu.Item>;
})}
</Menu>);
})}
</Box>
</div>);
};
ReactDOM.render(
<Menu hozInLine direction="hoz" mode="popup" className="my-hoz-menu" popupClassName="my-hoz-menu" popupProps={popupProps}
renderMore={(more) => {
const newDs = more.map((item, i) => {
const data = item.props.children.props;
return {
title: item.props.label,
dataSource: data.dataSource
};
});
return (<PopupItem noIcon triggerType="click" key="0-more" label="更多" >
<Panel dataSource={newDs}/>
</PopupItem>);
}}>
<PopupItem key="0" label="Popup item 1" noIcon>
<SubPanel dataSource={ds}/>
</PopupItem>
<PopupItem key="1" label="Popup item 2" noIcon>
<SubPanel dataSource={ds}/>
</PopupItem>
<PopupItem key="2" label="Popup item 3" noIcon>
<SubPanel dataSource={ds}/>
</PopupItem>
<PopupItem key="3" label="Popup item 4" noIcon>
<SubPanel dataSource={ds}/>
</PopupItem>
<PopupItem key="4" label="Popup item 5" noIcon>
<SubPanel dataSource={ds}/>
</PopupItem>
<PopupItem key="5" label="Popup item 6" noIcon>
<SubPanel dataSource={ds}/>
</PopupItem>
<PopupItem key="6" label="Popup item 7" noIcon>
<SubPanel dataSource={ds}/>
</PopupItem>
<PopupItem key="7" label="Popup item 8" noIcon>
<SubPanel dataSource={ds}/>
</PopupItem>
<PopupItem key="8" label="Popup item 9" noIcon>
<SubPanel dataSource={ds}/>
</PopupItem>
</Menu>
, mountNode);
.my-custom-menu {
width: 200px;
border: 1px solid #ccc;
padding: 0;
box-shadow: none;
z-index: 1000;
text-align: left;
}
.my-custom-content2 {
background: #fff;
border: 1px solid #ccc;
text-align: center;
font-size: 20px;
text-align: left;
}
.my-custom-content3 {
background: #fff;
border: 1px solid #ccc;
text-align: center;
font-size: 20px;
text-align: left;
}
ul {
list-style: none;
padding-inline-start: 10px;
}
.title {
font-size: 16px;
font-weight: bold;
}
.sub-title {
font-size: 12px;
font-weight: normal;
color: #999;
padding-left: 20px;
}
展示渲染更多 renderMore
用法
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
children | 菜单项和子菜单 | ReactNode | - |
onItemClick | 点击菜单项触发的回调函数 签名: Function(key: String, item: Object, event: Object) => void 参数: key: {String} 点击的菜单项的 key 值 item: {Object} 点击的菜单项对象 event: {Object} 点击的事件对象 |
Function | () => {} |
openKeys | 当前打开的子菜单的 key 值 | String/Array | - |
defaultOpenKeys | 初始打开的子菜单的 key 值 | String/Array | [] |
defaultOpenAll | 初始展开所有的子菜单,只在 mode 设置为 'inline' 以及 openMode 设置为 'multiple' 下生效,优先级高于 defaultOpenKeys | Boolean | false |
onOpen | 打开或关闭子菜单触发的回调函数 签名: Function(key: Array, extra: Object) => void 参数: key: {Array} 打开的所有子菜单的 key 值 extra: {Object} 额外参数 extra.key: {String} 当前操作子菜单的 key 值 extra.open: {Boolean} 是否是打开 |
Function | () => {} |
mode | 子菜单打开的模式 可选值: 'inline', 'popup' |
Enum | 'inline' |
triggerType | 子菜单打开的触发行为 可选值: 'click', 'hover' |
Enum | 'click' |
openMode | 展开内连子菜单的模式,同时可以展开一个子菜单还是多个子菜单,该属性仅在 mode 为 inline 时生效 可选值: 'single', 'multiple' |
Enum | 'multiple' |
inlineIndent | 内连子菜单缩进距离 | Number | 20 |
popupAutoWidth | 是否自动让弹层的宽度和菜单项保持一致,如果弹层的宽度比菜单项小则和菜单项保持一致,如果宽度大于菜单项则不做处理 | Boolean | false |
popupAlign | 弹层的对齐方式 可选值: 'follow', 'outside' |
Enum | 'follow' |
popupProps | 弹层自定义 props | Object/Function | {} |
popupClassName | 弹出子菜单自定义 className | String | - |
popupStyle | 弹出子菜单自定义 style | Object | - |
selectedKeys | 当前选中菜单项的 key 值 | String/Array | - |
defaultSelectedKeys | 初始选中菜单项的 key 值 | String/Array | [] |
onSelect | 选中或取消选中菜单项触发的回调函数 签名: Function(selectedKeys: Array, item: Object, extra: Object) => void 参数: selectedKeys: {Array} 选中的所有菜单项的值 item: {Object} 选中或取消选中的菜单项 extra: {Object} 额外参数 extra.select: {Boolean} 是否是选中 extra.key: {Array} 菜单项的 key extra.label: {Object} 菜单项的文本 extra.keyPath: {Array} 菜单项 key 的路径 |
Function | () => {} |
selectMode | 选中模式,单选还是多选,默认无值,不可选 可选值: 'single', 'multiple' |
Enum | - |
shallowSelect | 是否只能选择第一层菜单项(不能选择子菜单中的菜单项) | Boolean | false |
hasSelectedIcon | 是否显示选中图标,如果设置为 false 需配合配置平台设置选中时的背景色以示区分 | Boolean | true |
isSelectIconRight | 是否将选中图标居右,仅当 hasSelectedIcon 为true 时生效。 注意:SubMenu 上的选中图标一直居左,不受此API控制 |
Boolean | false |
direction | 菜单第一层展示方向 可选值: 'ver', 'hoz' |
Enum | 'ver' |
hozAlign | 横向菜单条 item 和 footer 的对齐方向,在 direction 设置为 'hoz' 并且 header 存在时生效 可选值: 'left', 'right' |
Enum | 'left' |
hozInLine | 横向菜单模式下,是否维持在一行,即超出一行折叠成 SubMenu 显示, 仅在 direction='hoz' mode='popup' 时生效 | Boolean | false |
header | 自定义菜单头部 | ReactNode | - |
footer | 自定义菜单尾部 | ReactNode | - |
autoFocus | 是否自动获得焦点 | Boolean | false |
focusedKey | 当前获得焦点的子菜单或菜单项 key 值 | String | - |
embeddable | 是否开启嵌入式模式,一般用于Layout的布局中,开启后没有默认背景、外层border、box-shadow,可以配合<Menu style={{lineHeight: '100px'}}> 自定义高度 |
Boolean | false |
icons | 可配置的icons,包括 select 等 | Object | {} |
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
disabled | 是否禁用 | Boolean | false |
helper | 帮助文本 | ReactNode | - |
children | 菜单项标签内容 | ReactNode | - |
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
label | 标签内容 | ReactNode | - |
selectable | 是否可选,该属性仅在设置 Menu 组件 selectMode 属性后生效 | Boolean | false |
mode | 子菜单打开方式,如果设置会覆盖 Menu 上的同名属性 可选值: 'inline', 'popup' |
Enum | Menu 的 mode 属性值 |
children | 菜单项或下一级子菜单 | ReactNode | - |
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
label | 标签内容 | ReactNode | - |
children | 自定义弹层内容 | ReactNode | - |
该子组件选中情况不受 defaultSelectedKeys/selectedKeys 控制,请自行控制选中逻辑
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
checked | 是否选中 | Boolean | false |
indeterminate | 是否半选中 | Boolean | false |
disabled | 是否禁用 | Boolean | false |
onChange | 选中或取消选中触发的回调函数 签名: Function(checked: Boolean, event: Object) => void 参数: checked: {Boolean} 是否选中 event: {Object} 选中事件对象 |
Function | () => {} |
helper | 帮助文本 | ReactNode | - |
children | 标签内容 | ReactNode | - |
该子组件选中情况不受 defaultSelectedKeys/selectedKeys 控制,请自行控制选中逻辑
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
checked | 是否选中 | Boolean | false |
disabled | 是否禁用 | Boolean | false |
onChange | 选中或取消选中触发的回调函数 签名: Function(checked: Boolean, event: Object) => void 参数: checked: {Boolean} 是否选中 event: {Object} 选中事件对象 |
Function | () => {} |
helper | 帮助文本 | ReactNode | - |
children | 标签内容 | ReactNode | - |
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
label | 标签内容 | ReactNode | - |
children | 菜单项 | ReactNode | - |
创建上下文菜单。
按键 | 说明 |
---|---|
Up Arrow | 导航到上一项 |
Down Arrow | 导航到下一项 |
Right Arrow | 打开子菜单,导航到子菜单第一项;横向菜单条第一层,导航到右一项 |
Left Arrow | 关闭子菜单,导航到父级菜单;横向菜单条第一层,导航都左一项 |
Enter | 打开子菜单,导航到子菜单第一项 |
Esc | 关闭子菜单,导航到父级菜单 |
SPACE | 切换选中状态 |