diff --git a/goldens/aria/private/index.api.md b/goldens/aria/private/index.api.md index a605f4808bd1..d8377b1340c3 100644 --- a/goldens/aria/private/index.api.md +++ b/goldens/aria/private/index.api.md @@ -439,7 +439,6 @@ export class MenuPattern { _clearTimeouts(): void; close(): void; closeAll(): void; - _closeTimeout: any; collapse(): void; readonly disabled: () => boolean; readonly dynamicSpaceKey: SignalLike<"" | " ">; @@ -451,6 +450,7 @@ export class MenuPattern { // (undocumented) readonly inputs: MenuInputs; readonly isFocused: WritableSignalLike; + readonly items: () => MenuItemPattern[]; readonly keydownManager: SignalLike>; last(): void; readonly listBehavior: List, V | undefined>; @@ -461,7 +461,6 @@ export class MenuPattern { onKeydown(event: KeyboardEvent): void; onMouseOut(event: MouseEvent): void; onMouseOver(event: MouseEvent): void; - _openTimeout: any; prev(): void; readonly role: () => string; readonly root: SignalLike | MenuBarPattern | MenuPattern | undefined>; diff --git a/src/aria/private/menu/menu.ts b/src/aria/private/menu/menu.ts index d739d3e22136..c7ff24ec72d6 100644 --- a/src/aria/private/menu/menu.ts +++ b/src/aria/private/menu/menu.ts @@ -105,11 +105,14 @@ export class MenuPattern { /** Whether the menu trigger has been hovered. */ readonly hasBeenHovered = signal(false); + /** Items currently inside the menu. */ + readonly items = () => this.inputs.items(); + /** Timeout used to open sub-menus on hover. */ - _openTimeout: any; + private _openTimeout: ReturnType | undefined; /** Timeout used to close sub-menus on hover out. */ - _closeTimeout: any; + private _closeTimeout: ReturnType | undefined; /** The tab index of the menu. */ readonly tabIndex = () => this.listBehavior.tabIndex(); @@ -246,7 +249,7 @@ export class MenuPattern { } const parent = this.inputs.parent(); - const activeItem = this?.inputs.activeItem(); + const activeItem = this.inputs.activeItem(); if (parent instanceof MenuItemPattern) { const grandparent = parent.inputs.parent(); @@ -689,7 +692,11 @@ export class MenuTriggerPattern { pendingFocusEffect(): void { const menu = this.inputs.menu(); const intent = this.pendingFocus(); - if (menu && intent) { + const items = menu?.items(); + + // We check the items so that we don't try calling into + // `first/last` until the items are actually available. + if (menu && intent && items?.length) { if (intent === 'first') { menu.first(); } else if (intent === 'last') {