import { useEffect, useRef } from 'react' export interface KeyboardShortcutHandlers { onSpace?: () => void onArrowUp?: (shift: boolean) => void onArrowDown?: (shift: boolean) => void onArrowLeft?: (shift: boolean) => void onArrowRight?: (shift: boolean) => void onEnter?: () => void onDoubleEnter?: () => void onR?: () => void onShiftR?: () => void onC?: () => void onShiftC?: () => void onI?: () => void onEscape?: () => void } const DOUBLE_ENTER_THRESHOLD = 300 export function useKeyboardShortcuts(handlers: KeyboardShortcutHandlers) { const handlersRef = useRef(handlers) useEffect(() => { handlersRef.current = handlers }, [handlers]) useEffect(() => { let lastEnterTime = 0 const handleKeyDown = (e: KeyboardEvent) => { if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) { return } const h = handlersRef.current switch (e.key) { case ' ': e.preventDefault() h.onSpace?.() break case 'ArrowUp': e.preventDefault() h.onArrowUp?.(e.shiftKey) break case 'ArrowDown': e.preventDefault() h.onArrowDown?.(e.shiftKey) break case 'ArrowLeft': e.preventDefault() h.onArrowLeft?.(e.shiftKey) break case 'ArrowRight': e.preventDefault() h.onArrowRight?.(e.shiftKey) break case 'Enter': { e.preventDefault() const now = Date.now() if (now - lastEnterTime < DOUBLE_ENTER_THRESHOLD) { h.onDoubleEnter?.() } else { h.onEnter?.() } lastEnterTime = now break } case 'r': case 'R': e.preventDefault() if (e.shiftKey) { h.onShiftR?.() } else { h.onR?.() } break case 'c': case 'C': e.preventDefault() if (e.shiftKey) { h.onShiftC?.() } else { h.onC?.() } break case 'i': case 'I': e.preventDefault() h.onI?.() break case 'Escape': e.preventDefault() h.onEscape?.() break } } window.addEventListener('keydown', handleKeyDown) return () => window.removeEventListener('keydown', handleKeyDown) }, []) }