Skip to content

Commit

Permalink
fix(MenuButton): focus on first item on mouse click (ABF-6488)
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelguebo committed Jun 19, 2023
1 parent c6e1336 commit e3b42a0
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
24 changes: 24 additions & 0 deletions packages/react/src/components/menu-button/menu-button.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,30 @@ describe('MenuButton', () => {
expect(getByTestId(wrapper, 'menu').exists()).toBe(true);
});

it('should open menu when Space key is pressed', () => {
const wrapper = mountWithTheme(<MenuButton buttonType="primary" options={options}>Test</MenuButton>);
getByTestId(wrapper, 'menu-button').simulate('keydown', { key: 'Space' });
setTimeout(() => {
expect(getByTestId(wrapper, 'menu').exists()).toBe(true);
}, 0);
});

it('should open menu when Enter key is pressed', () => {
const wrapper = mountWithTheme(<MenuButton buttonType="primary" options={options}>Test</MenuButton>);
getByTestId(wrapper, 'menu-button').simulate('keydown', { key: 'Enter' });
setTimeout(() => {
expect(getByTestId(wrapper, 'menu').exists()).toBe(true);
});
});

it('should select menu child #0 if Enter is pressed', () => {
const wrapper = mountWithTheme(<MenuButton buttonType="primary" options={options}>Test</MenuButton>);
getByTestId(wrapper, 'menu-button').simulate('keydown', { key: 'Enter' });
setTimeout(() => {
expect(document.activeElement).toBe(getByTestId(wrapper, 'menu').getNodes()[0]);
});
});

it('should be default open when defaultOpen prop is set to true', () => {
const wrapper = mountWithTheme(
<MenuButton buttonType="primary" defaultOpen options={options}>
Expand Down
10 changes: 7 additions & 3 deletions packages/react/src/components/menu-button/menu-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const MenuButton: FunctionComponent<PropsWithChildren<Props>> = ({
onMenuVisibilityChanged,
}) => {
const [visible, setVisible] = useState(!!defaultOpen);
const initialFocusIndex = 0;
const [initialFocusIndex, setInitialFocusIndex] = useState(0);
const buttonRef = useRef<HTMLButtonElement>(null);
const containerRef = useRef<HTMLDivElement>(null);

Expand Down Expand Up @@ -73,11 +73,15 @@ export const MenuButton: FunctionComponent<PropsWithChildren<Props>> = ({

/**
* Set focus on first menu item conditionally
* irrespective of whether it's a keypress, or a mouse event
* depending on whether it's a keypress, or a mouse event
* @type {() => void}
*/
const handleClickInside = useCallback(() => {
const handleClickInside = useCallback((event: React.MouseEvent<HTMLButtonElement>) => {
setVisible(!visible);
// event.detail returns an integer, indicating how many clicks there were
// If it's 0, no click was made and onClick was fired by a keypress
const focusIndex = event.detail === 0 ? 0 : -1;
setInitialFocusIndex(focusIndex);
}, [visible]);

/**
Expand Down

0 comments on commit e3b42a0

Please sign in to comment.