diff --git a/packages/menu/src/menu-mixin.js b/packages/menu/src/menu-mixin.js index 27ce88949..453b26450 100644 --- a/packages/menu/src/menu-mixin.js +++ b/packages/menu/src/menu-mixin.js @@ -1,4 +1,5 @@ export default { + inject: ['rootMenu'], computed: { indexPath() { const path = [this.index]; @@ -11,16 +12,6 @@ export default { } return path; }, - rootMenu() { - let parent = this.$parent; - while ( - parent && - parent.$options.componentName !== 'ElMenu' - ) { - parent = parent.$parent; - } - return parent; - }, parentMenu() { let parent = this.$parent; while ( diff --git a/packages/menu/src/menu.vue b/packages/menu/src/menu.vue index e93ba8f68..99a8fabc2 100644 --- a/packages/menu/src/menu.vue +++ b/packages/menu/src/menu.vue @@ -127,6 +127,9 @@ computed: { hoverBackground() { return this.backgroundColor ? this.mixColor(this.backgroundColor, 0.2) : ''; + }, + isMenuPopup() { + return this.mode === 'horizontal' || (this.mode === 'vertical' && this.collapse); } }, watch: { @@ -140,6 +143,7 @@ collapse(value) { if (value) this.openedMenus = []; + this.broadcast('ElSubmenu', 'toggle-collapse', value); } }, methods: { diff --git a/packages/menu/src/submenu.vue b/packages/menu/src/submenu.vue index 80c7a83bf..1d9754019 100644 --- a/packages/menu/src/submenu.vue +++ b/packages/menu/src/submenu.vue @@ -1,53 +1,31 @@ - diff --git a/packages/theme-chalk/src/menu.scss b/packages/theme-chalk/src/menu.scss index d31775cef..924c4c999 100644 --- a/packages/theme-chalk/src/menu.scss +++ b/packages/theme-chalk/src/menu.scss @@ -8,6 +8,7 @@ font-size: 14px; color: $--menu-item-color; padding: 0 20px; + list-style: none; cursor: pointer; position: relative; transition: border-color .3s, background-color .3s, color .3s; @@ -24,21 +25,14 @@ background-color: $--menu-item-fill; @include utils-clearfix; - & li { - list-style: none; - } - @include m(horizontal) { border-right: none; border-bottom: solid 1px #e6e6e6; - & .el-menu-item { + & > .el-menu-item { float: left; height: 60px; line-height: 60px; margin: 0; - cursor: pointer; - position: relative; - box-sizing: border-box; border-bottom: 2px solid transparent; color: $--color-text-secondary; @@ -51,26 +45,22 @@ background-color: #fff; } } - & .el-submenu { + & > .el-submenu { float: left; - position: relative; - &:focus { + + &:focus, + &:hover { outline: none; - > .el-submenu__title { + .el-submenu__title { color: $--color-text-primary; } } - > .el-menu { - position: absolute; - top: 65px; - left: 0; - border: none; - padding: 5px 0; - background-color: $--color-white; - z-index: 100; - min-width: 100%; - box-shadow: $--box-shadow-light; - border-radius: $--border-radius-small; + + &.is-active { + .el-submenu__title { + border-bottom: 2px solid $--color-primary; + color: $--color-text-primary; + } } & .el-submenu__title { @@ -78,20 +68,11 @@ line-height: 60px; border-bottom: 2px solid transparent; color: $--color-text-secondary; - } - .el-submenu__title:hover { - background-color: #fff; + &:hover { + background-color: #fff; + } } - - & .el-menu-item { - background-color: $--color-white; - float: none; - height: 36px; - line-height: 36px; - padding: 0 10px; - } - & .el-submenu__icon-arrow { position: static; vertical-align: middle; @@ -99,14 +80,26 @@ margin-top: -3px; } } + & .el-menu { + & .el-menu-item { + background-color: $--color-white; + float: none; + height: 36px; + line-height: 36px; + padding: 0 10px; + color: $--color-text-secondary; + + &.is-active { + color: $--color-text-primary; + } + } + } & .el-menu-item:hover, - & .el-submenu__title:hover, & .el-menu-item:focus { outline: none; color: $--color-text-primary; } - & > .el-menu-item.is-active, - & > .el-submenu.is-active .el-submenu__title { + & > .el-menu-item.is-active { border-bottom: 2px solid $--color-primary; color: $--color-text-primary; } @@ -162,6 +155,21 @@ } } } + @include m(popup) { + z-index: 100; + min-width: 200px; + border: none; + padding: 5px 0; + border-radius: $--border-radius-small; + box-shadow: $--box-shadow-light; + + &-bottom-start { + margin-top: 5px; + } + &-right-start { + margin-left: 5px; + } + } } @include b(menu-item) { @include menu-item; @@ -198,6 +206,10 @@ } @include b(submenu) { + list-style: none; + margin: 0; + padding-left: 0; + @include e(title) { position: relative; @include menu-item; diff --git a/src/utils/vue-popper.js b/src/utils/vue-popper.js index a18abe338..57b693c41 100644 --- a/src/utils/vue-popper.js +++ b/src/utils/vue-popper.js @@ -16,6 +16,10 @@ const stop = e => e.stopPropagation(); */ export default { props: { + transformOrigin: { + type: [Boolean, String], + default: true + }, placement: { type: String, default: 'bottom' @@ -139,6 +143,7 @@ export default { }, resetTransformOrigin() { + if (!this.transformOrigin) return; let placementMap = { top: 'bottom', bottom: 'top', @@ -147,7 +152,9 @@ export default { }; let placement = this.popperJS._popper.getAttribute('x-placement').split('-')[0]; let origin = placementMap[placement]; - this.popperJS._popper.style.transformOrigin = ['top', 'bottom'].indexOf(placement) > -1 ? `center ${ origin }` : `${ origin } center`; + this.popperJS._popper.style.transformOrigin = typeof this.transformOrigin === 'string' + ? this.transformOrigin + : ['top', 'bottom'].indexOf(placement) > -1 ? `center ${ origin }` : `${ origin } center`; }, appendArrow(element) { diff --git a/test/unit/specs/menu.spec.js b/test/unit/specs/menu.spec.js index ecdd11e63..fdac1b90a 100644 --- a/test/unit/specs/menu.spec.js +++ b/test/unit/specs/menu.spec.js @@ -270,7 +270,7 @@ describe('Menu', () => { var submenu = vm.$refs.submenu; triggerEvent(submenu.$el, 'mouseenter'); setTimeout(_ => { - expect(submenu.$el.querySelector('.el-menu').style.display).to.not.ok; + expect(document.body.querySelector('.el-menu--popup').parentElement.style.display).to.not.ok; done(); }, 500); }); @@ -301,10 +301,10 @@ describe('Menu', () => { triggerElm.click(); setTimeout(_ => { - expect(submenu.$el.querySelector('.el-menu').style.display).to.not.ok; + expect(document.body.querySelector('.el-menu--popup').parentElement.style.display).to.not.ok; triggerElm.click(); setTimeout(_ => { - expect(submenu.$el.querySelector('.el-menu').style.display).to.be.equal('none'); + expect(document.body.querySelector('.el-menu--popup').parentElement.style.display).to.be.equal('none'); done(); }, 1000); }, 500);