Skip to content

Commit

Permalink
feat: MenuItem, MenuGroup and SubMenu support ref (#683)
Browse files Browse the repository at this point in the history
* feat: MenuItem, MenuGroup and SubMenu support ref

* docs: add demo

* docs: add ref

* test: add case

* docs: fix demo
  • Loading branch information
madocto committed Mar 25, 2024
1 parent b29c3fc commit 81eafee
Show file tree
Hide file tree
Showing 8 changed files with 485 additions and 298 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ ReactDOM.render(
</tr>
</thead>
<tbody>
<tr>
<td>ref</td>
<td>React.HTMLLIElement</td>
<td></td>
<td>get dom node</td>
</tr>
<tr>
<td>className</td>
<td>String</td>
Expand Down Expand Up @@ -294,6 +300,12 @@ ReactDOM.render(
</tr>
</thead>
<tbody>
<tr>
<td>ref</td>
<td>React.HTMLLIElement</td>
<td></td>
<td>get dom node</td>
</tr>
<tr>
<td>popupClassName</td>
<td>String</td>
Expand Down Expand Up @@ -397,6 +409,12 @@ none
</tr>
</thead>
<tbody>
<tr>
<td>ref</td>
<td>React.HTMLLIElement</td>
<td></td>
<td>get dom node</td>
</tr>
<tr>
<td>title</td>
<td>String|React.Element</td>
Expand Down
3 changes: 3 additions & 0 deletions docs/demo/items-ref.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## items-ref

<code src="../examples/items-ref.tsx"></code>
100 changes: 100 additions & 0 deletions docs/examples/items-ref.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/* eslint no-console:0 */

import React, { useRef } from 'react';
import '../../assets/index.less';
import Menu from '../../src';

export default () => {
const ref1 = useRef();
const ref2 = useRef();
const ref3 = useRef();
const ref4 = useRef();
const ref5 = useRef();
const ref6 = useRef();
const ref7 = useRef();

return (
<>
<button
onClick={() => {
console.log(ref1.current);
console.log(ref2.current);
console.log(ref3.current);
console.log(ref4.current);
console.log(ref5.current);
console.log(ref6.current);
console.log(ref7.current);
}}
>
获取 Ref
</button>
<Menu
items={[
{
// MenuItem
label: 'Top Menu Item',
key: 'top',
ref: ref1,
},
{
// MenuGroup
type: 'group',
label: 'Top Menu Group without children',
ref: ref2,
},
{
// MenuGroup
type: 'group',
label: 'Top Menu Group with children',
ref: ref3,
children: [
{
// MenuItem
label: 'Menu Item 1',
key: 'inner1',
},
{
// Divider
type: 'divider',
},
{
// MenuItem
label: 'Menu Item 2',
key: 'inner2',
ref: ref4,
},
],
},
{
// SubMenu
label: 'SubMenu',
key: 'sub1',
ref: ref5,
children: [
{
// MenuItem
label: 'Menu Item 1-1',
key: 'inner11',
ref: ref6,
},

{
// SubMenu
label: 'SubMenu inner',
key: 'sub1-1',
ref: ref7,
children: [
{
// MenuItem
label: 'Menu Item 111',
key: 'inner1-1-1',
},
],
},
],
},
]}
/>
</>
);
};
2 changes: 1 addition & 1 deletion src/MenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type { MenuInfo, MenuItemType } from './interface';
import { warnItemProp } from './utils/warnUtil';

export interface MenuItemProps
extends Omit<MenuItemType, 'label' | 'key'>,
extends Omit<MenuItemType, 'label' | 'key'| 'ref'>,
Omit<
React.HTMLAttributes<HTMLLIElement>,
'onClick' | 'onMouseEnter' | 'onMouseLeave' | 'onSelect'
Expand Down
57 changes: 31 additions & 26 deletions src/MenuItemGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,18 @@ export interface MenuItemGroupProps
warnKey?: boolean;
}

const InternalMenuItemGroup = ({
className,
title,
eventKey,
children,
...restProps
}: MenuItemGroupProps) => {
const InternalMenuItemGroup = React.forwardRef<
HTMLLIElement,
MenuItemGroupProps
>((props, ref) => {
const { className, title, eventKey, children, ...restProps } = props;
const { prefixCls } = React.useContext(MenuContext);

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

return (
<li
ref={ref}
role="presentation"
{...restProps}
onClick={e => e.stopPropagation()}
Expand All @@ -49,26 +48,32 @@ const InternalMenuItemGroup = ({
</ul>
</li>
);
};
});

export default function MenuItemGroup({
children,
...props
}: MenuItemGroupProps): React.ReactElement {
const connectedKeyPath = useFullPath(props.eventKey);
const childList: React.ReactElement[] = parseChildren(
children,
connectedKeyPath,
);
const MenuItemGroup = React.forwardRef<HTMLLIElement, MenuItemGroupProps>(
(props, ref) => {
const { eventKey, children } = props;
const connectedKeyPath = useFullPath(eventKey);
const childList: React.ReactElement[] = parseChildren(
children,
connectedKeyPath,
);

const measure = useMeasure();
if (measure) {
return (childList as any) as React.ReactElement;
}
const measure = useMeasure();
if (measure) {
return childList as any as React.ReactElement;
}

return (
<InternalMenuItemGroup {...omit(props, ['warnKey'])}>
{childList}
</InternalMenuItemGroup>
);
return (
<InternalMenuItemGroup ref={ref} {...omit(props, ['warnKey'])}>
{childList}
</InternalMenuItemGroup>
);
},
);

if (process.env.NODE_ENV !== 'production') {
MenuItemGroup.displayName = 'MenuItemGroup';
}

export default MenuItemGroup;

0 comments on commit 81eafee

Please sign in to comment.