Skip to content

Commit

Permalink
fix: only focus parent item if sub-menu contained focus (#7519)
Browse files Browse the repository at this point in the history
  • Loading branch information
web-padawan authored Jul 9, 2024
1 parent 703939b commit d6be7a4
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
10 changes: 9 additions & 1 deletion packages/context-menu/src/vaadin-contextmenu-items-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,10 @@ export const ItemsMixin = (superClass) =>
if (item) {
const { children } = item._item;

// Check if the sub-menu was focused before closing it.
const child = subMenu._overlayElement.getFirstChild();
const isSubmenuFocused = child && child.focused;

if (subMenu.items !== children) {
subMenu.close();
}
Expand All @@ -374,8 +378,12 @@ export const ItemsMixin = (superClass) =>
// Forward parent overlay class
const { overlayClass } = this;
this.__openSubMenu(subMenu, item, overlayClass);
} else {
} else if (isSubmenuFocused) {
// If the sub-menu item was focused, focus its parent item.
subMenu.listenOn.focus();
} else if (!this._listBox.focused) {
// Otherwise, focus the overlay part to handle arrow keys.
this._overlayElement.$.overlay.focus();
}
}
}
Expand Down
16 changes: 16 additions & 0 deletions packages/context-menu/test/items.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,22 @@ describe('items', () => {
expect(focusSpy.called).to.be.true;
});

(isTouch ? it.skip : it)('should focus overlay part on closing sub-menu without focused item', async () => {
const parent = getMenuItems(rootMenu)[3];
await openMenu(parent);
const nonParent = getMenuItems(rootMenu)[1];
const focusSpy = sinon.spy(rootOverlay.$.overlay, 'focus');
await openMenu(nonParent);
expect(focusSpy.called).to.be.true;
});

(isTouch ? it.skip : it)('should not focus overlay part if the parent menu list-box has focus', async () => {
await openMenu(getMenuItems(rootMenu)[1]);
const focusSpy = sinon.spy(rootOverlay.$.overlay, 'focus');
await openMenu(getMenuItems(rootMenu)[2]);
expect(focusSpy.called).to.be.false;
});

it('should not close the menu if root item has keep open', () => {
getMenuItems(rootMenu)[2].click();
expect(rootMenu.opened).to.be.true;
Expand Down

0 comments on commit d6be7a4

Please sign in to comment.