diff --git a/README.md b/README.md index 18956d9201..9f6ab6f190 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/docs/useKeyPressEvent.md b/docs/useKeyPressEvent.md index b357ef456b..8ccda96696 100644 --- a/docs/useKeyPressEvent.md +++ b/docs/useKeyPressEvent.md @@ -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); @@ -50,9 +33,11 @@ const Demo = () => { }; ``` + ## Reference ```js -useKeyPressEvent('', onKeydown); -useKeyPressEvent('', onKeyup, onKeydown); +useKeyPressEvent('', keydown); +useKeyPressEvent('', keydown, keyup); +useKeyPressEvent('', keydown, keyup, useKeyPress); ``` diff --git a/src/__stories__/useKeyPressEvent.story.tsx b/src/__stories__/useKeyPressEvent.story.tsx index 045a146428..cf415aad9c 100644 --- a/src/__stories__/useKeyPressEvent.story.tsx +++ b/src/__stories__/useKeyPressEvent.story.tsx @@ -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); diff --git a/src/useKeyPressEvent.ts b/src/useKeyPressEvent.ts index 2e11ab4781..9a87105224 100644 --- a/src/useKeyPressEvent.ts +++ b/src/useKeyPressEvent.ts @@ -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;