diff --git a/src/components/menu/menu.ts b/src/components/menu/menu.ts index 78ada4afb..bd8c29749 100644 --- a/src/components/menu/menu.ts +++ b/src/components/menu/menu.ts @@ -1,7 +1,6 @@ import { html } from 'lit'; import { customElement, query } from 'lit/decorators.js'; import ShoelaceElement from '../../internal/shoelace-element'; -import { getTextContent } from '../../internal/slot'; import styles from './menu.styles'; import type SlMenuItem from '../menu-item/menu-item'; import type { CSSResultGroup } from 'lit'; @@ -23,9 +22,6 @@ export interface MenuSelectEventDetail { export default class SlMenu extends ShoelaceElement { static styles: CSSResultGroup = styles; - private typeToSelectString = ''; - private typeToSelectTimeout: number; - @query('slot') defaultSlot: HTMLSlotElement; connectedCallback() { @@ -47,24 +43,6 @@ export default class SlMenu extends ShoelaceElement { }) as SlMenuItem[]; } - // Gets the current menu item, which is the menu item that has `tabindex="0"` within the roving tab index. The menu - // item may or may not have focus, but for keyboard interaction purposes it's considered the "active" item. - private getCurrentItem() { - return this.getAllItems({ includeDisabled: false }).find(i => i.getAttribute('tabindex') === '0'); - } - - // Sets the current menu item to the specified element. This sets `tabindex="0"` on the target element and - // `tabindex="-1"` to all other items. This method must be called prior to setting focus on a menu item. - private setCurrentItem(item: SlMenuItem) { - const items = this.getAllItems({ includeDisabled: false }); - const activeItem = item.disabled ? items[0] : item; - - // Update tab indexes - items.forEach(i => { - i.setAttribute('tabindex', i === activeItem ? '0' : '-1'); - }); - } - private handleClick(event: MouseEvent) { const target = event.target as HTMLElement; const item = target.closest('sl-menu-item'); @@ -117,12 +95,8 @@ export default class SlMenu extends ShoelaceElement { this.setCurrentItem(items[index]); items[index].focus(); - - return; } } - - this.typeToSelect(event); } private handleMouseDown(event: MouseEvent) { @@ -143,37 +117,25 @@ export default class SlMenu extends ShoelaceElement { } /** - * Initiates type-to-select logic, which automatically selects an option based on what the user is currently typing. - * The event passed will be used to append the appropriate characters to the internal query and the selection will be - * updated. After a brief period, the internal query is cleared automatically. This is useful for enabling - * type-to-select behavior when the menu doesn't have focus. + * @internal Gets the current menu item, which is the menu item that has `tabindex="0"` within the roving tab index. + * The menu item may or may not have focus, but for keyboard interaction purposes it's considered the "active" item. */ - typeToSelect(event: KeyboardEvent) { + getCurrentItem() { + return this.getAllItems({ includeDisabled: false }).find(i => i.getAttribute('tabindex') === '0'); + } + + /** + * @internal Sets the current menu item to the specified element. This sets `tabindex="0"` on the target element and + * `tabindex="-1"` to all other items. This method must be called prior to setting focus on a menu item. + */ + setCurrentItem(item: SlMenuItem) { const items = this.getAllItems({ includeDisabled: false }); - clearTimeout(this.typeToSelectTimeout); - this.typeToSelectTimeout = window.setTimeout(() => (this.typeToSelectString = ''), 1000); + const activeItem = item.disabled ? items[0] : item; - if (event.key === 'Backspace') { - if (event.metaKey || event.ctrlKey) { - this.typeToSelectString = ''; - } else { - this.typeToSelectString = this.typeToSelectString.slice(0, -1); - } - } else { - this.typeToSelectString += event.key.toLowerCase(); - } - - for (const item of items) { - const slot = item.shadowRoot?.querySelector('slot:not([name])'); - const label = getTextContent(slot).toLowerCase().trim(); - if (label.startsWith(this.typeToSelectString)) { - this.setCurrentItem(item); - - // Set focus here to force the browser to show :focus-visible styles - item.focus(); - break; - } - } + // Update tab indexes + items.forEach(i => { + i.setAttribute('tabindex', i === activeItem ? '0' : '-1'); + }); } render() {