export function menuItems() { let items: HTMLElement[] = []; const focus = (index: number) => { if (items.length === 0) return; const wrapped = ((index % items.length) + items.length) % items.length; items[wrapped]?.focus({ preventScroll: true }); }; return { register(el: HTMLElement) { const index = items.findIndex( (item) => item.compareDocumentPosition(el) & Node.DOCUMENT_POSITION_PRECEDING ); if (index === -1) { items.push(el); } else { items.splice(index, 0, el); } return () => { items = items.filter((item) => item !== el); }; }, focus, navigate(event: KeyboardEvent) { const current = items.indexOf(event.target as HTMLElement); const targets: Record = { ArrowDown: current + 1, ArrowUp: current - 1, Home: 0, End: items.length - 1 }; if (!(event.key in targets)) return false; event.preventDefault(); focus(targets[event.key]!); return true; } }; }