Files
kandev/apps/web/hooks/use-capture-keydown.ts
T
2026-02-19 22:18:01 +00:00

42 lines
1.3 KiB
TypeScript

import { useEffect, useRef, type RefObject } from "react";
type CaptureKeydownShortcut = {
key: string;
metaOrCtrl?: boolean;
alt?: boolean;
shift?: boolean;
};
/**
* Attach a capture-phase keydown listener to a wrapper element.
* Useful for intercepting keyboard shortcuts before embedded editors
* (Monaco, CodeMirror) consume them.
*/
export function useCaptureKeydown(
ref: RefObject<HTMLElement | null>,
shortcut: CaptureKeydownShortcut,
callback: () => void,
): void {
const callbackRef = useRef(callback);
useEffect(() => {
callbackRef.current = callback;
}, [callback]);
useEffect(() => {
const el = ref.current;
if (!el) return;
const handler = (e: KeyboardEvent) => {
const metaOrCtrl = shortcut.metaOrCtrl ? e.metaKey || e.ctrlKey : true;
const alt = shortcut.alt ? e.altKey : !e.altKey;
const shift = shortcut.shift ? e.shiftKey : !e.shiftKey;
if (metaOrCtrl && alt && shift && e.key === shortcut.key) {
e.preventDefault();
e.stopPropagation();
callbackRef.current();
}
};
el.addEventListener("keydown", handler, true);
return () => el.removeEventListener("keydown", handler, true);
}, [ref, shortcut.key, shortcut.metaOrCtrl, shortcut.alt, shortcut.shift]);
}