From 793725b81e76242417217a33897e5a6a598afa8e Mon Sep 17 00:00:00 2001 From: thinkasany <480968828@qq.com> Date: Mon, 21 Apr 2025 23:06:36 +0800 Subject: [PATCH 1/2] feat: support classNames and styles for menu --- docs/examples/menuItemGroup.tsx | 6 ++- src/Menu.tsx | 15 ++++++- tests/SubMenu.spec.tsx | 29 +------------ tests/semantic.spec.tsx | 77 +++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 31 deletions(-) create mode 100644 tests/semantic.spec.tsx diff --git a/docs/examples/menuItemGroup.tsx b/docs/examples/menuItemGroup.tsx index 832470e1..6d9f0f01 100644 --- a/docs/examples/menuItemGroup.tsx +++ b/docs/examples/menuItemGroup.tsx @@ -8,7 +8,11 @@ import '../../assets/index.less'; export default () => (

menu item group

- console.log('click')}> + console.log('click')} + classNames={{ listTitle: 'test-title', list: 'test-list' }} + > 2 3 diff --git a/src/Menu.tsx b/src/Menu.tsx index 0207191e..6d1cdf36 100644 --- a/src/Menu.tsx +++ b/src/Menu.tsx @@ -30,7 +30,7 @@ import type { PopupRender, } from './interface'; import MenuItem from './MenuItem'; -import SubMenu from './SubMenu'; +import SubMenu, { SemanticName } from './SubMenu'; import { parseItems } from './utils/nodeUtil'; import { warnItemProp } from './utils/warnUtil'; @@ -54,6 +54,8 @@ export interface MenuProps extends Omit, 'onClick' | 'onSelect' | 'dir'> { prefixCls?: string; rootClassName?: string; + classNames?: Partial>; + styles?: Partial>; items?: ItemType[]; /** @deprecated Please use `items` instead */ @@ -168,6 +170,8 @@ const Menu = React.forwardRef((props, ref) => { rootClassName, style, className, + styles, + classNames: menuClassNames, tabIndex = 0, items, children, @@ -544,7 +548,12 @@ const Menu = React.forwardRef((props, ref) => { : // Need wrap for overflow dropdown that do not response for open childList.map((child, index) => ( // Always wrap provider to avoid sub node re-mount - lastVisibleIndex}> + lastVisibleIndex} + classNames={menuClassNames} + styles={styles} + > {child} )); @@ -614,6 +623,8 @@ const Menu = React.forwardRef((props, ref) => { { @@ -483,32 +483,5 @@ describe('SubMenu', () => { '150px', ); }); - it('support classNames and styles', () => { - const testClassNames = { - list: 'test-list', - listTitle: 'test-list-title', - }; - const testStyles = { - list: { color: 'red' }, - listTitle: { color: 'blue' }, - }; - const { container } = render( - - - - 1 - - - , - ); - fireEvent.mouseEnter(container.querySelector('.rc-menu-submenu-title')); - runAllTimer(); - const list = container.querySelector('.rc-menu-item-group-list'); - const listTitle = container.querySelector('.rc-menu-item-group-title'); - expect(list).toHaveClass(testClassNames.list); - expect(list).toHaveStyle(testStyles.list); - expect(listTitle).toHaveClass(testClassNames.listTitle); - expect(listTitle).toHaveStyle(testStyles.listTitle); - }); }); /* eslint-enable */ diff --git a/tests/semantic.spec.tsx b/tests/semantic.spec.tsx new file mode 100644 index 00000000..688dc448 --- /dev/null +++ b/tests/semantic.spec.tsx @@ -0,0 +1,77 @@ +/* eslint-disable no-undef */ +import { act, fireEvent, render } from '@testing-library/react'; +import Menu, { MenuItem, MenuItemGroup, SubMenu } from '../src'; +describe('semantic', () => { + function runAllTimer() { + for (let i = 0; i < 10; i += 1) { + act(() => { + jest.runAllTimers(); + }); + } + } + beforeEach(() => { + global.triggerProps = null; + global.popupTriggerProps = null; + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + it('support classNames and styles for subMenu', () => { + const testClassNames = { + list: 'test-list', + listTitle: 'test-list-title', + }; + const testStyles = { + list: { color: 'red' }, + listTitle: { color: 'blue' }, + }; + const { container } = render( + + + + 1 + + + , + ); + fireEvent.mouseEnter(container.querySelector('.rc-menu-submenu-title')); + runAllTimer(); + const list = container.querySelector('.rc-menu-item-group-list'); + const listTitle = container.querySelector('.rc-menu-item-group-title'); + expect(list).toHaveClass(testClassNames.list); + expect(list).toHaveStyle(testStyles.list); + expect(listTitle).toHaveClass(testClassNames.listTitle); + expect(listTitle).toHaveStyle(testStyles.listTitle); + }); + it('support classNames and styles for Menu', () => { + const testClassNames = { + list: 'test-list', + listTitle: 'test-list-title', + }; + const testStyles = { + list: { color: 'red' }, + listTitle: { color: 'blue' }, + }; + const { container } = render( + console.log('click')} classNames={testClassNames} styles={testStyles}> + + 2 + 3 + + + 4 + 5 + + , + ); + const list = container.querySelector('.rc-menu-item-group-list'); + const listTitle = container.querySelector('.rc-menu-item-group-title'); + expect(list).toHaveClass(testClassNames.list); + expect(list).toHaveStyle(testStyles.list); + expect(listTitle).toHaveClass(testClassNames.listTitle); + expect(listTitle).toHaveStyle(testStyles.listTitle); + }); +}); From 09d950f68dceb8b30cf7ac789071cf8e09b40e8e Mon Sep 17 00:00:00 2001 From: thinkasany <480968828@qq.com> Date: Mon, 21 Apr 2025 23:09:40 +0800 Subject: [PATCH 2/2] fix --- tests/semantic.spec.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/semantic.spec.tsx b/tests/semantic.spec.tsx index 688dc448..360c4639 100644 --- a/tests/semantic.spec.tsx +++ b/tests/semantic.spec.tsx @@ -1,5 +1,6 @@ /* eslint-disable no-undef */ import { act, fireEvent, render } from '@testing-library/react'; +import React from 'react'; import Menu, { MenuItem, MenuItemGroup, SubMenu } from '../src'; describe('semantic', () => { function runAllTimer() {