Skip to content

Commit

Permalink
fix: Menu trigger should be focused when dismissed on menuitem click (#…
Browse files Browse the repository at this point in the history
…25289)

* fix: Menu trigger should be focused when dismissed on menuitem click

Replaces `shouldHandleKeyboardRef` with `shouldHandlCloseRef` so that
mouse and keyboard click are handled the same way.

* changefiles

* revert overflow changes

* update change file
  • Loading branch information
ling1726 authored Oct 19, 2022
1 parent bd212e7 commit 099d9f0
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "fix: Menu trigger should be focused when dismissed by menuitem click",
"packageName": "@fluentui/react-menu",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "none",
"comment": "Remove it.only from unit tests",
"packageName": "@fluentui/react-overflow",
"email": "[email protected]",
"dependentChangeType": "none"
}
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,26 @@ describe('Menu', () => {
cy.get(menuTriggerSelector).click().get(menuSelector).should('exist').realPress(['Shift', 'Tab']);
cy.contains('Before').should('be.focused').get(menuSelector).should('not.exist');
});

(['Enter', 'Space'] as const).forEach(key => {
it(`should close menu and focus trigger on ${key}`, () => {
mount(
<Menu>
<MenuTrigger>
<button>Menu</button>
</MenuTrigger>
<MenuPopover>
<MenuList>
<MenuItem>Item</MenuItem>
</MenuList>
</MenuPopover>
</Menu>,
);

cy.get(menuTriggerSelector).click().get(menuSelector).should('exist').realPress(key);
cy.get(menuSelector).should('not.exist').get(menuTriggerSelector).should('be.focused');
});
});
});

describe('SplitMenuItem', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ const useMenuOpenState = (
const parentSetOpen = useMenuContext_unstable(context => context.setOpen);
const onOpenChange: MenuState['onOpenChange'] = useEventCallback((e, data) => state.onOpenChange?.(e, data));

const shouldHandleKeyboardRef = React.useRef(false);
const shouldHandleCloseRef = React.useRef(false);
const shouldHandleTabRef = React.useRef(false);
const pressedShiftRef = React.useRef(false);
const setOpenTimeout = React.useRef(0);
Expand All @@ -183,10 +183,10 @@ const useMenuOpenState = (

if (!data.open) {
state.setContextTarget(undefined);
shouldHandleCloseRef.current = true;
}

if (e.type === 'keydown') {
shouldHandleKeyboardRef.current = true;
if ((e as React.KeyboardEvent<HTMLElement>).key === Tab) {
shouldHandleTabRef.current = true;
pressedShiftRef.current = (e as React.KeyboardEvent<HTMLElement>).shiftKey;
Expand Down Expand Up @@ -284,26 +284,20 @@ const useMenuOpenState = (
React.useEffect(() => {
if (open) {
focusFirst();
}
}, [open, focusFirst]);

React.useEffect(() => {
if (open) {
focusFirst();
}

if (shouldHandleKeyboardRef.current && !open) {
if (shouldHandleTabRef.current && !state.isSubmenu) {
pressedShiftRef.current ? focusBeforeMenuTrigger() : focusAfterMenuTrigger();
} else {
state.triggerRef.current?.focus();
} else {
if (shouldHandleCloseRef.current) {
if (shouldHandleTabRef.current && !state.isSubmenu) {
pressedShiftRef.current ? focusBeforeMenuTrigger() : focusAfterMenuTrigger();
} else {
state.triggerRef.current?.focus();
}
}
}

shouldHandleKeyboardRef.current = false;
shouldHandleCloseRef.current = false;
shouldHandleTabRef.current = false;
pressedShiftRef.current = false;
}, [state.triggerRef, state.isSubmenu, open, focusFirst, focusAfterMenuTrigger, focusBeforeMenuTrigger]);

return [open ?? false, setOpen] as const;
return [open, setOpen] as const;
};

0 comments on commit 099d9f0

Please sign in to comment.