Skip to content

Commit ce20dbe

Browse files
committed
fix(aria/menu): lazy render trigger (#32203)
* fix(aria/menu): lazy render trigger * fixup! fix(aria/menu): lazy render trigger
1 parent 1909503 commit ce20dbe

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
@@ -53,6 +53,7 @@ import {DeferredContent, DeferredContentAware} from '@angular/aria/deferred-cont
5353
'(click)': '_pattern.onClick()',
5454
'(keydown)': '_pattern.onKeydown($event)',
5555
'(focusout)': '_pattern.onFocusOut($event)',
56+
'(focusin)': 'onFocusIn()',
5657
},
5758
})
5859
export class MenuTrigger<V> {
@@ -67,6 +68,9 @@ export class MenuTrigger<V> {
6768
/** The menu associated with the trigger. */
6869
menu = input<Menu<V> | undefined>(undefined);
6970

71+
/** Whether the menu item has been focused. */
72+
readonly hasBeenFocused = signal(false);
73+
7074
/** The menu trigger ui pattern instance. */
7175
_pattern: MenuTriggerPattern<V> = new MenuTriggerPattern({
7276
element: computed(() => this._elementRef.nativeElement),
@@ -76,6 +80,11 @@ export class MenuTrigger<V> {
7680
constructor() {
7781
effect(() => this.menu()?.parent.set(this));
7882
}
83+
84+
/** Marks the menu trigger as having been focused. */
85+
onFocusIn() {
86+
this.hasBeenFocused.set(true);
87+
}
7988
}
8089

8190
/**
@@ -187,7 +196,14 @@ export class Menu<V> {
187196
});
188197

189198
afterRenderEffect(() => {
190-
this._deferredContentAware?.contentVisible.set(this._pattern.isVisible());
199+
const parent = this.parent();
200+
if (parent instanceof MenuItem && parent.parent instanceof MenuBar) {
201+
this._deferredContentAware?.contentVisible.set(true);
202+
} else {
203+
this._deferredContentAware?.contentVisible.set(
204+
this._pattern.isVisible() || !!this.parent()?.hasBeenFocused(),
205+
);
206+
}
191207
});
192208

193209
// TODO(wagnermaciel): This is a redundancy needed for if the user uses display: none to hide
@@ -324,6 +340,7 @@ export class MenuBar<V> {
324340
host: {
325341
'role': 'menuitem',
326342
'class': 'ng-menu-item',
343+
'(focusin)': 'onFocusIn()',
327344
'[attr.tabindex]': '_pattern.tabindex()',
328345
'[attr.data-active]': '_pattern.isActive()',
329346
'[attr.aria-haspopup]': '_pattern.hasPopup()',
@@ -365,6 +382,9 @@ export class MenuItem<V> {
365382
/** The submenu associated with the menu item. */
366383
readonly submenu = input<Menu<V> | undefined>(undefined);
367384

385+
/** Whether the menu item has been focused. */
386+
readonly hasBeenFocused = signal(false);
387+
368388
/** The menu item ui pattern instance. */
369389
readonly _pattern: MenuItemPattern<V> = new MenuItemPattern<V>({
370390
id: this.id,
@@ -379,6 +399,11 @@ export class MenuItem<V> {
379399
constructor() {
380400
effect(() => this.submenu()?.parent.set(this));
381401
}
402+
403+
/** Marks the menu item as having been focused. */
404+
onFocusIn() {
405+
this.hasBeenFocused.set(true);
406+
}
382407
}
383408

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

0 commit comments

Comments
 (0)