From 2ca66f4121c51a42bc793ba7a44a16ce28795bf8 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Sun, 23 May 2021 21:42:35 +0800 Subject: [PATCH] refactor: menu --- components/old-menu/MenuItem.tsx | 66 --- components/old-menu/SubMenu.tsx | 42 -- .../__tests__/__snapshots__/demo.test.js.snap | 327 ----------- components/old-menu/__tests__/demo.test.js | 3 - components/old-menu/__tests__/index.test.js | 542 ------------------ components/old-menu/index.tsx | 323 ----------- components/old-menu/style/dark.less | 139 ----- components/old-menu/style/index.less | 515 ----------------- components/old-menu/style/index.ts | 6 - 9 files changed, 1963 deletions(-) delete mode 100644 components/old-menu/MenuItem.tsx delete mode 100644 components/old-menu/SubMenu.tsx delete mode 100644 components/old-menu/__tests__/__snapshots__/demo.test.js.snap delete mode 100644 components/old-menu/__tests__/demo.test.js delete mode 100644 components/old-menu/__tests__/index.test.js delete mode 100644 components/old-menu/index.tsx delete mode 100644 components/old-menu/style/dark.less delete mode 100644 components/old-menu/style/index.less delete mode 100644 components/old-menu/style/index.ts diff --git a/components/old-menu/MenuItem.tsx b/components/old-menu/MenuItem.tsx deleted file mode 100644 index fa4ac904e..000000000 --- a/components/old-menu/MenuItem.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { defineComponent, inject } from 'vue'; -import { Item, itemProps } from '../vc-menu'; -import { getOptionProps, getSlot } from '../_util/props-util'; -import Tooltip, { TooltipProps } from '../tooltip'; -import { SiderContextProps } from '../layout/Sider'; -import { injectExtraPropsKey } from '../vc-menu/FunctionProvider'; -import PropTypes from '../_util/vue-types'; - -export default defineComponent({ - name: 'MenuItem', - inheritAttrs: false, - props: { - ...itemProps, - onClick: PropTypes.func, - }, - isMenuItem: true, - setup() { - return { - getInlineCollapsed: inject<() => boolean>('getInlineCollapsed', () => false), - layoutSiderContext: inject('layoutSiderContext', {}), - injectExtraProps: inject(injectExtraPropsKey, () => ({})), - }; - }, - methods: { - onKeyDown(e: HTMLElement) { - (this.$refs.menuItem as any).onKeyDown(e); - }, - }, - render() { - const props = getOptionProps(this); - const { level, title, rootPrefixCls } = { ...props, ...this.injectExtraProps } as any; - const { getInlineCollapsed, $attrs: attrs } = this; - const inlineCollapsed = getInlineCollapsed(); - let tooltipTitle = title; - const children = getSlot(this); - if (typeof title === 'undefined') { - tooltipTitle = level === 1 ? children : ''; - } else if (title === false) { - tooltipTitle = ''; - } - const tooltipProps: TooltipProps = { - title: tooltipTitle, - }; - const siderCollapsed = this.layoutSiderContext.sCollapsed; - if (!siderCollapsed && !inlineCollapsed) { - tooltipProps.title = null; - // Reset `visible` to fix control mode tooltip display not correct - // ref: https://github.com/ant-design/ant-design/issues/16742 - tooltipProps.visible = false; - } - - const itemProps = { - ...props, - title, - ...attrs, - ref: 'menuItem', - }; - const toolTipProps: TooltipProps = { - ...tooltipProps, - placement: 'right', - overlayClassName: `${rootPrefixCls}-inline-collapsed-tooltip`, - }; - const item = {children}; - return {item}; - }, -}); diff --git a/components/old-menu/SubMenu.tsx b/components/old-menu/SubMenu.tsx deleted file mode 100644 index 24edc9dbf..000000000 --- a/components/old-menu/SubMenu.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { defineComponent, inject } from 'vue'; -import { SubMenu as VcSubMenu } from '../vc-menu'; -import classNames from '../_util/classNames'; -import { injectExtraPropsKey } from '../vc-menu/FunctionProvider'; - -export type MenuTheme = 'light' | 'dark'; - -export interface MenuContextProps { - inlineCollapsed?: boolean; - theme?: MenuTheme; -} - -export default defineComponent({ - name: 'ASubMenu', - isSubMenu: true, - inheritAttrs: false, - props: { ...VcSubMenu.props }, - setup() { - return { - menuPropsContext: inject('menuPropsContext', {}), - injectExtraProps: inject(injectExtraPropsKey, () => ({})), - }; - }, - methods: { - onKeyDown(e: Event) { - (this.$refs.subMenu as any).onKeyDown(e); - }, - }, - - render() { - const { $slots, $attrs } = this; - const { rootPrefixCls, popupClassName } = { ...this.$props, ...this.injectExtraProps } as any; - const { theme: antdMenuTheme } = this.menuPropsContext; - const props = { - ...this.$props, - popupClassName: classNames(`${rootPrefixCls}-${antdMenuTheme}`, popupClassName), - ref: 'subMenu', - ...$attrs, - } as any; - return ; - }, -}); diff --git a/components/old-menu/__tests__/__snapshots__/demo.test.js.snap b/components/old-menu/__tests__/__snapshots__/demo.test.js.snap deleted file mode 100644 index 4266989b9..000000000 --- a/components/old-menu/__tests__/__snapshots__/demo.test.js.snap +++ /dev/null @@ -1,327 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`renders ./antdv-demo/docs/menu/demo/horizontal.md correctly 1`] = ` -
- -
-`; - -exports[`renders ./antdv-demo/docs/menu/demo/inline.md correctly 1`] = ` -
- -
-`; - -exports[`renders ./antdv-demo/docs/menu/demo/inline-collapsed.md correctly 1`] = ` -
- -
-`; - -exports[`renders ./antdv-demo/docs/menu/demo/sider-current.md correctly 1`] = ` -
- -
-`; - -exports[`renders ./antdv-demo/docs/menu/demo/switch-mode.md correctly 1`] = ` -
Change Mode Change Theme

- -
-`; - -exports[`renders ./antdv-demo/docs/menu/demo/template.md correctly 1`] = ` -
- -
-`; - -exports[`renders ./antdv-demo/docs/menu/demo/theme.md correctly 1`] = ` -


- -
-`; - -exports[`renders ./antdv-demo/docs/menu/demo/vertical.md correctly 1`] = ` -
- -
-`; diff --git a/components/old-menu/__tests__/demo.test.js b/components/old-menu/__tests__/demo.test.js deleted file mode 100644 index ad45d6588..000000000 --- a/components/old-menu/__tests__/demo.test.js +++ /dev/null @@ -1,3 +0,0 @@ -import demoTest from '../../../tests/shared/demoTest'; - -demoTest('menu'); diff --git a/components/old-menu/__tests__/index.test.js b/components/old-menu/__tests__/index.test.js deleted file mode 100644 index ed370bc10..000000000 --- a/components/old-menu/__tests__/index.test.js +++ /dev/null @@ -1,542 +0,0 @@ -import { mount } from '@vue/test-utils'; -import { asyncExpect } from '@/tests/utils'; -import Menu from '..'; -import { InboxOutlined, PieChartOutlined } from '@ant-design/icons-vue'; -import mountTest from '../../../tests/shared/mountTest'; - -const { SubMenu } = Menu; -function $$(className) { - return document.body.querySelectorAll(className); -} -describe('Menu', () => { - mountTest({ - render() { - return ( -
- - - - - -
- ); - }, - }); - beforeEach(() => { - document.body.innerHTML = ''; - // jest.useFakeTimers() - }); - - afterEach(() => { - // jest.useRealTimers() - }); - it('If has select nested submenu item ,the menu items on the grandfather level should be highlight', async () => { - mount( - { - render() { - return ( - - - Option 1 - Option 2 - - Option 3 - Option 4 - - - menu2 - - ); - }, - }, - { attachTo: 'body', sync: false }, - ); - await asyncExpect(() => { - expect($$('.ant-menu-submenu-selected').length).toBe(1); - }); - }); - it('should accept defaultOpenKeys in mode horizontal', async () => { - mount( - { - render() { - return ( - - - Option 1 - Option 2 - - menu2 - - ); - }, - }, - { attachTo: 'body', sync: false }, - ); - await asyncExpect(() => { - expect($$('.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); - }); - }); - - it('should accept defaultOpenKeys in mode inline', async () => { - mount( - { - render() { - return ( - - - Option 1 - Option 2 - - menu2 - - ); - }, - }, - { attachTo: 'body', sync: false }, - ); - await asyncExpect(() => { - expect($$('.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); - }); - }); - - it('should accept defaultOpenKeys in mode vertical', async () => { - mount( - { - render() { - return ( - - - Option 1 - Option 2 - - menu2 - - ); - }, - }, - { attachTo: 'body', sync: false }, - ); - await asyncExpect(() => { - expect($$('.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); - }); - }); - - it('horizontal', async () => { - const wrapper = mount( - { - props: { - openKeys: { - type: Array, - default() { - return ['1']; - }, - }, - }, - render() { - return ( - - - Option 1 - Option 2 - - menu2 - - ); - }, - }, - { attachTo: 'body', sync: false }, - ); - await asyncExpect(() => { - expect($$('.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); - }); - wrapper.setProps({ openKeys: [] }); - await asyncExpect(() => { - expect($$('.ant-menu-sub')[0].parentElement.style.display).toBe('none'); - }, 500); - - wrapper.setProps({ openKeys: ['1'] }); - await asyncExpect(() => { - expect($$('.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); - }, 0); - }); - - it('inline', async () => { - const wrapper = mount( - { - props: { - openKeys: { - type: Array, - default() { - return ['1']; - }, - }, - }, - render() { - return ( - - - Option 1 - Option 2 - - menu2 - - ); - }, - }, - { attachTo: 'body', sync: false }, - ); - await asyncExpect(() => { - expect($$('.ant-menu-sub')[0].style.display).not.toBe('none'); - }); - wrapper.setProps({ openKeys: [] }); - await asyncExpect(() => { - expect($$('.ant-menu-sub')[0].style.display).toBe('none'); - }, 0); - wrapper.setProps({ openKeys: ['1'] }); - await asyncExpect(() => { - expect($$('.ant-menu-sub')[0].style.display).not.toBe('none'); - }, 0); - }); - - it('vertical', async () => { - const wrapper = mount( - { - props: { - openKeys: { - type: Array, - default() { - return ['1']; - }, - }, - }, - render() { - return ( - - - Option 1 - Option 2 - - menu2 - - ); - }, - }, - { attachTo: 'body', sync: false }, - ); - await asyncExpect(() => { - expect($$('.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); - }); - wrapper.setProps({ openKeys: [] }); - await asyncExpect(() => { - expect($$('.ant-menu-sub')[0].parentElement.style.display).toBe('none'); - }, 500); - wrapper.setProps({ openKeys: ['1'] }); - await asyncExpect(() => { - expect($$('.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); - }, 0); - }); - - // https://github.com/ant-design/ant-design/pulls/4677 - // https://github.com/ant-design/ant-design/issues/4692 - // TypeError: Cannot read property 'indexOf' of undefined - it('pr #4677 and issue #4692', () => { - const wrapper = mount( - { - render() { - return ( - - - menu1 - menu2 - - - ); - }, - }, - { attachTo: 'body', sync: false }, - ); - wrapper.vm.$forceUpdate(); - // just expect no error emit - }); - - it('should always follow openKeys when mode is switched', async () => { - const wrapper = mount( - { - props: { - mode: { - type: String, - default: 'inline', - }, - }, - render() { - return ( - - - Option 1 - Option 2 - - menu2 - - ); - }, - }, - { attachTo: 'body', sync: false }, - ); - await asyncExpect(() => { - expect($$('ul.ant-menu-sub')[0].style.display).not.toBe('none'); - }); - wrapper.setProps({ mode: 'vertical' }); - await asyncExpect(() => { - expect($$('ul.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); - }, 0); - wrapper.setProps({ mode: 'inline' }); - await asyncExpect(() => { - expect($$('ul.ant-menu-sub')[0].style.display).not.toBe('none'); - }, 0); - }); - - it('should always follow openKeys when inlineCollapsed is switched', async () => { - const wrapper = mount( - { - props: { - inlineCollapsed: { - type: Boolean, - default: false, - }, - }, - render() { - return ( - - - - Option - - - Option - Option - - - ); - }, - }, - { attachTo: 'body', sync: false }, - ); - await asyncExpect(() => { - expect(wrapper.findAll('ul.ant-menu-sub')[0].classes()).toContain('ant-menu-inline'); - expect($$('ul.ant-menu-sub')[0].style.display).not.toBe('none'); - }, 0); - wrapper.setProps({ inlineCollapsed: true }); - await asyncExpect(() => { - // 动画完成后的回调 - wrapper.vm.$refs.menu.switchModeFromInline = false; - wrapper.vm.$forceUpdate(); - }); - // await asyncExpect(() => { - // wrapper.trigger('transitionend', { propertyName: 'width' }); - // }); - // await asyncExpect(() => { - // expect(wrapper.findAll('ul.ant-menu-root')[0].classes()).toContain('ant-menu-vertical'); - // expect(wrapper.findAll('ul.ant-menu-sub').length).toBe(0); - // }, 500); - wrapper.setProps({ inlineCollapsed: false }); - await asyncExpect(() => { - expect(wrapper.findAll('ul.ant-menu-sub')[0].classes()).toContain('ant-menu-inline'); - expect($$('ul.ant-menu-sub')[0].style.display).not.toBe('none'); - }, 0); - }); - - it('inlineCollapsed should works well when specify a not existed default openKeys', async () => { - const wrapper = mount( - { - props: { - inlineCollapsed: { - type: Boolean, - default: false, - }, - }, - render() { - return ( - - - - Option - - - Option - Option - - - ); - }, - }, - { attachTo: 'body', sync: false }, - ); - await asyncExpect(() => { - expect(wrapper.findAll('.ant-menu-sub').length).toBe(0); - }); - wrapper.setProps({ inlineCollapsed: true }); - await asyncExpect(() => { - // 动画完成后的回调 - wrapper.vm.$refs.menu.switchModeFromInline = false; - wrapper.vm.$forceUpdate(); - }); - // await asyncExpect(() => { - // wrapper.trigger('transitionend', { propertyName: 'width' }); - // }); - // await asyncExpect(() => { - // $$('.ant-menu-submenu-title')[0].dispatchEvent(new MouseEvent('mouseenter')); - // }); - // await asyncExpect(() => { - // expect(wrapper.findAll('.ant-menu-submenu')[0].classes()).toContain( - // 'ant-menu-submenu-vertical', - // ); - // expect(wrapper.findAll('.ant-menu-submenu')[0].classes()).toContain('ant-menu-submenu-open'); - // expect($$('ul.ant-menu-sub')[0].className).toContain('ant-menu-vertical'); - // expect($$('ul.ant-menu-sub')[0].style.display).not.toBe('none'); - // }, 500); - }); - - describe('open submenu when click submenu title', () => { - beforeEach(() => { - document.body.innerHTML = ''; - }); - - const toggleMenu = (wrapper, index, event) => { - wrapper.findAll('.ant-menu-submenu-title')[index].trigger(event); - }; - - it('inline', async () => { - const wrapper = mount( - { - render() { - return ( - - - Option 1 - Option 2 - - menu2 - - ); - }, - }, - { attachTo: 'body', sync: false }, - ); - await asyncExpect(() => { - expect($$('.ant-menu-sub').length).toBe(0); - toggleMenu(wrapper, 0, 'click'); - }, 0); - await asyncExpect(() => { - expect($$('.ant-menu-sub').length).toBe(1); - expect($$('.ant-menu-sub')[0].style.display).not.toBe('none'); - toggleMenu(wrapper, 0, 'click'); - }, 500); - await asyncExpect(() => { - expect($$('.ant-menu-sub')[0].style.display).toBe('none'); - }, 500); - }); - - it('vertical', async () => { - const wrapper = mount( - { - render() { - return ( - - - Option 1 - Option 2 - - menu2 - - ); - }, - }, - { attachTo: 'body', sync: false }, - ); - await asyncExpect(() => { - expect($$('.ant-menu-sub').length).toBe(0); - toggleMenu(wrapper, 0, 'mouseenter'); - }, 0); - await asyncExpect(() => { - expect($$('.ant-menu-sub').length).toBe(1); - expect($$('.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); - toggleMenu(wrapper, 0, 'mouseleave'); - }, 500); - await asyncExpect(() => { - expect($$('.ant-menu-sub')[0].parentElement.style.display).toBe('none'); - }, 500); - }); - - it('horizontal', async () => { - const wrapper = mount( - { - render() { - return ( - - - Option 1 - Option 2 - - menu2 - - ); - }, - }, - { attachTo: 'body', sync: false }, - ); - await asyncExpect(() => { - expect($$('.ant-menu-sub').length).toBe(0); - toggleMenu(wrapper, 1, 'mouseenter'); - }, 100); - await asyncExpect(() => { - expect($$('.ant-menu-sub').length).toBe(1); - expect($$('.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); - toggleMenu(wrapper, 1, 'mouseleave'); - }, 500); - await asyncExpect(() => { - expect($$('.ant-menu-sub')[0].parentElement.style.display).toBe('none'); - }, 500); - }); - }); - - it('inline title', async () => { - const wrapper = mount( - { - render() { - return ( - - - - - Option 1 - test - - - - ); - }, - }, - { sync: false, attachTo: 'body' }, - ); - - wrapper.find('.ant-menu-item').trigger('mouseenter'); - await asyncExpect(() => { - const text = $$('.ant-tooltip-inner')[0].textContent; - expect(text).toBe('bamboo lucky'); - }, 500); - }); -}); diff --git a/components/old-menu/index.tsx b/components/old-menu/index.tsx deleted file mode 100644 index 842ace832..000000000 --- a/components/old-menu/index.tsx +++ /dev/null @@ -1,323 +0,0 @@ -import { defineComponent, inject, provide, toRef, App, ExtractPropTypes, Plugin } from 'vue'; -import omit from 'omit.js'; -import VcMenu, { Divider, ItemGroup } from '../vc-menu'; -import SubMenu from './SubMenu'; -import PropTypes from '../_util/vue-types'; -import animation from '../_util/openAnimation'; -import warning from '../_util/warning'; -import Item from './MenuItem'; -import { hasProp, getOptionProps } from '../_util/props-util'; -import BaseMixin from '../_util/BaseMixin'; -import commonPropsType from '../vc-menu/commonPropsType'; -import { defaultConfigProvider } from '../config-provider'; -import { SiderContextProps } from '../layout/Sider'; -import { tuple } from '../_util/type'; -// import raf from '../_util/raf'; - -export const MenuMode = PropTypes.oneOf([ - 'vertical', - 'vertical-left', - 'vertical-right', - 'horizontal', - 'inline', -]); - -export const menuProps = { - ...commonPropsType, - theme: PropTypes.oneOf(tuple('light', 'dark')).def('light'), - mode: MenuMode.def('vertical'), - selectable: PropTypes.looseBool, - selectedKeys: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])), - defaultSelectedKeys: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])), - openKeys: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])), - defaultOpenKeys: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])), - openAnimation: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), - openTransitionName: PropTypes.string, - prefixCls: PropTypes.string, - multiple: PropTypes.looseBool, - inlineIndent: PropTypes.number.def(24), - inlineCollapsed: PropTypes.looseBool, - isRootMenu: PropTypes.looseBool.def(true), - focusable: PropTypes.looseBool.def(false), - onOpenChange: PropTypes.func, - onSelect: PropTypes.func, - onDeselect: PropTypes.func, - onClick: PropTypes.func, - onMouseenter: PropTypes.func, - onSelectChange: PropTypes.func, -}; - -export type MenuProps = Partial>; - -const Menu = defineComponent({ - name: 'AMenu', - mixins: [BaseMixin], - inheritAttrs: false, - props: menuProps, - Divider: { ...Divider, name: 'AMenuDivider' }, - Item: { ...Item, name: 'AMenuItem' }, - SubMenu: { ...SubMenu, name: 'ASubMenu' }, - ItemGroup: { ...ItemGroup, name: 'AMenuItemGroup' }, - emits: [ - 'update:selectedKeys', - 'update:openKeys', - 'mouseenter', - 'openChange', - 'click', - 'selectChange', - 'select', - 'deselect', - ], - setup() { - const layoutSiderContext = inject('layoutSiderContext', {}); - const layoutSiderCollapsed = toRef(layoutSiderContext, 'sCollapsed'); - return { - configProvider: inject('configProvider', defaultConfigProvider), - layoutSiderContext, - layoutSiderCollapsed, - propsUpdating: false, - switchingModeFromInline: false, - leaveAnimationExecutedWhenInlineCollapsed: false, - inlineOpenKeys: [], - }; - }, - data() { - const props: MenuProps = getOptionProps(this); - warning( - !('inlineCollapsed' in props && props.mode !== 'inline'), - 'Menu', - "`inlineCollapsed` should only be used when Menu's `mode` is inline.", - ); - let sOpenKeys: (number | string)[]; - - if ('openKeys' in props) { - sOpenKeys = props.openKeys; - } else if ('defaultOpenKeys' in props) { - sOpenKeys = props.defaultOpenKeys; - } - return { - sOpenKeys, - }; - }, - // beforeUnmount() { - // raf.cancel(this.mountRafId); - // }, - watch: { - mode(val, oldVal) { - if (oldVal === 'inline' && val !== 'inline') { - this.switchingModeFromInline = true; - } - }, - openKeys(val) { - this.setState({ sOpenKeys: val }); - }, - inlineCollapsed(val) { - this.collapsedChange(val); - }, - layoutSiderCollapsed(val) { - this.collapsedChange(val); - }, - }, - created() { - provide('getInlineCollapsed', this.getInlineCollapsed); - provide('menuPropsContext', this.$props); - }, - updated() { - this.propsUpdating = false; - }, - methods: { - collapsedChange(val: unknown) { - if (this.propsUpdating) { - return; - } - this.propsUpdating = true; - if (!hasProp(this, 'openKeys')) { - if (val) { - this.switchingModeFromInline = true; - this.inlineOpenKeys = this.sOpenKeys; - this.setState({ sOpenKeys: [] }); - } else { - this.setState({ sOpenKeys: this.inlineOpenKeys }); - this.inlineOpenKeys = []; - } - } else if (val) { - // 缩起时,openKeys置为空的动画会闪动,react可以通过是否传递openKeys避免闪动,vue不是很方便动态传递openKeys - this.switchingModeFromInline = true; - } - }, - restoreModeVerticalFromInline() { - if (this.switchingModeFromInline) { - this.switchingModeFromInline = false; - this.$forceUpdate(); - } - }, - // Restore vertical mode when menu is collapsed responsively when mounted - // https://github.com/ant-design/ant-design/issues/13104 - // TODO: not a perfect solution, looking a new way to avoid setting switchingModeFromInline in this situation - handleMouseEnter(e: Event) { - this.restoreModeVerticalFromInline(); - this.$emit('mouseenter', e); - }, - handleTransitionEnd(e: TransitionEvent) { - // when inlineCollapsed menu width animation finished - // https://github.com/ant-design/ant-design/issues/12864 - const widthCollapsed = e.propertyName === 'width' && e.target === e.currentTarget; - - // Fix SVGElement e.target.className.indexOf is not a function - // https://github.com/ant-design/ant-design/issues/15699 - const { className } = e.target as SVGAnimationElement | HTMLElement; - // SVGAnimatedString.animVal should be identical to SVGAnimatedString.baseVal, unless during an animation. - const classNameValue = - Object.prototype.toString.call(className) === '[object SVGAnimatedString]' - ? className.animVal - : className; - - // Fix for , the width transition won't trigger when menu is collapsed - // https://github.com/ant-design/ant-design-pro/issues/2783 - const iconScaled = e.propertyName === 'font-size' && classNameValue.indexOf('anticon') >= 0; - - if (widthCollapsed || iconScaled) { - this.restoreModeVerticalFromInline(); - } - }, - handleClick(e: Event) { - this.handleOpenChange([]); - this.$emit('click', e); - }, - handleSelect(info) { - this.$emit('update:selectedKeys', info.selectedKeys); - this.$emit('select', info); - this.$emit('selectChange', info.selectedKeys); - }, - handleDeselect(info) { - this.$emit('update:selectedKeys', info.selectedKeys); - this.$emit('deselect', info); - this.$emit('selectChange', info.selectedKeys); - }, - handleOpenChange(openKeys: (number | string)[]) { - this.setOpenKeys(openKeys); - this.$emit('update:openKeys', openKeys); - this.$emit('openChange', openKeys); - }, - setOpenKeys(openKeys: (number | string)[]) { - if (!hasProp(this, 'openKeys')) { - this.setState({ sOpenKeys: openKeys }); - } - }, - getRealMenuMode() { - const inlineCollapsed = this.getInlineCollapsed(); - if (this.switchingModeFromInline && inlineCollapsed) { - return 'inline'; - } - const { mode } = this.$props; - return inlineCollapsed ? 'vertical' : mode; - }, - getInlineCollapsed() { - const { inlineCollapsed } = this.$props; - if (this.layoutSiderContext.sCollapsed !== undefined) { - return this.layoutSiderContext.sCollapsed; - } - return inlineCollapsed; - }, - getMenuOpenAnimation(menuMode: string) { - const { openAnimation, openTransitionName } = this.$props; - let menuOpenAnimation = openAnimation || openTransitionName; - if (openAnimation === undefined && openTransitionName === undefined) { - if (menuMode === 'horizontal') { - menuOpenAnimation = 'slide-up'; - } else if (menuMode === 'inline') { - menuOpenAnimation = animation; - } else { - // When mode switch from inline - // submenu should hide without animation - if (this.switchingModeFromInline) { - menuOpenAnimation = ''; - this.switchingModeFromInline = false; - } else { - menuOpenAnimation = 'zoom-big'; - } - } - } - return menuOpenAnimation; - }, - }, - render() { - const { layoutSiderContext } = this; - const { collapsedWidth } = layoutSiderContext; - const { getPopupContainer: getContextPopupContainer } = this.configProvider; - const props = getOptionProps(this); - const { prefixCls: customizePrefixCls, theme, getPopupContainer } = props; - const getPrefixCls = this.configProvider.getPrefixCls; - const prefixCls = getPrefixCls('menu', customizePrefixCls); - const menuMode = this.getRealMenuMode(); - const menuOpenAnimation = this.getMenuOpenAnimation(menuMode); - const { class: className, ...otherAttrs } = this.$attrs; - const menuClassName = { - [className as string]: className, - [`${prefixCls}-${theme}`]: true, - [`${prefixCls}-inline-collapsed`]: this.getInlineCollapsed(), - }; - - const menuProps = { - ...omit(props, [ - 'inlineCollapsed', - 'onUpdate:selectedKeys', - 'onUpdate:openKeys', - 'onSelectChange', - ]), - getPopupContainer: getPopupContainer || getContextPopupContainer, - openKeys: this.sOpenKeys, - mode: menuMode, - prefixCls, - ...otherAttrs, - onSelect: this.handleSelect, - onDeselect: this.handleDeselect, - onOpenChange: this.handleOpenChange, - onMouseenter: this.handleMouseEnter, - onTransitionend: this.handleTransitionEnd, - // children: getSlot(this), - }; - if (!hasProp(this, 'selectedKeys')) { - delete menuProps.selectedKeys; - } - - if (menuMode !== 'inline') { - // closing vertical popup submenu after click it - menuProps.onClick = this.handleClick; - menuProps.openTransitionName = menuOpenAnimation; - } else { - menuProps.onClick = (e: Event) => { - this.$emit('click', e); - }; - menuProps.openAnimation = menuOpenAnimation; - } - - // https://github.com/ant-design/ant-design/issues/8587 - const hideMenu = - this.getInlineCollapsed() && - (collapsedWidth === 0 || collapsedWidth === '0' || collapsedWidth === '0px'); - if (hideMenu) { - menuProps.openKeys = []; - } - - return ; - }, -}); - -/* istanbul ignore next */ -Menu.install = function(app: App) { - app.component(Menu.name, Menu); - app.component(Menu.Item.name, Menu.Item); - app.component(Menu.SubMenu.name, Menu.SubMenu); - app.component(Menu.Divider.name, Menu.Divider); - app.component(Menu.ItemGroup.name, Menu.ItemGroup); - return app; -}; - -export default Menu as typeof Menu & - Plugin & { - readonly Item: typeof Item; - readonly SubMenu: typeof SubMenu; - readonly Divider: typeof Divider; - readonly ItemGroup: typeof ItemGroup; - }; diff --git a/components/old-menu/style/dark.less b/components/old-menu/style/dark.less deleted file mode 100644 index 03d837a6a..000000000 --- a/components/old-menu/style/dark.less +++ /dev/null @@ -1,139 +0,0 @@ -.@{menu-prefix-cls} { - // dark theme - &-dark, - &-dark &-sub { - color: @menu-dark-color; - background: @menu-dark-bg; - .@{menu-prefix-cls}-submenu-title .@{menu-prefix-cls}-submenu-arrow { - opacity: 0.45; - transition: all 0.3s; - &::after, - &::before { - background: @menu-dark-arrow-color; - } - } - } - - &-dark&-submenu-popup { - background: transparent; - } - - &-dark &-inline&-sub { - background: @menu-dark-submenu-bg; - box-shadow: 0 2px 8px fade(@black, 45%) inset; - } - - &-dark&-horizontal { - border-bottom: 0; - } - - &-dark&-horizontal > &-item, - &-dark&-horizontal > &-submenu { - top: 0; - margin-top: 0; - border-color: @menu-dark-bg; - border-bottom: 0; - } - - &-dark&-horizontal > &-item > a::before { - bottom: 0; - } - - &-dark &-item, - &-dark &-item-group-title, - &-dark &-item > a { - color: @menu-dark-color; - } - - &-dark&-inline, - &-dark&-vertical, - &-dark&-vertical-left, - &-dark&-vertical-right { - border-right: 0; - } - - &-dark&-inline &-item, - &-dark&-vertical &-item, - &-dark&-vertical-left &-item, - &-dark&-vertical-right &-item { - left: 0; - margin-left: 0; - border-right: 0; - &::after { - border-right: 0; - } - } - - &-dark&-inline &-item, - &-dark&-inline &-submenu-title { - width: 100%; - } - - &-dark &-item:hover, - &-dark &-item-active, - &-dark &-submenu-active, - &-dark &-submenu-open, - &-dark &-submenu-selected, - &-dark &-submenu-title:hover { - color: @menu-dark-highlight-color; - background-color: transparent; - > a { - color: @menu-dark-highlight-color; - } - > .@{menu-prefix-cls}-submenu-title, - > .@{menu-prefix-cls}-submenu-title:hover { - > .@{menu-prefix-cls}-submenu-arrow { - opacity: 1; - &::after, - &::before { - background: @menu-dark-highlight-color; - } - } - } - } - &-dark &-item:hover { - background-color: @menu-dark-item-hover-bg; - } - - &-dark &-item-selected { - color: @menu-dark-highlight-color; - border-right: 0; - &::after { - border-right: 0; - } - > a, - > a:hover { - color: @menu-dark-highlight-color; - } - .@{iconfont-css-prefix} { - color: @menu-dark-selected-item-icon-color; - } - .@{iconfont-css-prefix} + span { - color: @menu-dark-selected-item-text-color; - } - } - - &&-dark &-item-selected, - &-submenu-popup&-dark &-item-selected { - background-color: @menu-dark-item-active-bg; - } - - // Disabled state sets text to dark gray and nukes hover/tab effects - &-dark &-item-disabled, - &-dark &-submenu-disabled { - &, - > a { - color: @disabled-color-dark !important; - opacity: 0.8; - } - > .@{menu-prefix-cls}-submenu-title { - color: @disabled-color-dark !important; - > .@{menu-prefix-cls}-submenu-arrow { - &::before, - &::after { - background: @disabled-color-dark !important; - } - } - } - } -} diff --git a/components/old-menu/style/index.less b/components/old-menu/style/index.less deleted file mode 100644 index 53ac60599..000000000 --- a/components/old-menu/style/index.less +++ /dev/null @@ -1,515 +0,0 @@ -@import '../../style/themes/index'; -@import '../../style/mixins/index'; - -@menu-prefix-cls: ~'@{ant-prefix}-menu'; - -// default theme -.@{menu-prefix-cls} { - .reset-component(); - - margin-bottom: 0; - padding-left: 0; // Override default ul/ol - color: @menu-item-color; - line-height: 0; // Fix display inline-block gap - list-style: none; - background: @menu-bg; - outline: none; - box-shadow: @box-shadow-base; - transition: background 0.3s, width 0.3s cubic-bezier(0.2, 0, 0, 1) 0s; - .clearfix(); - - ul, - ol { - margin: 0; - padding: 0; - list-style: none; - } - - &-hidden { - display: none; - } - - &-item-group-title { - padding: 8px 16px; - color: @menu-item-group-title-color; - font-size: @font-size-base; - line-height: @line-height-base; - transition: all 0.3s; - } - - &-submenu, - &-submenu-inline { - transition: border-color 0.3s @ease-in-out, background 0.3s @ease-in-out, - padding 0.15s @ease-in-out; - } - - &-submenu-selected { - color: @menu-highlight-color; - } - - &-item:active, - &-submenu-title:active { - background: @menu-item-active-bg; - } - - &-submenu &-sub { - cursor: initial; - transition: background 0.3s @ease-in-out, padding 0.3s @ease-in-out; - } - - &-item > a { - display: block; - color: @menu-item-color; - &:hover { - color: @menu-highlight-color; - } - &::before { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - background-color: transparent; - content: ''; - } - } - - // https://github.com/ant-design/ant-design/issues/19809 - &-item > .@{ant-prefix}-badge > a { - color: @menu-item-color; - &:hover { - color: @menu-highlight-color; - } - } - - &-item-divider { - height: 1px; - overflow: hidden; - line-height: 0; - background-color: @border-color-split; - } - - &-item:hover, - &-item-active, - &:not(&-inline) &-submenu-open, - &-submenu-active, - &-submenu-title:hover { - color: @menu-highlight-color; - } - - &-horizontal &-item, - &-horizontal &-submenu { - margin-top: -1px; - } - - &-horizontal > &-item:hover, - &-horizontal > &-item-active, - &-horizontal > &-submenu &-submenu-title:hover { - background-color: transparent; - } - - &-item-selected { - color: @menu-highlight-color; - > a, - > a:hover { - color: @menu-highlight-color; - } - } - - &:not(&-horizontal) &-item-selected { - background-color: @menu-item-active-bg; - } - - &-inline, - &-vertical, - &-vertical-left { - border-right: @border-width-base @border-style-base @border-color-split; - } - &-vertical-right { - border-left: @border-width-base @border-style-base @border-color-split; - } - - &-vertical&-sub, - &-vertical-left&-sub, - &-vertical-right&-sub { - min-width: 160px; - padding: 0; - border-right: 0; - transform-origin: 0 0; - - .@{menu-prefix-cls}-item { - left: 0; - margin-left: 0; - border-right: 0; - &::after { - border-right: 0; - } - } - > .@{menu-prefix-cls}-item, - > .@{menu-prefix-cls}-submenu { - transform-origin: 0 0; - } - } - - &-horizontal&-sub { - min-width: 114px; // in case of submenu width is too big: https://codesandbox.io/s/qvpwm6mk66 - } - - &-item, - &-submenu-title { - position: relative; - display: block; - margin: 0; - padding: 0 20px; - 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; - .@{iconfont-css-prefix} { - min-width: 14px; - margin-right: 10px; - font-size: @menu-icon-size; - transition: font-size 0.15s @ease-out, margin 0.3s @ease-in-out; - + span { - opacity: 1; - transition: opacity 0.3s @ease-in-out, width 0.3s @ease-in-out; - } - } - } - - & > &-item-divider { - height: 1px; - margin: 1px 0; - padding: 0; - overflow: hidden; - line-height: 0; - background-color: @border-color-split; - } - - &-submenu { - &-popup { - position: absolute; - z-index: @zindex-dropdown; - // background: @menu-popup-bg; - border-radius: @border-radius-base; - - .submenu-title-wrapper { - padding-right: 20px; - } - - &::before { - position: absolute; - top: -7px; - right: 0; - bottom: 0; - left: 0; - opacity: 0.0001; - content: ' '; - } - } - - > .@{menu-prefix-cls} { - background-color: @menu-bg; - border-radius: @border-radius-base; - &-submenu-title::after { - transition: transform 0.3s @ease-in-out; - } - } - - &-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; - &::before, - &::after { - position: absolute; - width: 6px; - height: 1.5px; - // background + background-image to makes before & after cross have same color. - // Since `linear-gradient` not work on IE9, we should hack it. - // ref: https://github.com/ant-design/ant-design/issues/15910 - background: @menu-bg; - background: ~'@{menu-item-color} \9'; - background-image: linear-gradient(to right, @menu-item-color, @menu-item-color); - background-image: ~'none \9'; - 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); - } - } - > .@{menu-prefix-cls}-submenu-title:hover .@{menu-prefix-cls}-submenu-arrow { - &::after, - &::before { - background: linear-gradient(to right, @menu-highlight-color, @menu-highlight-color); - } - } - } - - &-inline > .@{menu-prefix-cls}-submenu-title .@{menu-prefix-cls}-submenu-arrow { - &::before { - transform: rotate(-45deg) translateX(2px); - } - &::after { - transform: rotate(45deg) translateX(-2px); - } - } - - &-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); - } - } - } - } - - &-vertical &-submenu-selected, - &-vertical-left &-submenu-selected, - &-vertical-right &-submenu-selected { - color: @menu-highlight-color; - > a { - color: @menu-highlight-color; - } - } - - &-horizontal { - line-height: 46px; - white-space: nowrap; - border: 0; - border-bottom: @border-width-base @border-style-base @border-color-split; - box-shadow: none; - - > .@{menu-prefix-cls}-item, - > .@{menu-prefix-cls}-submenu { - position: relative; - top: 1px; - display: inline-block; - vertical-align: bottom; - border-bottom: 2px solid transparent; - - &:hover, - &-active, - &-open, - &-selected { - color: @menu-highlight-color; - border-bottom: 2px solid @menu-highlight-color; - } - } - - > .@{menu-prefix-cls}-item { - > a { - display: block; - color: @menu-item-color; - &:hover { - color: @menu-highlight-color; - } - &::before { - bottom: -2px; - } - } - &-selected > a { - color: @menu-highlight-color; - } - } - - &::after { - display: block; - clear: both; - height: 0; - content: '\20'; - } - } - - &-vertical, - &-vertical-left, - &-vertical-right, - &-inline { - .@{menu-prefix-cls}-item { - position: relative; - &::after { - position: absolute; - top: 0; - right: 0; - bottom: 0; - 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; - content: ''; - } - } - - .@{menu-prefix-cls}-item, - .@{menu-prefix-cls}-submenu-title { - height: @menu-item-height; - margin-top: @menu-item-vertical-margin; - margin-bottom: @menu-item-vertical-margin; - padding: 0 16px; - overflow: hidden; - font-size: @menu-item-font-size; - line-height: @menu-item-height; - text-overflow: ellipsis; - } - - // disable margin collapsed - .@{menu-prefix-cls}-submenu { - padding-bottom: 0.02px; - } - - .@{menu-prefix-cls}-item:not(:last-child) { - margin-bottom: @menu-item-boundary-margin; - } - - > .@{menu-prefix-cls}-item, - > .@{menu-prefix-cls}-submenu > .@{menu-prefix-cls}-submenu-title { - height: @menu-inline-toplevel-item-height; - line-height: @menu-inline-toplevel-item-height; - } - } - - &-inline { - width: 100%; - .@{menu-prefix-cls}-selected, - .@{menu-prefix-cls}-item-selected { - &::after { - transform: scaleY(1); - opacity: 1; - transition: transform 0.15s @ease-in-out, opacity 0.15s @ease-in-out; - } - } - - .@{menu-prefix-cls}-item, - .@{menu-prefix-cls}-submenu-title { - width: ~'calc(100% + 1px)'; - } - - .@{menu-prefix-cls}-submenu-title { - padding-right: 34px; - } - } - - &-inline-collapsed { - width: @menu-collapsed-width; - > .@{menu-prefix-cls}-item, - > .@{menu-prefix-cls}-item-group - > .@{menu-prefix-cls}-item-group-list - > .@{menu-prefix-cls}-item, - > .@{menu-prefix-cls}-item-group - > .@{menu-prefix-cls}-item-group-list - > .@{menu-prefix-cls}-submenu - > .@{menu-prefix-cls}-submenu-title, - > .@{menu-prefix-cls}-submenu > .@{menu-prefix-cls}-submenu-title { - left: 0; - padding: 0 ((@menu-collapsed-width - @menu-icon-size-lg) / 2) !important; - text-overflow: clip; - .@{menu-prefix-cls}-submenu-arrow { - display: none; - } - .@{iconfont-css-prefix} { - margin: 0; - font-size: @menu-icon-size-lg; - line-height: @menu-item-height; - + span { - display: inline-block; - max-width: 0; - opacity: 0; - } - } - } - &-tooltip { - pointer-events: none; - .@{iconfont-css-prefix} { - display: none; - } - a { - color: @text-color-dark; - } - } - - .@{menu-prefix-cls}-item-group-title { - padding-right: 4px; - padding-left: 4px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } - } - - &-item-group-list { - margin: 0; - padding: 0; - .@{menu-prefix-cls}-item, - .@{menu-prefix-cls}-submenu-title { - padding: 0 16px 0 28px; - } - } - - &-root&-vertical, - &-root&-vertical-left, - &-root&-vertical-right, - &-root&-inline { - box-shadow: none; - } - - &-sub&-inline { - padding: 0; - border: 0; - border-radius: 0; - box-shadow: none; - & > .@{menu-prefix-cls}-item, - & > .@{menu-prefix-cls}-submenu > .@{menu-prefix-cls}-submenu-title { - height: @menu-item-height; - line-height: @menu-item-height; - list-style-position: inside; - list-style-type: disc; - } - - & .@{menu-prefix-cls}-item-group-title { - padding-left: 32px; - } - } - - // Disabled state sets text to gray and nukes hover/tab effects - &-item-disabled, - &-submenu-disabled { - color: @disabled-color !important; - background: none; - border-color: transparent !important; - cursor: not-allowed; - > a { - color: @disabled-color !important; - pointer-events: none; - } - > .@{menu-prefix-cls}-submenu-title { - color: @disabled-color !important; - cursor: not-allowed; - > .@{menu-prefix-cls}-submenu-arrow { - &::before, - &::after { - background: @disabled-color !important; - } - } - } - } -} - -@import './dark'; diff --git a/components/old-menu/style/index.ts b/components/old-menu/style/index.ts deleted file mode 100644 index be4998634..000000000 --- a/components/old-menu/style/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import '../../style/index.less'; -import './index.less'; - -// style dependencies -// deps-lint-skip: layout -import '../../tooltip/style';