Socket
Socket
Sign inDemoInstall

@reecelucas/react-use-hotkeys

Package Overview
Dependencies
3
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.3.5 to 2.0.0

esm/helpers/ignoreKeydownEvent.d.ts

9

esm/index.d.ts

@@ -0,3 +1,10 @@

import type { ElementsToIgnore } from "./helpers/ignoreKeydownEvent";
import "./vendor/shim-keyboard-event-key";
declare const useHotkeys: (hotkeys: string | string[], callback: (event: KeyboardEvent) => void, eventListenerOptions?: boolean | AddEventListenerOptions) => void;
interface Options {
enabled?: boolean;
enableOnContentEditable?: boolean;
ignoredElementWhitelist?: ElementsToIgnore[];
eventListenerOptions?: AddEventListenerOptions;
}
declare const useHotkeys: (hotkeys: string | string[], callback: (event: KeyboardEvent) => void, options?: Options) => void;
export default useHotkeys;

23

esm/index.js

@@ -10,6 +10,7 @@ import { useEffect, useMemo } from "react";

import takeUntilLast from "./helpers/takeUntilLast";
import ignoreKeydownEvent from "./helpers/ignoreKeydownEvent";
import "./vendor/shim-keyboard-event-key";
var KEY_SEQUENCE_TIMEOUT = 1000;
var ESCAPE_HATCH_KEY = "*";
var useHotkeys = function (hotkeys, callback, eventListenerOptions) {
var useHotkeys = function (hotkeys, callback, options) {
var hotkeysArray = useMemo(function () {

@@ -23,2 +24,3 @@ return Array.isArray(hotkeys)

var sequenceTimers = {};
var _a = options || {}, enabled = _a.enabled, enableOnContentEditable = _a.enableOnContentEditable, ignoredElementWhitelist = _a.ignoredElementWhitelist, eventListenerOptions = _a.eventListenerOptions;
var clearSequenceTimer = function (index) {

@@ -54,7 +56,3 @@ clearTimeout(sequenceTimers[index]);

var onKeydown = function (event) {
/**
* Chrome autocomplete triggers `keydown` event but event.key will be undefined.
* See https://bugs.chromium.org/p/chromium/issues/detail?id=581537.
*/
if (!event.key && !modifierKeyPressed(event)) {
if (ignoreKeydownEvent(event, enableOnContentEditable, ignoredElementWhitelist)) {
return;

@@ -87,8 +85,17 @@ }

};
window.addEventListener("keydown", onKeydown, eventListenerOptions);
if (enabled !== false) {
window.addEventListener("keydown", onKeydown, eventListenerOptions);
}
return function () {
window.removeEventListener("keydown", onKeydown, eventListenerOptions);
};
}, [hotkeysArray, callback, eventListenerOptions]);
}, [
hotkeysArray,
callback,
options === null || options === void 0 ? void 0 : options.enabled,
options === null || options === void 0 ? void 0 : options.enableOnContentEditable,
options === null || options === void 0 ? void 0 : options.ignoredElementWhitelist,
options === null || options === void 0 ? void 0 : options.eventListenerOptions,
]);
};
export default useHotkeys;

@@ -0,3 +1,10 @@

import type { ElementsToIgnore } from "./helpers/ignoreKeydownEvent";
import "./vendor/shim-keyboard-event-key";
declare const useHotkeys: (hotkeys: string | string[], callback: (event: KeyboardEvent) => void, eventListenerOptions?: boolean | AddEventListenerOptions) => void;
interface Options {
enabled?: boolean;
enableOnContentEditable?: boolean;
ignoredElementWhitelist?: ElementsToIgnore[];
eventListenerOptions?: AddEventListenerOptions;
}
declare const useHotkeys: (hotkeys: string | string[], callback: (event: KeyboardEvent) => void, options?: Options) => void;
export default useHotkeys;

@@ -12,6 +12,7 @@ "use strict";

var takeUntilLast_1 = require("./helpers/takeUntilLast");
var ignoreKeydownEvent_1 = require("./helpers/ignoreKeydownEvent");
require("./vendor/shim-keyboard-event-key");
var KEY_SEQUENCE_TIMEOUT = 1000;
var ESCAPE_HATCH_KEY = "*";
var useHotkeys = function (hotkeys, callback, eventListenerOptions) {
var useHotkeys = function (hotkeys, callback, options) {
var hotkeysArray = (0, react_1.useMemo)(function () {

@@ -25,2 +26,3 @@ return Array.isArray(hotkeys)

var sequenceTimers = {};
var _a = options || {}, enabled = _a.enabled, enableOnContentEditable = _a.enableOnContentEditable, ignoredElementWhitelist = _a.ignoredElementWhitelist, eventListenerOptions = _a.eventListenerOptions;
var clearSequenceTimer = function (index) {

@@ -56,7 +58,3 @@ clearTimeout(sequenceTimers[index]);

var onKeydown = function (event) {
/**
* Chrome autocomplete triggers `keydown` event but event.key will be undefined.
* See https://bugs.chromium.org/p/chromium/issues/detail?id=581537.
*/
if (!event.key && !(0, modifierKeyPressed_1.default)(event)) {
if ((0, ignoreKeydownEvent_1.default)(event, enableOnContentEditable, ignoredElementWhitelist)) {
return;

@@ -89,8 +87,17 @@ }

};
window.addEventListener("keydown", onKeydown, eventListenerOptions);
if (enabled !== false) {
window.addEventListener("keydown", onKeydown, eventListenerOptions);
}
return function () {
window.removeEventListener("keydown", onKeydown, eventListenerOptions);
};
}, [hotkeysArray, callback, eventListenerOptions]);
}, [
hotkeysArray,
callback,
options === null || options === void 0 ? void 0 : options.enabled,
options === null || options === void 0 ? void 0 : options.enableOnContentEditable,
options === null || options === void 0 ? void 0 : options.ignoredElementWhitelist,
options === null || options === void 0 ? void 0 : options.eventListenerOptions,
]);
};
exports.default = useHotkeys;
{
"name": "@reecelucas/react-use-hotkeys",
"version": "1.3.5",
"version": "2.0.0",
"description": "React hook to create keyboard shortcuts",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

@@ -19,2 +19,6 @@ # react-use-hotkeys

```ts
import useHotkeys from "@reecelucas/react-use-hotkeys";
```
All hotkey combinations must use valid `KeyBoardEvent` `"key"` values. A full list can be found on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values) and Wes Bos has created a great [interactive lookup](https://keycode.info/).

@@ -24,18 +28,18 @@

// Single keys
useHotkeys('Escape', () => {
console.log('Some action');
useHotkeys("Escape", () => {
console.log("Some action");
});
useHotkeys('F7', () => {
console.log('Some action');
useHotkeys("F7", () => {
console.log("Some action");
});
// Modifier combinations
useHotkeys('Meta+Shift+z', () => {
console.log('Some action');
useHotkeys("Meta+Shift+z", () => {
console.log("Some action");
});
// Key sequences
useHotkeys('w s d', () => {
console.log('Some action');
useHotkeys("w s d", () => {
console.log("Some action");
});

@@ -45,13 +49,13 @@

// space key in sequence (`w ' ' d` also works)
console.log('Some action');
console.log("Some action");
});
// Multiple key combinations mapped to the same callback
useHotkeys(['Control+z', 'Meta+z'], () => {
console.log('Some action');
useHotkeys(["Control+z", "Meta+z"], () => {
console.log("Some action");
});
useHotkeys(['a', 'Meta+z', 'w s d'], () => {
console.log('Some action');
})
useHotkeys(["a", "Meta+z", "w s d"], () => {
console.log("Some action");
});
```

@@ -63,3 +67,3 @@

// Modifier keys in sequences
useHotkeys('Control i d', () => {
useHotkeys("Control i d", () => {
console.log("I won't run!");

@@ -69,3 +73,3 @@ });

// Modifier combinations in sequences
useHotkeys('Control+z i d', () => {
useHotkeys("Control+z i d", () => {
console.log("I won't run!");

@@ -75,24 +79,82 @@ });

You can pass `AddEventListenerOptions` if you need to listen for `keydown` events in the capturing phase:
If you find a use case where the API is too restrictive you can use the escape hatch to perform whatever custom logic you need:
```jsx
useHotkeys('Escape', () => {
console.log('Some action');
}, true);
useHotkeys("*", (event) => {
console.log("I will run on every keydown event");
useHotkeys('Escape', () => {
console.log('Some action');
}, { capture: true });
if (customKeyLogic(event)) {
console.log("some action");
}
});
```
If you find a use case where the API is too restrictive you can use the escape hatch to perform whatever custom logic you need:
## Options
### `enabled`
You can disable the hook by passing `enabled: false`. When disabled the hook will stop listening for `keydown` events:
```jsx
useHotkeys('*', event => {
console.log("I will run on every keydown");
useHotkeys(
"Escape",
() => {
console.log("I won't run!");
},
{ enabled: false }
);
```
if (customKeyLogic(event)) {
console.log("some action");
### `enableOnContentEditable`
By default, the hook will ignore `keydown` events originating from elements with the `contenteditable` attribute, since this behaviour is normally what you want. If you want to override this behaviour you can pass `enableOnContentEditable: true`:
```jsx
useHotkeys(
"Escape",
() => {
console.log("Some action");
},
{ enableOnContentEditable: true }
);
```
### `ignoredElementWhitelist`
By default, the hook will ignore `keydown` events originating from `INPUT` and `TEXTAREA` elements, since this behaviour is normally what you want. If you want to override this behaviour you can use `ignoredElementWhitelist`:
```jsx
useHotkeys(
"Escape",
() => {
console.log("I will now run on input elements");
},
{ ignoredElementWhitelist: ["INPUT"] }
);
useHotkeys(
"Escape",
() => {
console.log("I will now run on input and textarea elements");
},
{ ignoredElementWhitelist: ["INPUT", "TEXTAREA"] }
);
```
### `eventListenerOptions`
You can pass [`AddEventListenerOptions`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#parameters) if you need to listen for `keydown` events in the capturing phase:
```jsx
useHotkeys(
"Escape",
() => {
console.log("I will run in the capturing phase");
},
{
eventListenerOptions: {
capture: true,
},
}
});
);
```

@@ -106,3 +168,8 @@

callback: (event: KeyboardEvent) => void,
eventListenerOptions?: boolean | AddEventListenerOptions
options?: {
enabled?: boolean;
enableOnContentEditable?: boolean;
ignoredElementWhitelist?: ("INPUT" | "TEXTAREA")[];
eventListenerOptions?: AddEventListenerOptions;
}
) => void;

@@ -109,0 +176,0 @@ ```

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc