Skip to content

Commit e07022d

Browse files
committed
feat: support classNames and styles
1 parent 9e58600 commit e07022d

File tree

4 files changed

+49
-4
lines changed

4 files changed

+49
-4
lines changed

src/MenuItemGroup.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export interface MenuItemGroupProps extends Omit<MenuItemGroupType, 'type' | 'ch
2020

2121
const InternalMenuItemGroup = React.forwardRef<HTMLLIElement, MenuItemGroupProps>((props, ref) => {
2222
const { className, title, eventKey, children, ...restProps } = props;
23-
const { prefixCls } = React.useContext(MenuContext);
23+
const { prefixCls, classNames: menuClassNames, styles } = React.useContext(MenuContext);
2424

2525
const groupPrefixCls = `${prefixCls}-item-group`;
2626

@@ -34,12 +34,17 @@ const InternalMenuItemGroup = React.forwardRef<HTMLLIElement, MenuItemGroupProps
3434
>
3535
<div
3636
role="presentation"
37-
className={`${groupPrefixCls}-title`}
37+
className={classNames(`${groupPrefixCls}-title`, menuClassNames?.listTitle)}
38+
style={styles?.listTitle}
3839
title={typeof title === 'string' ? title : undefined}
3940
>
4041
{title}
4142
</div>
42-
<ul role="group" className={`${groupPrefixCls}-list`}>
43+
<ul
44+
role="group"
45+
className={classNames(`${groupPrefixCls}-list`, menuClassNames?.list)}
46+
style={styles?.list}
47+
>
4348
{children}
4449
</ul>
4550
</li>

src/SubMenu/index.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ import {
2222
import { useMenuId } from '../context/IdContext';
2323
import PrivateContext from '../context/PrivateContext';
2424

25+
export type SemanticName = 'list' | 'listTitle';
2526
export interface SubMenuProps extends Omit<SubMenuType, 'key' | 'children' | 'label'> {
27+
classNames?: Partial<Record<SemanticName, string>>;
28+
styles?: Partial<Record<SemanticName, React.CSSProperties>>;
2629
title?: React.ReactNode;
2730

2831
children?: React.ReactNode;
@@ -45,6 +48,9 @@ const InternalSubMenu = React.forwardRef<HTMLLIElement, SubMenuProps>((props, re
4548
style,
4649
className,
4750

51+
styles,
52+
classNames: menuClassNames,
53+
4854
title,
4955
eventKey,
5056
warnKey,
@@ -275,6 +281,8 @@ const InternalSubMenu = React.forwardRef<HTMLLIElement, SubMenuProps>((props, re
275281
const renderPopupContent = React.useMemo(() => {
276282
const originNode = (
277283
<MenuContextProvider
284+
classNames={menuClassNames}
285+
styles={styles}
278286
mode={popupContentTriggerMode === 'horizontal' ? 'vertical' : popupContentTriggerMode}
279287
>
280288
<SubMenuList id={popupId} ref={popupRef}>
@@ -363,6 +371,8 @@ const InternalSubMenu = React.forwardRef<HTMLLIElement, SubMenuProps>((props, re
363371
// >>>>> Render
364372
return (
365373
<MenuContextProvider
374+
classNames={menuClassNames}
375+
styles={styles}
366376
onItemClick={onMergedItemClick}
367377
mode={mode === 'horizontal' ? 'vertical' : mode}
368378
itemIcon={mergedItemIcon}

src/context/MenuContext.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@ import type {
1010
TriggerSubMenuAction,
1111
PopupRender,
1212
} from '../interface';
13+
import { SubMenuProps } from '..';
1314

1415
export interface MenuContextProps {
1516
prefixCls: string;
17+
classNames?: SubMenuProps['classNames'];
18+
styles?: SubMenuProps['styles'];
1619
rootClassName?: string;
1720
openKeys: string[];
1821
rtl?: boolean;

tests/SubMenu.spec.tsx

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { act, fireEvent, render } from '@testing-library/react';
33
import { resetWarned } from '@rc-component/util/lib/warning';
44
import React from 'react';
5-
import Menu, { MenuItem, SubMenu } from '../src';
5+
import Menu, { MenuItem, MenuItemGroup, SubMenu } from '../src';
66
import { isActive, last } from './util';
77

88
jest.mock('@rc-component/trigger', () => {
@@ -483,5 +483,32 @@ describe('SubMenu', () => {
483483
'150px',
484484
);
485485
});
486+
it('support classNames and styles', () => {
487+
const testClassNames = {
488+
list: 'test-list',
489+
listTitle: 'test-list-title',
490+
};
491+
const testStyles = {
492+
list: { color: 'red' },
493+
listTitle: { color: 'blue' },
494+
};
495+
const { container } = render(
496+
<Menu openKeys={['s1']}>
497+
<SubMenu key="s1" title="submenu1" classNames={testClassNames} styles={testStyles}>
498+
<MenuItemGroup title="group 1" key="2">
499+
<MenuItem key="s1-1">1</MenuItem>
500+
</MenuItemGroup>
501+
</SubMenu>
502+
</Menu>,
503+
);
504+
fireEvent.mouseEnter(container.querySelector('.rc-menu-submenu-title'));
505+
runAllTimer();
506+
const list = container.querySelector('.rc-menu-item-group-list');
507+
const listTitle = container.querySelector('.rc-menu-item-group-title');
508+
expect(list).toHaveClass(testClassNames.list);
509+
expect(list).toHaveStyle(testStyles.list);
510+
expect(listTitle).toHaveClass(testClassNames.listTitle);
511+
expect(listTitle).toHaveStyle(testStyles.listTitle);
512+
});
486513
});
487514
/* eslint-enable */

0 commit comments

Comments
 (0)