// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. import { Constants } from "./constants"; import { Collection } from "./collection"; import { PopupControl } from "./popup-control"; import { MenuItem } from "./menu-item"; export class PopupMenu extends PopupControl { private _items: Collection = new Collection(); private _renderedItems: Array = []; private _selectedIndex: number = -1; protected renderContent(): HTMLElement { const element = document.createElement("div"); element.className = this.hostConfig.makeCssClassName("ac-ctrl ac-popup"); element.setAttribute("role", "menu"); for (let i = 0; i < this._items.length; i++) { const renderedItem = this._items.get(i).render(this.hostConfig); renderedItem.tabIndex = 0; element.appendChild(renderedItem); if (i == 0) { renderedItem.setAttribute("aria-expanded", "true"); } if (i === this.selectedIndex) { renderedItem.focus(); } this._renderedItems.push(renderedItem); } return element; } keyDown(e: KeyboardEvent) { super.keyDown(e); let selectedItemIndex = this._selectedIndex; switch (e.key) { case Constants.keys.tab: this.closePopup(true); break; /* case Constants.keys.enter: if (this.selectedIndex >= 0) { this.selectedIndex = this.selectedIndex; this.close(); } break; */ case Constants.keys.up: if (selectedItemIndex <= 0) { selectedItemIndex = this._renderedItems.length - 1; } else { selectedItemIndex--; if (selectedItemIndex < 0) { selectedItemIndex = this._renderedItems.length - 1; } } this.selectedIndex = selectedItemIndex; this.removeAriaExpanded(selectedItemIndex); e.cancelBubble = true; break; case Constants.keys.down: if (selectedItemIndex < 0) { selectedItemIndex = 0; } else { selectedItemIndex++; if (selectedItemIndex >= this._renderedItems.length) { selectedItemIndex = 0; } this.removeAriaExpanded(selectedItemIndex); } this.selectedIndex = selectedItemIndex; e.cancelBubble = true; break; } } get items(): Collection { return this._items; } get selectedIndex(): number { return this._selectedIndex; } set selectedIndex(index: number) { if (index >= 0 && index < this._renderedItems.length) { this._renderedItems[index].focus(); this._selectedIndex = index; } } // remove aria-expanded attribute from menu item private removeAriaExpanded(index: number) { if (this._renderedItems[index].getAttribute("aria-expanded") === "true") { this._renderedItems[index].removeAttribute("aria-expanded"); } } }