Skip to content

Commit

Permalink
feat: menu ref support focus (#442)
Browse files Browse the repository at this point in the history
  • Loading branch information
MadCcc authored Mar 27, 2022
1 parent bd99d30 commit 4242acd
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 6 deletions.
15 changes: 11 additions & 4 deletions src/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type {
SelectInfo,
RenderIconType,
ItemType,
MenuRef,
} from './interface';
import MenuItem from './MenuItem';
import { parseItems } from './utils/nodeUtil';
Expand All @@ -28,7 +29,7 @@ import { PathRegisterContext, PathUserContext } from './context/PathContext';
import useKeyRecords, { OVERFLOW_KEY } from './hooks/useKeyRecords';
import { IdContext } from './context/IdContext';
import PrivateContext from './context/PrivateContext';
import { composeRef } from 'rc-util/lib/ref';
import { useImperativeHandle } from 'react';

/**
* Menu modify after refactor:
Expand Down Expand Up @@ -149,7 +150,7 @@ interface LegacyMenuProps extends MenuProps {
openAnimation?: string;
}

const Menu = React.forwardRef<HTMLUListElement, MenuProps>((props, ref) => {
const Menu = React.forwardRef<MenuRef, MenuProps>((props, ref) => {
const {
prefixCls = 'rc-menu',
style,
Expand Down Expand Up @@ -232,7 +233,13 @@ const Menu = React.forwardRef<HTMLUListElement, MenuProps>((props, ref) => {
const [mounted, setMounted] = React.useState(false);

const containerRef = React.useRef<HTMLUListElement>();
const mergedRef = composeRef(containerRef, ref);

useImperativeHandle(ref, () => ({
list: containerRef.current,
focus: (options?: FocusOptions) => {
containerRef.current?.focus(options);
},
}));

const uuid = useUUID(id);

Expand Down Expand Up @@ -498,7 +505,7 @@ const Menu = React.forwardRef<HTMLUListElement, MenuProps>((props, ref) => {
const container = (
<Overflow
id={id}
ref={mergedRef as any}
ref={containerRef as any}
prefixCls={`${prefixCls}-overflow`}
component="ul"
itemComponent={MenuItem}
Expand Down
5 changes: 5 additions & 0 deletions src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,8 @@ export type SelectEventHandler = (info: SelectInfo) => void;

// ========================== Click ==========================
export type MenuClickEventHandler = (info: MenuInfo) => void;

export type MenuRef = {
focus: (options?: FocusOptions) => void;
list: HTMLUListElement;
};
17 changes: 15 additions & 2 deletions tests/Menu.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -650,14 +650,27 @@ describe('Menu', () => {

it('should support ref', () => {
const menuRef = React.createRef();
const wrapper = mount(
<Menu ref={menuRef}>
<MenuItem key="light">Light</MenuItem>
</Menu>,
);

mount(
expect(menuRef.current?.list).toBe(wrapper.find('ul').first().getDOMNode());
});

it('should support focus through ref', () => {
const menuRef = React.createRef();
const wrapper = mount(
<Menu ref={menuRef}>
<MenuItem key="light">Light</MenuItem>
</Menu>,
);
menuRef.current?.focus();

expect(menuRef.current).toBeTruthy();
expect(document.activeElement).toBe(
wrapper.find('ul').first().getDOMNode(),
);
});
});
/* eslint-enable */

0 comments on commit 4242acd

Please sign in to comment.