Skip to content

Instantly share code, notes, and snippets.

@mmazzarolo
Created December 30, 2018 22:09
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mmazzarolo/d157c83e697fd46510bec4c3a5003f2c to your computer and use it in GitHub Desktop.
Save mmazzarolo/d157c83e697fd46510bec4c3a5003f2c to your computer and use it in GitHub Desktop.
A React hook for handling keypresses
import { useState, useEffect, useRef } from "react";
interface Parameters {
key: string;
ctrlKey?: boolean;
shiftKey?: boolean;
metaKey?: boolean;
onKeyDown?: (e: KeyboardEvent) => void;
onKeyUp?: (e: KeyboardEvent) => void;
}
const checkKeyValidity = (e: KeyboardEvent, params: Parameters) => {
return (
e.key === params.key &&
e.ctrlKey === !!params.ctrlKey &&
e.metaKey === !!params.metaKey &&
e.shiftKey === !!params.shiftKey
);
};
export function useKeyboardPress(params: Parameters) {
const [isKeyDown, setIsKeyDown] = useState(false);
const shouldDisableKeyDownUpdate = useRef(false);
const handleKeyDown = (e: KeyboardEvent) => {
const isKeyValid = checkKeyValidity(e, params);
if (isKeyValid) {
if (params.onKeyDown) {
params.onKeyDown(e);
}
if (!shouldDisableKeyDownUpdate.current) {
shouldDisableKeyDownUpdate.current = true;
setIsKeyDown(true);
}
}
};
const handleKeyUp = (e: KeyboardEvent) => {
shouldDisableKeyDownUpdate.current = false;
if (params.onKeyUp) {
params.onKeyUp(e);
}
setIsKeyDown(false);
};
useEffect(() => {
window.document.addEventListener("keydown", handleKeyDown);
window.document.addEventListener("keyup", handleKeyUp);
return () => {
window.document.removeEventListener("keydown", handleKeyDown);
window.document.removeEventListener("keyup", handleKeyUp);
};
}, []);
return isKeyDown;
}
@mmazzarolo
Copy link
Author

Usage examples

Check if the tab key is down

const isTabDown = useKeyboardPress({
  key: "Tab"
})

Invoke a callback when the A key is pressed

useKeyboardPress({
  key: "a",
  onKeyDown: () => {
    console.log(`Key "a" has been pressed`);
  }
})

Combination of the two examples above

const isBDown = useKeyboardPress({
  key: "b",
  onKeyDown: () => {
    console.log(`Key "b" has been pressed`);
  }
})

Override CTRL + F search (on Windows)

useKeyboardPress({
  key: "f",
  ctrlKey: true,
  onKeyDown: (e) => {
    e.preventDefault();
    console.log(`CTRL + F has been pressed`);
    handleSearchPress();
  }
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment