Skip to content

Commit e87a66b

Browse files
authored
fix(aria/menu): lazy render trigger (#32203)
* fix(aria/menu): lazy render trigger * fixup! fix(aria/menu): lazy render trigger
1 parent d15fbb0 commit e87a66b

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

src/aria/menu/menu.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import {DeferredContent, DeferredContentAware} from '@angular/aria/deferred-cont
5151
'(click)': '_pattern.onClick()',
5252
'(keydown)': '_pattern.onKeydown($event)',
5353
'(focusout)': '_pattern.onFocusOut($event)',
54+
'(focusin)': 'onFocusIn()',
5455
},
5556
})
5657
export class MenuTrigger<V> {
@@ -65,6 +66,9 @@ export class MenuTrigger<V> {
6566
/** The menu associated with the trigger. */
6667
menu = input<Menu<V> | undefined>(undefined);
6768

69+
/** Whether the menu item has been focused. */
70+
readonly hasBeenFocused = signal(false);
71+
6872
/** The menu trigger ui pattern instance. */
6973
_pattern: MenuTriggerPattern<V> = new MenuTriggerPattern({
7074
element: computed(() => this._elementRef.nativeElement),
@@ -74,6 +78,11 @@ export class MenuTrigger<V> {
7478
constructor() {
7579
effect(() => this.menu()?.parent.set(this));
7680
}
81+
82+
/** Marks the menu trigger as having been focused. */
83+
onFocusIn() {
84+
this.hasBeenFocused.set(true);
85+
}
7786
}
7887

7988
/**
@@ -185,7 +194,14 @@ export class Menu<V> {
185194
});
186195

187196
afterRenderEffect(() => {
188-
this._deferredContentAware?.contentVisible.set(this._pattern.isVisible());
197+
const parent = this.parent();
198+
if (parent instanceof MenuItem && parent.parent instanceof MenuBar) {
199+
this._deferredContentAware?.contentVisible.set(true);
200+
} else {
201+
this._deferredContentAware?.contentVisible.set(
202+
this._pattern.isVisible() || !!this.parent()?.hasBeenFocused(),
203+
);
204+
}
189205
});
190206

191207
// TODO(wagnermaciel): This is a redundancy needed for if the user uses display: none to hide
@@ -322,6 +338,7 @@ export class MenuBar<V> {
322338
host: {
323339
'role': 'menuitem',
324340
'class': 'ng-menu-item',
341+
'(focusin)': 'onFocusIn()',
325342
'[attr.tabindex]': '_pattern.tabindex()',
326343
'[attr.data-active]': '_pattern.isActive()',
327344
'[attr.aria-haspopup]': '_pattern.hasPopup()',
@@ -363,6 +380,9 @@ export class MenuItem<V> {
363380
/** The submenu associated with the menu item. */
364381
readonly submenu = input<Menu<V> | undefined>(undefined);
365382

383+
/** Whether the menu item has been focused. */
384+
readonly hasBeenFocused = signal(false);
385+
366386
/** The menu item ui pattern instance. */
367387
readonly _pattern: MenuItemPattern<V> = new MenuItemPattern<V>({
368388
id: this.id,
@@ -377,6 +397,11 @@ export class MenuItem<V> {
377397
constructor() {
378398
effect(() => this.submenu()?.parent.set(this));
379399
}
400+
401+
/** Marks the menu item as having been focused. */
402+
onFocusIn() {
403+
this.hasBeenFocused.set(true);
404+
}
380405
}
381406

382407
/** Defers the rendering of the menu content. */

0 commit comments

Comments
 (0)