import type { Ref } from 'vue' export interface RovingFocusOptions { orientation?: 'vertical' | 'horizontal' loop?: boolean } export function useRovingFocus(itemsRef: Ref, options: RovingFocusOptions = {}) { const orientation = options.orientation ?? 'vertical' const loop = options.loop ?? true function focusIndex(index: number) { const items = itemsRef.value if (items.length === 0) return const clamped = loop ? ((index % items.length) + items.length) % items.length : Math.max(0, Math.min(index, items.length - 1)) items[clamped]?.focus() } function handleKeydown(event: KeyboardEvent) { const items = itemsRef.value if (items.length === 0) return const currentIndex = items.indexOf(document.activeElement as HTMLElement) const nextKey = orientation === 'vertical' ? 'ArrowDown' : 'ArrowRight' const prevKey = orientation === 'vertical' ? 'ArrowUp' : 'ArrowLeft' if (event.key === nextKey) { event.preventDefault() focusIndex(currentIndex + 1) } else if (event.key === prevKey) { event.preventDefault() focusIndex(currentIndex - 1) } else if (event.key === 'Home') { event.preventDefault() focusIndex(0) } else if (event.key === 'End') { event.preventDefault() focusIndex(items.length - 1) } } return { handleKeydown, focusIndex } }