diff --git a/src/DOMWrap.tsx b/src/DOMWrap.tsx index ed587017..ac3c97e5 100644 --- a/src/DOMWrap.tsx +++ b/src/DOMWrap.tsx @@ -18,6 +18,7 @@ interface DOMWrapProps { visible?: boolean; tag?: string; style?: React.CSSProperties; + forwardedRef: React.RefObject; } interface DOMWrapState { @@ -53,10 +54,16 @@ class DOMWrap extends React.Component { childRef = React.createRef(); + setRef(e: HTMLElement) { + (this.childRef as any).current = e; + (this.props.forwardedRef as any).current = e; + } + componentDidMount() { this.setChildrenWidthAndResize(); if (this.props.level === 1 && this.props.mode === 'horizontal') { const menuUl = this.childRef.current; + if (!menuUl) { return; } @@ -249,6 +256,7 @@ class DOMWrap extends React.Component { } const ul = this.childRef.current; + if (!ul) { return; } @@ -356,13 +364,14 @@ class DOMWrap extends React.Component { tag, children, theme, + forwardedRef, ...rest } = this.props; const Tag = tag as any; return ( - + {this.renderChildren(children)} ); diff --git a/src/MenuItem.tsx b/src/MenuItem.tsx index 0e96386f..8223f132 100644 --- a/src/MenuItem.tsx +++ b/src/MenuItem.tsx @@ -50,6 +50,7 @@ export interface MenuItemProps inlineIndent?: number; level?: number; direction?: 'ltr' | 'rtl'; + forwardedRef?: React.RefObject; } export class MenuItem extends React.Component { @@ -235,6 +236,7 @@ export class MenuItem extends React.Component { 'onMouseEnter', 'onMouseLeave', 'onSelect', + 'forwardedRef', ])} {...attrs} {...mouseEvent} diff --git a/src/SubMenu.tsx b/src/SubMenu.tsx index b6a89114..bff15978 100644 --- a/src/SubMenu.tsx +++ b/src/SubMenu.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import * as ReactDOM from 'react-dom'; import Trigger from 'rc-trigger'; import raf from 'rc-util/lib/raf'; import KeyCode from 'rc-util/lib/KeyCode'; @@ -102,6 +101,7 @@ export interface SubMenuProps { motion?: CSSMotionProps; direction?: 'ltr' | 'rtl'; + forwardedRef?: React.RefObject; } interface SubMenuState { @@ -140,12 +140,16 @@ export class SubMenu extends React.Component { mode: props.mode, isOpen: props.isOpen, }; + + this.menuInstanceRef = React.createRef(); } isRootMenu: boolean; menuInstance: MenuItem; + menuInstanceRef: React.RefObject; + subMenuTitle: HTMLElement; internalMenuId: string; @@ -414,7 +418,7 @@ export class SubMenu extends React.Component { if (!this.subMenuTitle || !this.menuInstance) { return; } - const popupMenu = ReactDOM.findDOMNode(this.menuInstance) as HTMLElement; + const popupMenu = this.menuInstanceRef.current; if (popupMenu.offsetWidth >= this.subMenuTitle.offsetWidth) { return; } @@ -462,6 +466,7 @@ export class SubMenu extends React.Component { itemIcon: props.itemIcon, expandIcon: props.expandIcon, direction: props.direction, + forwardedRef: this.menuInstanceRef, }; }; @@ -664,6 +669,8 @@ export class SubMenu extends React.Component { ? null : this.getMotion(baseProps.mode, baseProps.visible); + delete props.forwardedRef; + return (
  • ; } export class SubPopupMenu extends React.Component { @@ -168,6 +170,7 @@ export class SubPopupMenu extends React.Component { focusable: true, style: {}, manualRef: noop, + forwardedRef: noop, }; constructor(props: SubPopupMenuProps) { @@ -388,6 +391,7 @@ export class SubPopupMenu extends React.Component { expandIcon: childProps.expandIcon || this.props.expandIcon, ...extraProps, direction: props.direction, + forwardedRef: childProps.disabled ? undefined : props.forwardedRef, }; // ref: https://github.com/ant-design/ant-design/issues/13943 if (props.mode === 'inline' || isMobileDevice()) {