Skip to content

Commit

Permalink
feat: Menu support expandIcon (#27565)
Browse files Browse the repository at this point in the history
* style: optimize menu expand icon color

close #20035

* feat: 🆕 support Menu expandIcon

* revert arrow color
  • Loading branch information
afc163 authored and yoyo837 committed Nov 19, 2020
1 parent 7c3b84e commit bc92ecd
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 73 deletions.
1 change: 1 addition & 0 deletions components/menu/index.en-US.md
Expand Up @@ -31,6 +31,7 @@ More layouts with navigation: [Layout](/components/layout).
| --- | --- | --- | --- | --- |
| defaultOpenKeys | Array with the keys of default opened sub menus | string\[] | - | |
| defaultSelectedKeys | Array with the keys of default selected menu items | string\[] | - | |
| expandIcon | custom expand icon of submenu | ReactNode \| `(props: SubMenuProps & { isSubMenu: boolean }) => ReactNode` | - | 4.9.0 |
| forceSubMenuRender | Render submenu into DOM before it becomes visible | boolean | false | |
| inlineCollapsed | Specifies the collapsed status when menu is inline mode | boolean | - | |
| inlineIndent | Indent (in pixels) of inline menu items on each level | number | 24 | |
Expand Down
6 changes: 5 additions & 1 deletion components/menu/index.tsx
Expand Up @@ -7,6 +7,7 @@ import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import devWarning from '../_util/devWarning';
import { SiderContext, SiderContextProps } from '../layout/Sider';
import collapseMotion from '../_util/motion';
import { cloneElement } from '../_util/reactNode';
import MenuContext, { MenuTheme } from './MenuContext';

export { MenuItemGroupProps } from 'rc-menu';
Expand Down Expand Up @@ -53,7 +54,7 @@ class InternalMenu extends React.Component<InternalMenuProps> {
}

renderMenu = ({ getPopupContainer, getPrefixCls, direction }: ConfigConsumerProps) => {
const { prefixCls: customizePrefixCls, className, theme } = this.props;
const { prefixCls: customizePrefixCls, className, theme, expandIcon } = this.props;
const defaultMotions = {
horizontal: { motionName: 'slide-up' },
inline: collapseMotion,
Expand Down Expand Up @@ -84,6 +85,9 @@ class InternalMenu extends React.Component<InternalMenuProps> {
prefixCls={prefixCls}
direction={direction}
defaultMotions={defaultMotions}
expandIcon={cloneElement(expandIcon, {
className: `${prefixCls}-submenu-expand-icon`,
})}
/>
</MenuContext.Provider>
);
Expand Down
1 change: 1 addition & 0 deletions components/menu/index.zh-CN.md
Expand Up @@ -32,6 +32,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/3XZcjGpvK/Menu.svg
| --- | --- | --- | --- | --- |
| defaultOpenKeys | 初始展开的 SubMenu 菜单项 key 数组 | string\[] | - | |
| defaultSelectedKeys | 初始选中的菜单项 key 数组 | string\[] | - | |
| expandIcon | 自定义展开图标 | ReactNode \| `(props: SubMenuProps & { isSubMenu: boolean }) => ReactNode` | - | 4.9.0 |
| forceSubMenuRender | 在子菜单展示之前就渲染进 DOM | boolean | false | |
| inlineCollapsed | inline 时菜单是否收起状态 | boolean | - | |
| inlineIndent | inline 模式的菜单缩进宽度 | number | 24 | |
Expand Down
128 changes: 56 additions & 72 deletions components/menu/style/index.less
Expand Up @@ -42,12 +42,12 @@
}

&-horizontal &-submenu {
transition: border-color 0.3s @ease-in-out, background 0.3s @ease-in-out;
transition: border-color 0.3s ease-in-out, background 0.3s ease-in-out;
}
&-submenu,
&-submenu-inline {
transition: border-color 0.3s @ease-in-out, background 0.3s @ease-in-out,
padding 0.15s @ease-in-out;
transition: border-color 0.3s ease-in-out, background 0.3s ease-in-out,
padding 0.15s ease-in-out;
}

&-submenu-selected {
Expand All @@ -61,7 +61,7 @@

&-submenu &-sub {
cursor: initial;
transition: background 0.3s @ease-in-out, padding 0.3s @ease-in-out;
transition: background 0.3s ease-in-out, padding 0.3s ease-in-out;
}

&-item a {
Expand Down Expand Up @@ -172,9 +172,9 @@

&-horizontal &-item,
&-horizontal &-submenu-title {
transition: color 0.3s @ease-in-out, border-color 0.3s @ease-in-out,
background 0.3s @ease-in-out;
transition: color 0.3s ease-in-out, border-color 0.3s ease-in-out, background 0.3s ease-in-out;
}

&-item,
&-submenu-title {
position: relative;
Expand All @@ -183,16 +183,16 @@
padding: @menu-item-padding;
white-space: nowrap;
cursor: pointer;
transition: color 0.3s @ease-in-out, border-color 0.3s @ease-in-out,
background 0.3s @ease-in-out, padding 0.15s @ease-in-out;
transition: color 0.3s ease-in-out, border-color 0.3s ease-in-out, background 0.3s ease-in-out,
padding 0.15s ease-in-out;
.@{iconfont-css-prefix} {
min-width: 14px;
margin-right: @menu-icon-margin-right;
font-size: @menu-icon-size;
transition: font-size 0.15s @ease-out, margin 0.3s @ease-in-out;
transition: font-size 0.15s ease-out, margin 0.3s ease-in-out, color 0.3s ease-in-out;
+ span {
opacity: 1;
transition: opacity 0.3s @ease-in-out, width 0.3s @ease-in-out;
transition: opacity 0.3s ease-in-out, width 0.3s ease-in-out, color 0.3s ease-in-out;
}
}

Expand Down Expand Up @@ -246,86 +246,70 @@
background-color: @menu-bg;
border-radius: @border-radius-base;
&-submenu-title::after {
transition: transform 0.3s @ease-in-out;
transition: transform 0.3s ease-in-out;
}
}

&-popup > .@{menu-prefix-cls} {
background-color: @menu-popup-bg;
}

&-vertical,
&-vertical-left,
&-vertical-right,
&-inline {
> .@{menu-prefix-cls}-submenu-title .@{menu-prefix-cls}-submenu-arrow {
position: absolute;
top: 50%;
right: 16px;
width: 10px;
transition: transform 0.3s @ease-in-out;
&-expand-icon,
&-arrow {
position: absolute;
top: 50%;
right: 16px;
width: 10px;
color: @menu-item-color;
transform: translateY(-50%);
transition: transform 0.3s ease-in-out;
}

&::before,
&::after {
position: absolute;
width: 6px;
height: 1.5px;
// background + background-image to makes before & after cross have same color.
// ref: https://github.com/ant-design/ant-design/issues/15910
background-image: linear-gradient(to right, @menu-item-color, @menu-item-color);
border-radius: 2px;
transition: background 0.3s @ease-in-out, transform 0.3s @ease-in-out,
top 0.3s @ease-in-out;
content: '';
}
&::before {
transform: rotate(45deg) translateY(-2px);
}
&::after {
transform: rotate(-45deg) translateY(2px);
}
&-arrow {
&::before,
&::after {
position: absolute;
width: 6px;
height: 1.5px;
background-color: currentColor;
border-radius: 2px;
transition: background 0.3s ease-in-out, transform 0.3s ease-in-out, top 0.3s ease-in-out,
color 0.3s ease-in-out;
content: '';
}
> .@{menu-prefix-cls}-submenu-title:hover .@{menu-prefix-cls}-submenu-arrow {
&::after,
&::before {
background: linear-gradient(to right, @menu-highlight-color, @menu-highlight-color);
}
&::before {
transform: rotate(45deg) translateY(-2.5px);
}
&::after {
transform: rotate(-45deg) translateY(2.5px);
}
}

&-vertical,
&-vertical-left,
&-vertical-right {
> .@{menu-prefix-cls}-submenu-title .@{menu-prefix-cls}-submenu-arrow {
&::before {
transform: rotate(45deg) translateY(-2px);
}
&::after {
transform: rotate(-45deg) translateY(2px);
}
}
&:hover &-expand-icon,
&:hover &-arrow {
color: @menu-highlight-color;
}

&-inline > .@{menu-prefix-cls}-submenu-title .@{menu-prefix-cls}-submenu-arrow {
&-inline &-arrow {
&::before {
transform: rotate(-45deg) translateX(2px);
transform: rotate(-45deg) translateX(2.5px);
}
&::after {
transform: rotate(45deg) translateX(-2px);
transform: rotate(45deg) translateX(-2.5px);
}
}

&-open {
&.@{menu-prefix-cls}-submenu-inline
> .@{menu-prefix-cls}-submenu-title
.@{menu-prefix-cls}-submenu-arrow {
transform: translateY(-2px);
&::after {
transform: rotate(-45deg) translateX(-2px);
}
&::before {
transform: rotate(45deg) translateX(2px);
}
&-horizontal &-arrow {
display: none;
}

&-open&-inline &-arrow {
transform: translateY(-2px);
&::after {
transform: rotate(-45deg) translateX(-2.5px);
}
&::before {
transform: rotate(45deg) translateX(2.5px);
}
}
}
Expand Down Expand Up @@ -412,7 +396,7 @@
border-right: @menu-item-active-border-width solid @menu-highlight-color;
transform: scaleY(0.0001);
opacity: 0;
transition: transform 0.15s @ease-out, opacity 0.15s @ease-out;
transition: transform 0.15s ease-out, opacity 0.15s ease-out;
content: '';
}
}
Expand Down Expand Up @@ -457,7 +441,7 @@
&::after {
transform: scaleY(1);
opacity: 1;
transition: transform 0.15s @ease-in-out, opacity 0.15s @ease-in-out;
transition: transform 0.15s ease-in-out, opacity 0.15s ease-in-out;
}
}

Expand Down

0 comments on commit bc92ecd

Please sign in to comment.