Skip to content

Commit

Permalink
fix(menu): allow submenus to close when focus is lost
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 563207098
  • Loading branch information
Elliott Marquez authored and copybara-github committed Sep 6, 2023
1 parent 046c96f commit 7a19c7e
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 21 deletions.
3 changes: 0 additions & 3 deletions menu/internal/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,9 +339,6 @@ export abstract class Menu extends LitElement {
return;
}

// Stop propagation to prevent nested menus from interfering with each other
event.stopPropagation();

if (event.relatedTarget) {
// Don't close the menu if we are switching focus between menu,
// md-menu-item, and md-list
Expand Down
28 changes: 10 additions & 18 deletions menu/internal/submenuitem/sub-menu-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {List} from '../../../list/internal/list.js';
import {MdRipple} from '../../../ripple/ripple.js';
import {Corner, Menu} from '../menu.js';
import {MenuItemEl} from '../menuitem/menu-item.js';
import {CLOSE_REASON, CloseMenuEvent, createActivateTypeaheadEvent, createCloseOnFocusoutEvent, createDeactivateItemsEvent, createDeactivateTypeaheadEvent, createStayOpenOnFocusoutEvent, KEYDOWN_CLOSE_KEYS, NAVIGABLE_KEY, SELECTION_KEY} from '../shared.js';
import {CLOSE_REASON, CloseMenuEvent, createActivateTypeaheadEvent, createDeactivateItemsEvent, createDeactivateTypeaheadEvent, KEYDOWN_CLOSE_KEYS, NAVIGABLE_KEY, SELECTION_KEY} from '../shared.js';

/**
* @fires deactivate-items Requests the parent menu to deselect other items when
Expand All @@ -20,11 +20,6 @@ import {CLOSE_REASON, CloseMenuEvent, createActivateTypeaheadEvent, createCloseO
* typeahead functionality when a submenu opens
* @fires activate-typeahead Requests the parent menu to activate the typeahead
* functionality when a submenu closes
* @fires stay-open-on-focusout Requests the parent menu to stay open when
* focusout event is fired or has a `null` `relatedTarget` when submenu is
* opened.
* @fires close-on-focusout Requests the parent menu to close when focusout
* event is fired or has a `null` `relatedTarget` When submenu is closed.
*/
export class SubMenuItem extends MenuItemEl {
/**
Expand Down Expand Up @@ -175,8 +170,7 @@ export class SubMenuItem extends MenuItemEl {
private onCloseSubmenu(event: CloseMenuEvent) {
const {itemPath, reason} = event.detail;
itemPath.push(this);
// Restore focusout behavior
this.dispatchEvent(createCloseOnFocusoutEvent());

this.dispatchEvent(createActivateTypeaheadEvent());
// Escape should only close one menu not all of the menus unlike space or
// click selection which should close all menus.
Expand Down Expand Up @@ -232,17 +226,17 @@ export class SubMenuItem extends MenuItemEl {
// want to focus the root on hover, so the user can pick up navigation with
// keyboard after hover.
menu.defaultFocus = 'LIST_ROOT';
menu.skipRestoreFocus = true;
menu.stayOpenOnOutsideClick = true;
menu.stayOpenOnFocusout = true;
// This is required in the case where we have a leaf menu open and and the
// user hovers a parent menu's item which is not an md-sub-menu item.
// If this were set to true, then the menu would close and focus would be
// lost. That means the focusout event would have a `relatedTarget` of
// `null` since nothing in the menu would be focused anymore due to the
// leaf menu closing. restoring focus ensures that we keep focus in the
// submenu tree.
menu.skipRestoreFocus = false;

// Menu could already be opened because of mouse interaction
const menuAlreadyOpen = menu.open;
// We want the parent to stay open in the case such that a middle submenu
// has a submenuitem hovered which opens a third submenut. Then if you hover
// on yet another middle menu-item (not submenuitem) then focusout Event's
// relatedTarget will be `null` thus, causing all the menus to close
this.dispatchEvent(createStayOpenOnFocusoutEvent());
menu.show();

// Deactivate other items. This can be the case if the user has tabbed
Expand Down Expand Up @@ -272,8 +266,6 @@ export class SubMenuItem extends MenuItemEl {
this.dispatchEvent(createActivateTypeaheadEvent());
menu.quick = true;
menu.close();
// Restore focusout behavior.
this.dispatchEvent(createCloseOnFocusoutEvent());
this.active = false;
this.selected = false;
menu.addEventListener('closed', onClosed, {once: true});
Expand Down

0 comments on commit 7a19c7e

Please sign in to comment.