diff --git a/src/aria/menu/menu.ts b/src/aria/menu/menu.ts index 308c5045ab56..ce6959094e52 100644 --- a/src/aria/menu/menu.ts +++ b/src/aria/menu/menu.ts @@ -51,6 +51,7 @@ import {DeferredContent, DeferredContentAware} from '@angular/aria/deferred-cont '(click)': '_pattern.onClick()', '(keydown)': '_pattern.onKeydown($event)', '(focusout)': '_pattern.onFocusOut($event)', + '(focusin)': 'onFocusIn()', }, }) export class MenuTrigger { @@ -65,6 +66,9 @@ export class MenuTrigger { /** The menu associated with the trigger. */ menu = input | undefined>(undefined); + /** Whether the menu item has been focused. */ + readonly hasBeenFocused = signal(false); + /** The menu trigger ui pattern instance. */ _pattern: MenuTriggerPattern = new MenuTriggerPattern({ element: computed(() => this._elementRef.nativeElement), @@ -74,6 +78,11 @@ export class MenuTrigger { constructor() { effect(() => this.menu()?.parent.set(this)); } + + /** Marks the menu trigger as having been focused. */ + onFocusIn() { + this.hasBeenFocused.set(true); + } } /** @@ -185,7 +194,14 @@ export class Menu { }); afterRenderEffect(() => { - this._deferredContentAware?.contentVisible.set(this._pattern.isVisible()); + const parent = this.parent(); + if (parent instanceof MenuItem && parent.parent instanceof MenuBar) { + this._deferredContentAware?.contentVisible.set(true); + } else { + this._deferredContentAware?.contentVisible.set( + this._pattern.isVisible() || !!this.parent()?.hasBeenFocused(), + ); + } }); // TODO(wagnermaciel): This is a redundancy needed for if the user uses display: none to hide @@ -322,6 +338,7 @@ export class MenuBar { host: { 'role': 'menuitem', 'class': 'ng-menu-item', + '(focusin)': 'onFocusIn()', '[attr.tabindex]': '_pattern.tabindex()', '[attr.data-active]': '_pattern.isActive()', '[attr.aria-haspopup]': '_pattern.hasPopup()', @@ -363,6 +380,9 @@ export class MenuItem { /** The submenu associated with the menu item. */ readonly submenu = input | undefined>(undefined); + /** Whether the menu item has been focused. */ + readonly hasBeenFocused = signal(false); + /** The menu item ui pattern instance. */ readonly _pattern: MenuItemPattern = new MenuItemPattern({ id: this.id, @@ -377,6 +397,11 @@ export class MenuItem { constructor() { effect(() => this.submenu()?.parent.set(this)); } + + /** Marks the menu item as having been focused. */ + onFocusIn() { + this.hasBeenFocused.set(true); + } } /** Defers the rendering of the menu content. */