React hook for using keyboard shortcuts in components.
Installations
npm install react-hotkeys-hook
Developer
Developer Guide
Module System
CommonJS
Min. Node Version
Typescript Support
Yes
Node Version
20.17.0
NPM Version
10.8.2
Statistics
2,737 Stars
2,122 Commits
117 Forks
5 Watching
48 Branches
43 Contributors
Updated on 27 Nov 2024
Bundle Size
7.96 kB
Minified
2.71 kB
Minified + Gzipped
Languages
TypeScript (98.97%)
JavaScript (1.03%)
Total Downloads
Cumulative downloads
Total Downloads
60,459,760
Last day
2.2%
158,577
Compared to previous day
Last week
8.3%
818,897
Compared to previous week
Last month
10.7%
3,268,938
Compared to previous month
Last year
91%
29,475,664
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Dev Dependencies
26
useHotkeys(keys, callback)
npm i react-hotkeys-hook
A React hook for using keyboard shortcuts in components in a declarative way.
Quick Start
The easiest way to use the hook.
1import { useHotkeys } from 'react-hotkeys-hook' 2 3export const ExampleComponent = () => { 4 const [count, setCount] = useState(0) 5 useHotkeys('ctrl+k', () => setCount(count + 1), [count]) 6 7 return ( 8 <p> 9 Pressed {count} times. 10 </p> 11 ) 12}
Scopes
Scopes allow you to group hotkeys together. You can use scopes to prevent hotkeys from colliding with each other.
1const App = () => { 2 return ( 3 <HotkeysProvider initiallyActiveScopes={['settings']}> 4 <ExampleComponent /> 5 </HotkeysProvider> 6 ) 7} 8 9export const ExampleComponent = () => { 10 const [count, setCount] = useState(0) 11 useHotkeys('ctrl+k', () => setCount(prevCount => prevCount + 1), { scopes: ['settings'] }) 12 13 return ( 14 <p> 15 Pressed {count} times. 16 </p> 17 ) 18}
Changing a scope's active state
You can change the active state of a scope using the disableScope
, enableScope
and toggleScope
functions
returned by the useHotkeysContext()
hook. Note that you have to have your app wrapped in a <HotkeysProvider>
component.
1const App = () => { 2 return ( 3 <HotkeysProvider initiallyActiveScopes={['settings']}> 4 <ExampleComponent /> 5 </HotkeysProvider> 6 ) 7} 8 9export const ExampleComponent = () => { 10 const { toggleScope } = useHotkeysContext() 11 12 return ( 13 <button onClick={() => toggleScope('settings')}> 14 Change scope active state 15 </button> 16 ) 17}
Focus trap
This will only trigger the hotkey if the component is focused.
1export const ExampleComponent = () => { 2 const [count, setCount] = useState(0) 3 const ref = useHotkeys<HTMLParagraphElement>('ctrl+k', () => setCount(prevCount => prevCount + 1)) 4 5 return ( 6 <p tabIndex={-1} ref={ref}> 7 Pressed {count} times. 8 </p> 9 ) 10}
Documentation & Live Examples
API
useHotkeys(keys, callback)
1useHotkeys(keys: string | string[], callback: (event: KeyboardEvent, handler: HotkeysEvent) => void, options: Options = {}, deps: DependencyList = [])
Parameter | Type | Required? | Default value | Description |
---|---|---|---|---|
keys | string or string[] | required | - | set the hotkeys you want the hook to listen to. You can use single or multiple keys, modifier combinations, etc. This will either be a string or an array of strings. To separate multiple keys, use a comma. This split key value can be overridden with the splitKey option. |
callback | (event: KeyboardEvent, handler: HotkeysEvent) => void | required | - | This is the callback function that will be called when the hotkey is pressed. The callback will receive the browsers native KeyboardEvent and the libraries HotkeysEvent . |
options | Options | optional | {} | Object to modify the behavior of the hook. Default options are given below. |
dependencies | DependencyList | optional | [] | The given callback will always be memoised inside the hook. So if you reference any outside variables, you need to set them here for the callback to get updated (Much like useCallback works in React). |
Options
All options are optional and have a default value which you can override to change the behavior of the hook.
Option | Type | Default value | Description |
---|---|---|---|
enabled | boolean or (keyboardEvent: KeyboardEvent, hotkeysEvent: HotkeysEvent) => boolean | true | This option determines whether the hotkey is active or not. It can take a boolean (for example a flag from a state outside) or a function which gets executed once the hotkey is pressed. If the function returns false the hotkey won't get executed and all browser events are prevented. |
enableOnFormTags | boolean or FormTags[] | false | By default hotkeys are not registered if a focus focuses on an input field. This will prevent accidental triggering of hotkeys when the user is typing. If you want to enable hotkeys, use this option. Setting it to true will enable on all form tags, otherwise you can give an array of form tags to enable the hotkey on (possible options are: ['input', 'textarea', 'select'] ) |
enableOnContentEditable | boolean | false | Set this option to enable hotkeys on tags that have set the contentEditable prop to true |
combinationKey | string | + | Character to indicate keystrokes like shift+c . You might want to change this if you want to listen to the + character like ctrl-+ . |
splitKey | string | , | Character to separate different keystrokes like ctrl+a, ctrl+b . |
scopes | string or string[] | * | With scopes you can group hotkeys together. The default scope is the wildcard * which matches all hotkeys. Use the <HotkeysProvider> component to change active scopes. |
keyup | boolean | false | Determines whether to listen to the browsers keyup event for triggering the callback. |
keydown | boolean | true | Determines whether to listen to the browsers keydown event for triggering the callback. If you set both keyup and keydown to true, the callback will trigger on both events. |
preventDefault | boolean or (keyboardEvent: KeyboardEvent, hotkeysEvent: HotkeysEvent) => boolean | false | Set this to a true if you want the hook to prevent the browsers default behavior on certain keystrokes like meta+s to save a page. NOTE: Certain keystrokes are not preventable, like meta+w to close a tab in chrome. |
description | string | undefined | Use this option to describe what the hotkey does. this is helpful if you want to display a list of active hotkeys to the user. |
Overloads
The hooks call signature is very flexible. For example if you don't need to set any special options you can use the dependency array as your third parameter:
useHotkeys('ctrl+k', () => console.log(counter + 1), [counter])
isHotkeyPressed(keys: string | string[], splitKey?: string = ',')
This function allows us to check if the user is currently pressing down a key.
1import { isHotkeyPressed } from 'react-hotkeys-hook' 2 3isHotkeyPressed('esc') // Returns true if Escape key is pressed down.
You can also check for multiple keys at the same time:
1isHotkeyPressed(['esc', 'ctrl+s']) // Returns true if Escape or Ctrl+S are pressed down.
Support
- Ask your question in the Github Discussions
- Ask your question on StackOverflow
Found an issue or have a feature request?
Open up an issue or pull request and participate.
Local Development
Checkout this repo, run yarn
or npm i
and then run the test
script to test the behavior of the hook.
Contributing
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
License
Distributed under the MIT License. See LICENSE
for more information.
Contact
Johannes Klauss - @JohannesKlauss - klauss.johannes@gmail.com
Project Link: https://github.com/JohannesKlauss/react-hotkeys-hook
Contributors
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
17 commit(s) and 7 issue activity found in the last 90 days -- score normalized to 10
Reason
no binaries found in the repo
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Info: FSF or OSI recognized license: MIT License: LICENSE:0
Reason
Found 4/15 approved changesets -- score normalized to 2
Reason
detected GitHub workflow tokens with excessive permissions
Details
- Warn: no topLevel permission defined: .github/workflows/main.yml:1
- Info: no jobLevel write permissions found
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/JohannesKlauss/react-hotkeys-hook/main.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/JohannesKlauss/react-hotkeys-hook/main.yml/main?enable=pin
- Warn: npmCommand not pinned by hash: .github/workflows/main.yml:28
- Info: 0 out of 2 GitHub-owned GitHubAction dependencies pinned
- Info: 0 out of 1 npmCommand dependencies pinned
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 23 are checked with a SAST tool
Reason
19 existing vulnerabilities detected
Details
- Warn: Project is vulnerable to: GHSA-wf5p-g6vw-rhxx
- Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x
- Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275
- Warn: Project is vulnerable to: GHSA-jrvm-mcxc-mf6m
- Warn: Project is vulnerable to: GHSA-pfrx-2q88-qq97
- Warn: Project is vulnerable to: GHSA-3rfm-jhwj-7488
- Warn: Project is vulnerable to: GHSA-hhq3-ff78-jv3g
- Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv
- Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3
- Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j
- Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw
- Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc
- Warn: Project is vulnerable to: GHSA-w5p7-h5w8-2hfq
- Warn: Project is vulnerable to: GHSA-4vvj-4cpr-p986
- Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg
- Warn: Project is vulnerable to: GHSA-5fw9-fq32-wv5p
- Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6
- Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm
- Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3
Score
4
/10
Last Scanned on 2024-11-25
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn MoreOther packages similar to react-hotkeys-hook
@udecode/react-hotkeys
Fork of react-hotkeys-hook
react-hot-keys
React component to listen to keydown and keyup keyboard events, defining and dispatching keyboard shortcuts.
react-hotkeys
A declarative library for handling hotkeys and focus within a React application
@reecelucas/react-use-hotkeys
React hook to create keyboard shortcuts