From bfa1bec320b6a73f4a4a89e508223e873920e3ac Mon Sep 17 00:00:00 2001 From: Material Web Team Date: Fri, 24 Mar 2023 09:39:49 -0700 Subject: [PATCH] fix(menu): properly implement selected state Before, I set the focused, actively-keyboard-interacted, or pressed element as visual selected state. That doesn't seem to be how GMDC handles it and created problems down the line with md-select where we could not show the currently-selected item + keyboard navigation at the same time. This CL brings the behavior in line with GMDC and fixes this problem down the line for select. Also in this CL I add the selected state to sub-menu-item when it's open PiperOrigin-RevId: 519166067 --- list/lib/listitem/list-item.ts | 6 +++--- menu/lib/menuitem/_menu-item.scss | 4 +--- menu/lib/submenuitem/sub-menu-item.ts | 8 ++++++++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/list/lib/listitem/list-item.ts b/list/lib/listitem/list-item.ts index 935e4a60a1..1d6eba8f31 100644 --- a/list/lib/listitem/list-item.ts +++ b/list/lib/listitem/list-item.ts @@ -82,9 +82,9 @@ export class ListItemEl extends LitElement implements ListItem { @property({type: Number}) itemTabIndex = -1; /** - * Whether or not the element is in the selected visual state. When active, - * tabindex is set to 0, and in some list item variants (like md-list-item), - * focuses the underlying item. + * Whether or not the element is actively being interacted with by md-list. + * When active, tabindex is set to 0, and in some list item variants (like + * md-list-item), focuses the underlying item. */ @property({type: Boolean, reflect: true}) active = false; diff --git a/menu/lib/menuitem/_menu-item.scss b/menu/lib/menuitem/_menu-item.scss index 4062a15167..accaafb13c 100644 --- a/menu/lib/menuitem/_menu-item.scss +++ b/menu/lib/menuitem/_menu-item.scss @@ -36,9 +36,7 @@ $_custom-property-prefix: 'menu'; } .list-item { - :host([active]) &, - :host(:active) &, - &:focus { + :host([selected]) & { background-color: var(--_list-item-selected-container-color); } } diff --git a/menu/lib/submenuitem/sub-menu-item.ts b/menu/lib/submenuitem/sub-menu-item.ts index 9edf9caad3..be4633b619 100644 --- a/menu/lib/submenuitem/sub-menu-item.ts +++ b/menu/lib/submenuitem/sub-menu-item.ts @@ -44,6 +44,10 @@ export class SubMenuItem extends MenuItemEl { */ @property({type: Number, attribute: 'hover-close-delay'}) hoverCloseDelay = 400; + /** + * Sets the item in the selected visual state when a submenu is opened. + */ + @property({type: Boolean, reflect: true}) selected = false; @queryAssignedElements({slot: 'submenu', flatten: true}) protected menus!: Menu[]; @@ -157,12 +161,14 @@ export class SubMenuItem extends MenuItemEl { e.reason.key === KEYDOWN_CLOSE_KEYS.ESCAPE) { e.stopPropagation(); this.active = true; + this.selected = false; // It might already be active so manually focus this.listItemRoot.focus(); return; } this.active = false; + this.selected = false; } protected async onSubMenuKeydown(e: KeyboardEvent) { @@ -212,6 +218,7 @@ export class SubMenuItem extends MenuItemEl { this.dispatchEvent(new DeactivateItemsEvent()); this.dispatchEvent(new DeactivateTypeaheadEvent()); this.active = true; + this.selected = true; // This is the case of mouse hovering when already opened via keyboard or // vice versa @@ -235,6 +242,7 @@ export class SubMenuItem extends MenuItemEl { menu.quick = true; menu.close(); this.active = false; + this.selected = false; menu.addEventListener('closed', onClosed, {once: true}); }