Skip to content

Commit

Permalink
feat: 🎸 refactor useKeyPressEvent hook
Browse files Browse the repository at this point in the history
Changes its interface, fixes bug of calling callback on initial mount,
useKeyPress hook is injected as dependency and can be overwirtten to
useKeyboardJs.

BREAKING CHANGE: 🧨 useKeyPressEvent hook modified for dependency injection and providing
event objects to user
  • Loading branch information
streamich committed Mar 28, 2019
1 parent 00fecab commit c0658f6
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 55 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
- [`useGeolocation`](./docs/useGeolocation.md) — tracks geo location state of user's device. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/sensors-usegeolocation--demo)
- [`useHover` and `useHoverDirty`](./docs/useHover.md) — tracks mouse hover state of some element. [![][img-demo]](https://codesandbox.io/s/zpn583rvx)
- [`useIdle`](./docs/useIdle.md) — tracks whether user is being inactive.
- [`useKey`](./docs/useKey.md), [`useKeyPress`](./docs/useKeyPress.md), [`useKeyPressEvent`](./docs/useKeyPressEvent.md), and [`useKeyboardJs`](./docs/useKeyboardJs.md) — track keys. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/sensors-usekeypressevent--demo)
- [`useKey`](./docs/useKey.md), [`useKeyPress`](./docs/useKeyPress.md), [`useKeyboardJs`](./docs/useKeyPressEvent.md), and [`useKeyPressEvent`](./docs/useKeyPressEvent.md) — track keys. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/sensors-usekeypressevent--demo)
- [`useLocation`](./docs/useLocation.md) — tracks page navigation bar location state.
- [`useMedia`](./docs/useMedia.md) — tracks state of a CSS media query. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/sensors-usemedia--demo)
- [`useMediaDevices`](./docs/useMediaDevices.md) — tracks state of connected hardware devices.
Expand Down
33 changes: 9 additions & 24 deletions docs/useKeyPressEvent.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,15 @@
# `useKeyPressEvent`

React UI sensor hook that detects when the user is pressing a specific
key on their keyboard and fires a specified keyup and/or keydown effect. If
you only need to retrieve the state, see [useKeyPress](useKeyPress.md).

Complex bindings like detecting when multiple keys are held down at the same
time or requiring them to be held down in a specified order are also available
via [KeyboardJS key combos](https://github.com/RobertWHurst/KeyboardJS).
Check its documentation for further details on how to make combo strings.

The first argument is the key(s) to watch. If only a second argument
(a function) is passed, it will be used in the keydown event. On the other hand,
if a second and third argument are passed, the second will be used in the keyup
event and the third in the keydown event. Essentially, keydown takes precedence.

Requires `keyboardjs`:

```bash
npm add keyboardjs
# or
yarn add keyboardjs
```
This hook fires `keydown` and `keyup` calllbacks, similar to how [`useKey`](./useKey.md)
hook does, but it only triggers each callback once per press cycle. For example,
if you press and hold a key, it will fire `keydown` callback only once.


## Usage

```jsx
import React, { useState } from React;
import { useKeyPressEvent } from "react-use";
import useKeyPressEvent from 'react-use/lib/useKeyPressEvent';

const Demo = () => {
const [count, setCount] = useState(0);
Expand All @@ -50,9 +33,11 @@ const Demo = () => {
};
```


## Reference

```js
useKeyPressEvent('<key>', onKeydown);
useKeyPressEvent('<key>', onKeyup, onKeydown);
useKeyPressEvent('<key>', keydown);
useKeyPressEvent('<key>', keydown, keyup);
useKeyPressEvent('<key>', keydown, keyup, useKeyPress);
```
12 changes: 9 additions & 3 deletions src/__stories__/useKeyPressEvent.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@ import ShowDocs from "../util/ShowDocs";
const Demo = () => {
const [count, setCount] = React.useState(0);

const increment = () => setCount(count => ++count);
const decrement = () => setCount(count => --count);
const reset = () => setCount(count => 0);
const increment = () => {
console.log('INCREMENT');
setCount(count => ++count);
};
const decrement = () => {
console.log('DECREMENT');
setCount(count => --count);
};
const reset = () => setCount(() => 0);

useKeyPressEvent(']', increment, increment);
useKeyPressEvent('[', decrement, decrement);
Expand Down
39 changes: 12 additions & 27 deletions src/useKeyPressEvent.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,18 @@
import * as React from 'react';
const { useEffect } = React;
import useKeyPress from './useKeyPress';

type KeyPressCallback = ((targetKey: string) => void) | undefined | null;
import {KeyFilter, Handler} from './useKey';
import useKeyPressDefault from './useKeyPress';
import useUpdateEffect from './useUpdateEffect';

const useKeyPressEvent = (
targetKey: string,
onKeyup: KeyPressCallback = undefined,
onKeydown: KeyPressCallback = undefined
key: string | KeyFilter,
keydown?: Handler | null | undefined,
keyup?: Handler | null | undefined,
useKeyPress = useKeyPressDefault,
) => {
const useKeyboardJS: boolean = targetKey.length > 1;
const pressedKeys: boolean = useKeyPress(targetKey);

if (onKeydown === undefined) {
onKeydown = onKeyup;
onKeyup = null;
}

useEffect(
() => {
if (!pressedKeys) {
if (onKeyup) onKeyup(targetKey);
return;
}

if (onKeydown) onKeydown(targetKey);
},
[pressedKeys]
);
const [pressed, event] = useKeyPress(key);
useUpdateEffect(() => {
if (!pressed && keyup) keyup(event!);
else if (keydown) keydown(event!);
}, [pressed]);
};

export default useKeyPressEvent;

0 comments on commit c0658f6

Please sign in to comment.