Skip to content

Commit 282f38b

Browse files
authored
fix: support submenu item title (#868)
1 parent 9c994fc commit 282f38b

4 files changed

Lines changed: 44 additions & 4 deletions

File tree

src/SubMenu/index.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ import { useMenuId } from '../context/IdContext';
2323
import PrivateContext from '../context/PrivateContext';
2424

2525
export type SemanticName = 'list' | 'listTitle';
26-
export interface SubMenuProps extends Omit<SubMenuType, 'key' | 'children' | 'label'> {
26+
export interface SubMenuProps extends Omit<SubMenuType, 'key' | 'children' | 'label' | 'title'> {
2727
classNames?: Partial<Record<SemanticName, string>>;
2828
styles?: Partial<Record<SemanticName, React.CSSProperties>>;
2929
title?: React.ReactNode;
30+
itemTitle?: string;
3031

3132
children?: React.ReactNode;
3233

@@ -51,6 +52,7 @@ const InternalSubMenu = React.forwardRef<HTMLLIElement, SubMenuProps>((props, re
5152
classNames: menuClassNames,
5253

5354
title,
55+
itemTitle,
5456
eventKey,
5557
warnKey,
5658

@@ -252,7 +254,7 @@ const InternalSubMenu = React.forwardRef<HTMLLIElement, SubMenuProps>((props, re
252254
className={`${subMenuPrefixCls}-title`}
253255
tabIndex={mergedDisabled ? null : -1}
254256
ref={elementRef}
255-
title={typeof title === 'string' ? title : null}
257+
title={itemTitle ?? (typeof title === 'string' ? title : null)}
256258
data-menu-id={overflowDisabled && domDataId ? null : domDataId}
257259
aria-expanded={open}
258260
aria-haspopup

src/interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export interface SubMenuType extends ItemSharedProps {
1212
type?: 'submenu';
1313

1414
label?: React.ReactNode;
15+
title?: string;
1516

1617
children: ItemType[];
1718

src/utils/nodeUtil.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,15 @@ function convertItemsToNodes(
3636
}
3737

3838
// Sub Menu
39+
const { title: itemTitle, ...subMenuRestProps } = restProps;
40+
3941
return (
40-
<MergedSubMenu key={mergedKey} {...restProps} title={label}>
42+
<MergedSubMenu
43+
key={mergedKey}
44+
{...subMenuRestProps}
45+
title={label}
46+
itemTitle={typeof itemTitle === 'string' ? itemTitle : undefined}
47+
>
4148
{convertItemsToNodes(children, components, prefixCls)}
4249
</MergedSubMenu>
4350
);
@@ -51,7 +58,12 @@ function convertItemsToNodes(
5158
const hasExtra = !!extra || extra === 0;
5259

5360
return (
54-
<MergedMenuItem key={mergedKey} {...restProps} extra={extra} itemData={{ ...opt, key: mergedKey }}>
61+
<MergedMenuItem
62+
key={mergedKey}
63+
{...restProps}
64+
extra={extra}
65+
itemData={{ ...opt, key: mergedKey }}
66+
>
5567
{hasExtra ? (
5668
<>
5769
<span className={`${prefixCls}-item-label`}>{label}</span>

tests/Options.spec.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,30 @@ describe('Options', () => {
4141

4242
expect(container.children).toMatchSnapshot();
4343
});
44+
45+
it('uses submenu item title as native title without replacing label', () => {
46+
const { container } = render(
47+
<Menu
48+
items={[
49+
{
50+
label: 'Users',
51+
key: 'sub1',
52+
title: 'People',
53+
children: [
54+
{
55+
label: 'User 1',
56+
key: 'user1',
57+
},
58+
],
59+
},
60+
]}
61+
/>,
62+
);
63+
64+
const titleNode = container.querySelector('.rc-menu-submenu-title');
65+
66+
expect(titleNode).toHaveTextContent('Users');
67+
expect(titleNode).toHaveAttribute('title', 'People');
68+
});
4469
});
4570
/* eslint-enable */

0 commit comments

Comments
 (0)