From 24f58c20e1c3a673f0a60e5d76081d9301f8cee2 Mon Sep 17 00:00:00 2001 From: jiang <155259966@qq.com> Date: Thu, 27 Jul 2017 19:43:45 +0800 Subject: [PATCH] fix menu-anim (#6955) * fix menu-anim * fix menu-anim * update * remove space * fix test * Improve code style * submeu-title use color transition * sync motion-collapse time * snyc padding --- components/menu/__tests__/index.test.js | 13 ++++++---- components/menu/index.tsx | 22 +++++++++++++---- components/menu/style/index.less | 33 ++++++++++++++++--------- components/style/core/motion.less | 2 +- 4 files changed, 47 insertions(+), 23 deletions(-) diff --git a/components/menu/__tests__/index.test.js b/components/menu/__tests__/index.test.js index 233b14b6c6..313fb91c08 100644 --- a/components/menu/__tests__/index.test.js +++ b/components/menu/__tests__/index.test.js @@ -150,11 +150,14 @@ describe('Menu', () => { expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-inline')).toBe(true); expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(false); wrapper.setProps({ inlineCollapsed: true }); - expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-vertical')).toBe(true); - expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(true); - wrapper.setProps({ inlineCollapsed: false }); - expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-inline')).toBe(true); - expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(false); + setTimeout(() => { + // 动画结束后套样式; + expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-vertical')).toBe(true); + expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(true); + wrapper.setProps({ inlineCollapsed: false }); + expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-inline')).toBe(true); + expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(false); + }, 300); }); it('should open submenu when click submenu title (inline)', async () => { diff --git a/components/menu/index.tsx b/components/menu/index.tsx index 2074d4f67c..38a129bc7d 100644 --- a/components/menu/index.tsx +++ b/components/menu/index.tsx @@ -135,8 +135,12 @@ export default class Menu extends React.Component { } } getRealMenuMode() { + const inlineCollapsed = this.getInlineCollapsed(); + if (this.switchModeFromInline && inlineCollapsed) { + return 'inline'; + } const { mode } = this.props; - return this.getInlineCollapsed() ? 'vertical' : mode; + return inlineCollapsed ? 'vertical' : mode; } getInlineCollapsed() { const { inlineCollapsed } = this.props; @@ -145,9 +149,8 @@ export default class Menu extends React.Component { } return inlineCollapsed; } - getMenuOpenAnimation() { + getMenuOpenAnimation(menuMode) { const { openAnimation, openTransitionName } = this.props; - const menuMode = this.getRealMenuMode(); let menuOpenAnimation = openAnimation || openTransitionName; if (openAnimation === undefined && openTransitionName === undefined) { switch (menuMode) { @@ -165,17 +168,26 @@ export default class Menu extends React.Component { } break; case 'inline': - menuOpenAnimation = animation; + menuOpenAnimation = { + ...animation, + leave: (node, done) => animation.leave(node, () => { + // Make sure inline menu leave animation finished before mode is switched + this.switchModeFromInline = false; + this.setState({}); + done(); + }), + }; break; default: } } return menuOpenAnimation; } + render() { const { prefixCls, className, theme } = this.props; const menuMode = this.getRealMenuMode(); - const menuOpenAnimation = this.getMenuOpenAnimation(); + const menuOpenAnimation = this.getMenuOpenAnimation(menuMode); const menuClassName = classNames(className, `${prefixCls}-${theme}`, { [`${prefixCls}-inline-collapsed`]: this.getInlineCollapsed(), diff --git a/components/menu/style/index.less b/components/menu/style/index.less index 6d7b5573b9..397d7d01c5 100644 --- a/components/menu/style/index.less +++ b/components/menu/style/index.less @@ -2,6 +2,7 @@ @import "../../style/mixins/index"; @menu-prefix-cls: ~"@{ant-prefix}-menu"; +@menu-collapsed-width: 64px; // default theme .@{menu-prefix-cls} { @@ -14,6 +15,7 @@ color: @text-color; background: @component-background; line-height: 46px; + transition: background .3s @ease-in-out, width .15s @ease-in-out; &-hidden { display: none; @@ -35,7 +37,12 @@ &-submenu, &-submenu-title { cursor: pointer; - transition: all .3s; + } + &-submenu, &-submenu-inline { + transition: border-color .3s @ease-in-out, background .3s @ease-in-out, padding .15s @ease-in-out; + } + &-item, &-submenu-title { + transition: color .3s @ease-in-out, border-color .3s @ease-in-out, background .3s @ease-in-out, padding .15s @ease-in-out; } &-item:active, @@ -45,6 +52,7 @@ &-submenu &-sub { cursor: initial; + transition: background .3s @ease-in-out, padding .3s @ease-in-out; } &-item > a { @@ -133,7 +141,8 @@ bottom: 0; border-right: 3px solid @primary-color; transform: scaleY(.0001); - transition: all .2s; + opacity: 0; + transition: transform .15s @ease-out, opacity .15s @ease-out; } } } @@ -162,23 +171,24 @@ &-inline { width: 100%; - transition: width .24s; .@{menu-prefix-cls}-selected, .@{menu-prefix-cls}-item-selected { &:after { + transition: transform .15s @ease-in-out, opacity .15s @ease-in-out; + opacity: 1; transform: scaleY(1); } } } + &-vertical&-inline-collapsed, &-inline-collapsed { - width: 64px; - transition: all .3s; + width: @menu-collapsed-width; > .@{menu-prefix-cls}-item, > .@{menu-prefix-cls}-submenu > .@{menu-prefix-cls}-submenu-title { - text-align: center; left: 0; text-overflow: clip; + padding: 0 (@menu-collapsed-width - 16px) / 2; &:after { display: none; } @@ -188,7 +198,6 @@ margin: 0; + span { max-width: 0; - visibility: hidden; display: inline-block; opacity: 0; } @@ -234,13 +243,12 @@ position: relative; display: block; white-space: nowrap; - .@{iconfont-css-prefix} { min-width: 14px; margin-right: 8px; - transition: all .3s; + transition: font-size .15s @ease-out, margin .3s @ease-in-out; + span { - transition: all .3s; + transition: opacity .3s @ease-in-out, width .3s @ease-in-out; opacity: 1; } } @@ -261,6 +269,9 @@ > .@{menu-prefix-cls} { background-color: @component-background; border-radius: @border-radius-base; + &-submenu-title:after { + transition: transform .3s @ease-in-out; + } } &-vertical > .@{menu-prefix-cls}-submenu-title:after { @@ -271,7 +282,6 @@ text-transform: none; text-rendering: auto; position: absolute; - transition: transform .3s; content: "\e61d"; right: 16px; .ie-rotate(3); @@ -286,7 +296,6 @@ text-transform: none; text-rendering: auto; position: absolute; - transition: transform .3s; content: "\e61d"; right: 16px; top: 0; diff --git a/components/style/core/motion.less b/components/style/core/motion.less index 7d3ac83118..e47ce302a8 100644 --- a/components/style/core/motion.less +++ b/components/style/core/motion.less @@ -10,6 +10,6 @@ .ant-motion-collapse { overflow: hidden; &-active { - transition: height .12s, opacity .12s !important; + transition: height .15s @ease-in-out, opacity .15s @ease-in-out !important; } }