import { useEffect, useRef } from 'react' import type { VaultEntry } from '../types' interface KeyboardNavigationOptions { activeTabPath: string | null visibleNotesRef: React.RefObject onReplaceActiveTab: (entry: VaultEntry) => void onSelectNote: (entry: VaultEntry) => void } function navigateNote( visibleNotesRef: React.RefObject, activeTabPathRef: React.RefObject, onReplace: React.RefObject<(entry: VaultEntry) => void>, onSelect: React.RefObject<(entry: VaultEntry) => void>, direction: 1 | -1, ) { const notes = visibleNotesRef.current! if (notes.length === 0) return const currentPath = activeTabPathRef.current const currentIndex = notes.findIndex((n) => n.path === currentPath) const nextIndex = currentIndex === -1 ? (direction === 1 ? 0 : notes.length - 1) : currentIndex + direction // Clamp to list bounds — don't wrap around if (nextIndex < 0 || nextIndex >= notes.length) return const nextNote = notes[nextIndex] if (currentPath) { onReplace.current!(nextNote) } else { onSelect.current!(nextNote) } } function useLatestRef(value: T): React.RefObject { const ref = useRef(value) useEffect(() => { ref.current = value }) return ref } export function useKeyboardNavigation({ activeTabPath, visibleNotesRef, onReplaceActiveTab, onSelectNote, }: KeyboardNavigationOptions) { const activeTabPathRef = useLatestRef(activeTabPath) const onReplaceRef = useLatestRef(onReplaceActiveTab) const onSelectNoteRef = useLatestRef(onSelectNote) useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { const mod = e.metaKey || e.ctrlKey if (!mod) return // Cmd+Alt+ArrowUp/Down: navigate notes in the current list if (e.altKey && !e.shiftKey && (e.key === 'ArrowUp' || e.key === 'ArrowDown')) { e.preventDefault() const direction: 1 | -1 = e.key === 'ArrowDown' ? 1 : -1 navigateNote(visibleNotesRef, activeTabPathRef, onReplaceRef, onSelectNoteRef, direction) } } window.addEventListener('keydown', handleKeyDown) return () => window.removeEventListener('keydown', handleKeyDown) }, [activeTabPathRef, visibleNotesRef, onReplaceRef, onSelectNoteRef]) }