Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Menu.Item support icon #23629

Merged
merged 12 commits into from Apr 26, 2020
9 changes: 3 additions & 6 deletions components/dropdown/demo/dropdown-button.md
Expand Up @@ -29,16 +29,13 @@ function handleMenuClick(e) {

const menu = (
<Menu onClick={handleMenuClick}>
<Menu.Item key="1">
<UserOutlined />
<Menu.Item key="1" icon={<UserOutlined />}>
1st menu item
</Menu.Item>
<Menu.Item key="2">
<UserOutlined />
<Menu.Item key="2" icon={<UserOutlined />}>
2nd menu item
</Menu.Item>
<Menu.Item key="3">
<UserOutlined />
<Menu.Item key="3" icon={<UserOutlined />}>
3rd item
</Menu.Item>
</Menu>
Expand Down
30 changes: 3 additions & 27 deletions components/dropdown/demo/menu-full.md
Expand Up @@ -30,15 +30,7 @@ const menu = (
<Menu.Item key="01">Option 0</Menu.Item>
<Menu.Item key="02">Option 0</Menu.Item>
</Menu.ItemGroup>
<SubMenu
key="sub1"
title={
<span>
<MailOutlined />
<span>Navigation One</span>
</span>
}
>
<SubMenu key="sub1" icon={<MailOutlined />} title="Navigation One">
<Menu.ItemGroup key="g1" title="Item 1">
<Menu.Item key="1">Option 1</Menu.Item>
<Menu.Item key="2">Option 2</Menu.Item>
Expand All @@ -48,31 +40,15 @@ const menu = (
<Menu.Item key="4">Option 4</Menu.Item>
</Menu.ItemGroup>
</SubMenu>
<SubMenu
key="sub2"
title={
<span>
<AppstoreOutlined />
<span>Navigation Two</span>
</span>
}
>
<SubMenu key="sub2" icon={<AppstoreOutlined />} title="Navigation Two">
<Menu.Item key="5">Option 5</Menu.Item>
<Menu.Item key="6">Option 6</Menu.Item>
<SubMenu key="sub3" title="Submenu">
<Menu.Item key="7">Option 7</Menu.Item>
<Menu.Item key="8">Option 8</Menu.Item>
</SubMenu>
</SubMenu>
<SubMenu
key="sub4"
title={
<span>
<SettingOutlined />
<span>Navigation Three</span>
</span>
}
>
<SubMenu key="sub4" icon={<SettingOutlined />} title="Navigation Three">
<Menu.Item key="9">Option 9</Menu.Item>
<Menu.Item key="10">Option 10</Menu.Item>
<Menu.Item key="11">Option 11</Menu.Item>
Expand Down
34 changes: 7 additions & 27 deletions components/layout/demo/custom-trigger-debug.md
Expand Up @@ -42,42 +42,22 @@ class SiderDemo extends React.Component {
<Sider trigger={null} collapsible collapsed={this.state.collapsed}>
<div className="logo" />
<Menu theme="dark" mode="inline" defaultSelectedKeys={['3']} defaultOpenKeys={['sub1']}>
<Menu.Item key="1">
<PieChartOutlined />
<span>Option 1</span>
<Menu.Item key="1" icon={<PieChartOutlined />}>
Option 1
</Menu.Item>
<Menu.Item key="2">
<DesktopOutlined />
<span>Option 2</span>
<Menu.Item key="2" icon={<DesktopOutlined />}>
Option 2
</Menu.Item>
<SubMenu
key="sub1"
title={
<span>
<UserOutlined />
<span>User</span>
</span>
}
>
<SubMenu key="sub1" icon={<UserOutlined />} title="User">
<Menu.Item key="3">Tom</Menu.Item>
<Menu.Item key="4">Bill</Menu.Item>
<Menu.Item key="5">Alex</Menu.Item>
</SubMenu>
<SubMenu
key="sub2"
title={
<span>
<TeamOutlined />
<span>Team</span>
</span>
}
>
<SubMenu key="sub2" icon={<TeamOutlined />} title="Team">
<Menu.Item key="6">Team 1</Menu.Item>
<Menu.Item key="8">Team 2</Menu.Item>
</SubMenu>
<Menu.Item key="9">
<FileOutlined />
</Menu.Item>
<Menu.Item key="9" icon={<FileOutlined />} />
</Menu>
</Sider>
<Layout>
Expand Down
22 changes: 19 additions & 3 deletions components/menu/MenuItem.tsx
Expand Up @@ -15,6 +15,7 @@ export interface MenuItemProps
rootPrefixCls?: string;
disabled?: boolean;
level?: number;
icon?: React.ReactNode;
title?: React.ReactNode;
children?: React.ReactNode;
className?: string;
Expand All @@ -37,9 +38,19 @@ export default class MenuItem extends React.Component<MenuItemProps> {
this.menuItem = menuItem;
};

renderItemChildren() {
const { icon, children } = this.props;
// inline-collapsed.md demo 依赖 span 来隐藏文字,有 icon 属性,则内部包裹一个 span
// ref: https://github.com/ant-design/ant-design/pull/23456
if (!icon || (React.isValidElement(children) && children.type === 'span')) {
return children;
}
return <span>{children}</span>;
}

renderItem = ({ siderCollapsed }: SiderContextProps) => {
const { level, className, children, rootPrefixCls } = this.props;
const { title, ...rest } = this.props;
const { title, icon, ...rest } = this.props;

return (
<MenuContext.Consumer>
Expand All @@ -60,6 +71,7 @@ export default class MenuItem extends React.Component<MenuItemProps> {
// ref: https://github.com/ant-design/ant-design/issues/16742
tooltipProps.visible = false;
}
const childrenLength = toArray(children).length;
return (
<Tooltip
{...tooltipProps}
Expand All @@ -69,11 +81,15 @@ export default class MenuItem extends React.Component<MenuItemProps> {
<Item
{...rest}
className={classNames(className, {
[`${rootPrefixCls}-item-only-child`]: toArray(children).length === 1,
[`${rootPrefixCls}-item-only-child`]:
(icon ? childrenLength + 1 : childrenLength) === 1,
})}
title={title}
ref={this.saveMenuItem}
/>
>
{icon}
{this.renderItemChildren()}
</Item>
</Tooltip>
);
}}
Expand Down
22 changes: 20 additions & 2 deletions components/menu/SubMenu.tsx
Expand Up @@ -2,7 +2,7 @@ import * as React from 'react';
import * as PropTypes from 'prop-types';
import { SubMenu as RcSubMenu } from 'rc-menu';
import classNames from 'classnames';

import omit from 'omit.js';
import MenuContext, { MenuContextProps } from './MenuContext';

interface TitleEventEntity {
Expand All @@ -15,6 +15,7 @@ export interface SubMenuProps {
className?: string;
disabled?: boolean;
title?: React.ReactNode;
icon?: React.ReactNode;
style?: React.CSSProperties;
onTitleClick?: (e: TitleEventEntity) => void;
onTitleMouseEnter?: (e: TitleEventEntity) => void;
Expand All @@ -41,13 +42,30 @@ class SubMenu extends React.Component<SubMenuProps, any> {
this.subMenu = subMenu;
};

renderTitle() {
const { icon, title } = this.props;
if (!icon) {
return title;
}
// inline-collapsed.md demo 依赖 span 来隐藏文字,有 icon 属性,则内部包裹一个 span
// ref: https://github.com/ant-design/ant-design/pull/23456
const titleIsSpan = React.isValidElement(title) && title.type === 'span';
return (
<>
{icon}
{titleIsSpan ? title : <span>{title}</span>}
</>
);
}

render() {
const { rootPrefixCls, popupClassName } = this.props;
return (
<MenuContext.Consumer>
{({ antdMenuTheme }: MenuContextProps) => (
<RcSubMenu
{...this.props}
{...omit(this.props, ['icon'])}
title={this.renderTitle()}
ref={this.saveSubMenu}
popupClassName={classNames(
rootPrefixCls,
Expand Down