Skip to content

Instantly share code, notes, and snippets.

@ryochin
Last active September 4, 2024 04:28
Show Gist options
  • Save ryochin/0c8579554cc0c7ca51ffb779b34c5ef5 to your computer and use it in GitHub Desktop.
Save ryochin/0c8579554cc0c7ca51ffb779b34c5ef5 to your computer and use it in GitHub Desktop.
TS: enhanced UseKeyPress React Hook
// https://novajs.co/react-hook-key-press
import { useState, useEffect } from 'react'
type KeyConfig = {
key: string
ctrl?: boolean
alt?: boolean
shift?: boolean
meta?: boolean
}
export const useKeyPress = (config: KeyConfig): [boolean, KeyboardEvent | undefined] => {
const [keyPressed, setKeyPressed] = useState(false)
const [keyboardEvent, setKeyboardEvent] = useState<KeyboardEvent>()
const { key: targetKey, ctrl, alt, shift, meta } = config
const handleKeyDown = (e: KeyboardEvent) => {
const { key, ctrlKey, altKey, shiftKey, metaKey } = e
if (check(key, targetKey, ctrl, alt, shift, meta, ctrlKey, altKey, shiftKey, metaKey)) {
setKeyPressed(true)
setKeyboardEvent(e)
}
}
const handleKeyUp = (e: KeyboardEvent) => {
const { key, ctrlKey, altKey, shiftKey, metaKey } = e
if (check(key, targetKey, ctrl, alt, shift, meta, ctrlKey, altKey, shiftKey, metaKey)) {
setKeyPressed(false)
setKeyboardEvent(undefined)
}
}
useEffect(() => {
window.addEventListener('keydown', handleKeyDown)
window.addEventListener('keyup', handleKeyUp)
return () => {
window.removeEventListener('keydown', handleKeyDown)
window.removeEventListener('keyup', handleKeyUp)
}
}, [])
return [keyPressed, keyboardEvent]
}
const check = (key: string,
targetKey: string,
ctrl: boolean | undefined,
alt: boolean | undefined,
shift: boolean | undefined,
meta: boolean | undefined,
ctrlKey: boolean,
altKey: boolean,
shiftKey: boolean,
metaKey: boolean): boolean | undefined => {
return (!ctrl && !alt && !shift && !meta && key === targetKey) ||
(ctrl && key === targetKey && ctrlKey === ctrl) ||
(alt && key === targetKey && altKey === alt) ||
(shift && key === targetKey && shiftKey === shift) ||
(meta && key === targetKey && metaKey === meta)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment