| 140 | |
| 141 | // Keyboard shortcut hook for undo/redo |
| 142 | export function useUndoRedoKeyboard( |
| 143 | onUndo: () => void, |
| 144 | onRedo: () => void, |
| 145 | enabled: boolean = true |
| 146 | ) { |
| 147 | useEffect(() => { |
| 148 | if (!enabled) return; |
| 149 | |
| 150 | const handleKeyDown = (event: KeyboardEvent) => { |
| 151 | // Check for Ctrl (Windows/Linux) or Cmd (Mac) |
| 152 | const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0; |
| 153 | const modifier = isMac ? event.metaKey : event.ctrlKey; |
| 154 | |
| 155 | if (!modifier) return; |
| 156 | |
| 157 | // Avoid interfering with text inputs |
| 158 | const activeElement = document.activeElement; |
| 159 | const isInputActive = |
| 160 | activeElement instanceof HTMLInputElement || |
| 161 | activeElement instanceof HTMLTextAreaElement || |
| 162 | (activeElement as HTMLElement)?.isContentEditable; |
| 163 | |
| 164 | if (isInputActive) return; |
| 165 | |
| 166 | if (event.key === 'z' || event.key === 'Z') { |
| 167 | event.preventDefault(); |
| 168 | if (event.shiftKey) { |
| 169 | // Ctrl/Cmd + Shift + Z = Redo |
| 170 | onRedo(); |
| 171 | } else { |
| 172 | // Ctrl/Cmd + Z = Undo |
| 173 | onUndo(); |
| 174 | } |
| 175 | } |
| 176 | |
| 177 | // Also support Ctrl/Cmd + Y for redo (common on Windows) |
| 178 | if (event.key === 'y' || event.key === 'Y') { |
| 179 | if (!event.shiftKey) { |
| 180 | event.preventDefault(); |
| 181 | onRedo(); |
| 182 | } |
| 183 | } |
| 184 | }; |
| 185 | |
| 186 | window.addEventListener('keydown', handleKeyDown); |
| 187 | return () => window.removeEventListener('keydown', handleKeyDown); |
| 188 | }, [onUndo, onRedo, enabled]); |
| 189 | } |