@@ -34,40 +34,71 @@ export interface MenuItemProps
3434 itemData ?: ItemData ;
3535}
3636
37- // Since Menu event provide the `info.item` which point to the MenuItem node instance.
38- // We have to use class component here.
39- // This should be removed from doc & api in future.
40- class LegacyMenuItem extends React . Component < any > {
41- render ( ) {
42- const { title, attribute, elementRef, ...restProps } = this . props ;
43-
44- // Here the props are eventually passed to the DOM element.
45- // React does not recognize non-standard attributes.
46- // Therefore, remove the props that is not used here.
47- // ref: https://github.com/ant-design/ant-design/issues/41395
48- const passedProps = omit ( restProps , [
49- 'eventKey' ,
50- 'popupClassName' ,
51- 'popupOffset' ,
52- 'onTitleClick' ,
53- ] ) ;
54- warning ( ! attribute , '`attribute` of Menu.Item is deprecated. Please pass attribute directly.' ) ;
55-
56- return (
57- < Overflow . Item
58- { ...attribute }
59- title = { typeof title === 'string' ? title : undefined }
60- { ...passedProps }
61- ref = { elementRef }
62- />
63- ) ;
64- }
65- }
37+ type LegacyMenuItemProps = Omit < React . ComponentProps < typeof Overflow . Item > , 'title' | 'ref' > & {
38+ title ?: React . ReactNode ;
39+ attribute ?: Record < string , string > ;
40+ elementRef ?: React . Ref < HTMLLIElement > ;
41+ eventKey ?: string ;
42+ popupClassName ?: string ;
43+ popupOffset ?: number [ ] ;
44+ onTitleClick ?: ( ) => void ;
45+ } ;
46+
47+ type LegacyMenuItemHandle = {
48+ props : LegacyMenuItemProps ;
49+ element : HTMLLIElement | null ;
50+ } ;
51+
52+ // Keep exposing a legacy-compatible handle for deprecated `info.item`.
53+ // This should be removed together with the deprecated API in future.
54+ const LegacyMenuItem = React . forwardRef < LegacyMenuItemHandle , LegacyMenuItemProps > ( ( props , ref ) => {
55+ const { title, attribute, elementRef, ...restProps } = props ;
56+ const propsRef = React . useRef ( props ) ;
57+ const domRef = React . useRef < HTMLLIElement > ( null ) ;
58+
59+ propsRef . current = props ;
60+
61+ React . useImperativeHandle (
62+ ref ,
63+ ( ) => ( {
64+ get props ( ) {
65+ return propsRef . current ;
66+ } ,
67+ get element ( ) {
68+ return domRef . current ;
69+ } ,
70+ } ) ,
71+ [ ] ,
72+ ) ;
73+
74+ // Here the props are eventually passed to the DOM element.
75+ // React does not recognize non-standard attributes.
76+ // Therefore, remove the props that is not used here.
77+ // ref: https://github.com/ant-design/ant-design/issues/41395
78+ const passedProps = omit ( restProps , [
79+ 'eventKey' ,
80+ 'popupClassName' ,
81+ 'popupOffset' ,
82+ 'onTitleClick' ,
83+ ] ) ;
84+ const mergedRef = useComposeRef ( elementRef , domRef ) ;
85+
86+ warning ( ! attribute , '`attribute` of Menu.Item is deprecated. Please pass attribute directly.' ) ;
87+
88+ return (
89+ < Overflow . Item
90+ { ...attribute }
91+ title = { typeof title === 'string' ? title : undefined }
92+ { ...passedProps }
93+ ref = { mergedRef }
94+ />
95+ ) ;
96+ } ) ;
6697
6798/**
6899 * Real Menu Item component
69100 */
70- const InternalMenuItem = React . forwardRef ( ( props : MenuItemProps , ref : React . Ref < HTMLElement > ) => {
101+ const InternalMenuItem = React . forwardRef ( ( props : MenuItemProps , ref : React . Ref < HTMLLIElement > ) => {
71102 const {
72103 style,
73104 className,
@@ -117,7 +148,7 @@ const InternalMenuItem = React.forwardRef((props: MenuItemProps, ref: React.Ref<
117148
118149 const itemCls = `${ prefixCls } -item` ;
119150
120- const legacyMenuItemRef = React . useRef < any > ( ) ;
151+ const legacyMenuItemRef = React . useRef < LegacyMenuItemHandle | null > ( null ) ;
121152 const elementRef = React . useRef < HTMLLIElement > ( ) ;
122153 const mergedDisabled = contextDisabled || disabled ;
123154
@@ -147,7 +178,7 @@ const InternalMenuItem = React.forwardRef((props: MenuItemProps, ref: React.Ref<
147178 key : eventKey ,
148179 // Note: For legacy code is reversed which not like other antd component
149180 keyPath : [ ...connectedKeys ] . reverse ( ) ,
150- item : legacyMenuItemRef . current ,
181+ item : legacyMenuItemRef . current as unknown as React . ReactInstance ,
151182 domEvent : e ,
152183 itemData : propsItemData || itemData ,
153184 } ;
@@ -214,6 +245,7 @@ const InternalMenuItem = React.forwardRef((props: MenuItemProps, ref: React.Ref<
214245 < LegacyMenuItem
215246 ref = { legacyMenuItemRef }
216247 elementRef = { mergedEleRef }
248+ eventKey = { eventKey }
217249 role = { role === null ? 'none' : role || 'menuitem' }
218250 tabIndex = { disabled ? null : - 1 }
219251 data-menu-id = { overflowDisabled && domDataId ? null : domDataId }
@@ -257,7 +289,7 @@ const InternalMenuItem = React.forwardRef((props: MenuItemProps, ref: React.Ref<
257289 return renderNode ;
258290} ) ;
259291
260- function MenuItem ( props : MenuItemProps , ref : React . Ref < HTMLElement > ) : React . ReactElement {
292+ function MenuItem ( props : MenuItemProps , ref : React . Ref < HTMLLIElement > ) : React . ReactElement {
261293 const { eventKey } = props ;
262294
263295 // ==================== Record KeyPath ====================
0 commit comments