import { useEffect, useCallback } from 'react'; interface KeyboardShortcut { key: string; ctrlOrCmd?: boolean; shift?: boolean; alt?: boolean; handler: () => void; description: string; } interface UseKeyboardShortcutsOptions { shortcuts: KeyboardShortcut[]; enabled?: boolean; } /** * Hook for registering keyboard shortcuts * Automatically handles Cmd (Mac) vs Ctrl (Windows/Linux) */ export function useKeyboardShortcuts({ shortcuts, enabled = true }: UseKeyboardShortcutsOptions) { const handleKeyDown = useCallback( (event: KeyboardEvent) => { if (!enabled) return; // Ignore shortcuts when typing in input fields const target = event.target as HTMLElement; if ( target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable ) { return; } for (const shortcut of shortcuts) { const matchesKey = event.key.toLowerCase() === shortcut.key.toLowerCase(); const matchesCtrl = !shortcut.ctrlOrCmd || (event.ctrlKey || event.metaKey); const matchesShift = !shortcut.shift || event.shiftKey; const matchesAlt = !shortcut.alt || event.altKey; if (matchesKey && matchesCtrl && matchesShift && matchesAlt) { event.preventDefault(); shortcut.handler(); break; } } }, [shortcuts, enabled] ); useEffect(() => { if (!enabled) return; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, [handleKeyDown, enabled]); return { shortcuts: shortcuts.map(s => ({ ...s, displayKey: `${s.ctrlOrCmd ? '⌘/Ctrl + ' : ''}${s.shift ? 'Shift + ' : ''}${s.alt ? 'Alt + ' : ''}${s.key.toUpperCase()}`, })), }; }