diff --git a/src/Menu.tsx b/src/Menu.tsx index edad0c5b..4f53db97 100644 --- a/src/Menu.tsx +++ b/src/Menu.tsx @@ -426,6 +426,11 @@ const Menu = React.forwardRef((props, ref) => { elementToFocus?.focus?.(options); } }, + findItem: ({ key: itemKey }) => { + const keys = getKeys(); + const { key2element } = refreshElements(keys, uuid); + return key2element.get(itemKey) || null; + }, }; }); diff --git a/src/interface.ts b/src/interface.ts index f47873d1..f44b9eb6 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -134,9 +134,12 @@ export type MenuRef = { */ focus: (options?: FocusOptions) => void; list: HTMLUListElement; + findItem: (params: { key: string }) => HTMLElement | null; }; // ======================== Component ======================== export type ComponentType = 'submenu' | 'item' | 'group' | 'divider'; -export type Components = Partial>>; +export type Components = Partial< + Record> +>; diff --git a/tests/Menu.spec.tsx b/tests/Menu.spec.tsx index fc7326ef..76318b9a 100644 --- a/tests/Menu.spec.tsx +++ b/tests/Menu.spec.tsx @@ -333,7 +333,7 @@ describe('Menu', () => { // don't use selectedKeys as string // it is a compatible feature for https://github.com/ant-design/ant-design/issues/29429 const { container } = render( - + 1 2 , @@ -807,5 +807,23 @@ describe('Menu', () => { rerender(); expect(container.querySelectorAll('.rc-menu-submenu-arrow').length).toBe(1); }); + + it('should find item by key', () => { + const menuRef = React.createRef(); + const { container } = render( + + Light + Cat + , + ); + + const lightItem = menuRef.current?.findItem({ key: 'light' }); + const catItem = menuRef.current?.findItem({ key: 'cat' }); + const nonExistentItem = menuRef.current?.findItem({ key: 'dog' }); + + expect(lightItem).toBe(container.querySelectorAll('li')[0]); + expect(catItem).toBe(container.querySelectorAll('li')[1]); + expect(nonExistentItem).toBe(null); + }); }); /* eslint-enable */