hcc-meat-coder / ui /src /lib /useKeybinds.ts
chraos's picture
Claude Opus 4.7 (1M context)
Milestone 0.4.0: narrative + polish (blog, demo script, keybinds, calibrator fit)
6fc49c1
Raw History Blame Contribute Delete
1.35 kB
import { useEffect } from "react";
interface Opts {
onCode: () => void;
onNext: () => void;
onPrev: () => void;
enabled?: boolean;
}
/**
* Global keybinds:
* Cmd/Ctrl + Enter — Code the current note
* j / ArrowDown — Select next HCC candidate
* k / ArrowUp — Select previous HCC candidate
*
* Ignored while the user is typing into an editable control so it doesn't
* fight with the textarea.
*/
export function useKeybinds({ onCode, onNext, onPrev, enabled = true }: Opts) {
useEffect(() => {
if (!enabled) return;
function handler(e: KeyboardEvent) {
const target = e.target as HTMLElement | null;
const inEditable =
!!target &&
(target.tagName === "INPUT" ||
target.tagName === "TEXTAREA" ||
target.isContentEditable);
if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
e.preventDefault();
onCode();
return;
}
if (inEditable) return;
if (e.key === "j" || e.key === "ArrowDown") {
e.preventDefault();
onNext();
} else if (e.key === "k" || e.key === "ArrowUp") {
e.preventDefault();
onPrev();
}
}
window.addEventListener("keydown", handler);
return () => window.removeEventListener("keydown", handler);
}, [onCode, onNext, onPrev, enabled]);
}