From c3d49e230b99a6b9194ac408d7a3678d066a6701 Mon Sep 17 00:00:00 2001 From: Parker McMullin Date: Sat, 9 Mar 2019 19:25:59 -0700 Subject: [PATCH 1/2] Added useKeyPressEvent custom hook with associated doc. This focuses on utilizing the onKeyup and/or onKeydown events unlike useKeyPress which involves state. useKeyPressEvent uses useKeyPress to achieve this functionality. --- docs/useKeyPressEvent.md | 57 ++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- src/useKeyPressEvent.ts | 35 ++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 docs/useKeyPressEvent.md create mode 100644 src/useKeyPressEvent.ts diff --git a/docs/useKeyPressEvent.md b/docs/useKeyPressEvent.md new file mode 100644 index 00000000..29257394 --- /dev/null +++ b/docs/useKeyPressEvent.md @@ -0,0 +1,57 @@ +# `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](#). + +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. + +## Usage + +```jsx +import React, { useState } from React; +import { useKeyPressEvent } from "react-use"; + +const Demo = () => { + const [count, setCount] = useState(0); + + const onKeyup = keys => { + console.log(`onKeyup: ${keys}`); + }; + + const onKeydown = keys => { + console.log(`onKeydown: ${keys}`); + setCount(count => ++count); + }; + + useKeyPressEvent('h', onKeyup, onKeydown); + + useKeyPressEvent('l', () => { + console.log(`onKeydown for 'l'`); + setCount(count => ++count); + }); + + return ( +
+

Try pressing h or l to see the count increment

+

Count: {countOfPressed}

+
+ ); +}; +``` + +## Reference + +```js +useKeyPressEvent('', onKeydown); + +useKeyPressEvent('', onKeyup, onKeydown); +``` diff --git a/package.json b/package.json index cc4a7374..dd587703 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "semantic-release": "15.13.3", "ts-loader": "3.5.0", "ts-node": "7.0.1", - "typescript": "3.3.3333" + "typescript": "^3.3.3333" }, "peerDependencies": { "react": "^16.8.0", diff --git a/src/useKeyPressEvent.ts b/src/useKeyPressEvent.ts new file mode 100644 index 00000000..44d01692 --- /dev/null +++ b/src/useKeyPressEvent.ts @@ -0,0 +1,35 @@ +import * as React from 'react'; +const { useEffect } = React; +import useKeyPress from './useKeyPress'; + +type KeyPressCallback = ((targetKey: string) => void) | undefined | null; + +const useKeyPressEvent = ( + targetKey: string, + onKeyup: KeyPressCallback = undefined, + onKeydown: KeyPressCallback = undefined +) => { + const useKeyboardJS: boolean = targetKey.length > 1; + const pressedKeys: boolean = useKeyPress(targetKey, { + useKeyboardJS, + }); + + if (onKeydown === undefined) { + onKeydown = onKeyup; + onKeyup = null; + } + + useEffect( + () => { + if (!pressedKeys) { + if (onKeyup) onKeyup(targetKey); + return; + } + + if (onKeydown) onKeydown(targetKey); + }, + [pressedKeys] + ); +}; + +export default useKeyPressEvent; From 7cf90107e127a543ff312dbeecdbb41cc71a2e6d Mon Sep 17 00:00:00 2001 From: streamich Date: Tue, 19 Mar 2019 22:47:12 +0100 Subject: [PATCH 2/2] =?UTF-8?q?chore:=20=F0=9F=A4=96=20various=20improveme?= =?UTF-8?q?nts=20for=20useKeyPrssEvent()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add link to README, expose in index.ts, improve docs/demo, add Storybook story --- README.md | 1 + docs/useKeyPressEvent.md | 27 ++++++++----------- src/__stories__/useKeyPressEvent.story.tsx | 30 ++++++++++++++++++++++ src/index.ts | 2 ++ yarn.lock | 11 +------- 5 files changed, 44 insertions(+), 27 deletions(-) create mode 100644 src/__stories__/useKeyPressEvent.story.tsx diff --git a/README.md b/README.md index cf632c61..d4821508 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ - [`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. - [`useKeyPress`](./docs/useKeyPress.md) — tracks whether a keyboard key—or set of keys—was pressed. + - [`useKeyPressEvent`](./docs/useKeyPressEvent.md) — call `onKeyDown` and `onKeyUp` callbacks, whe key pressed. - [`useLocation`](./docs/useLocation.md) — tracks page navigation bar location state. - [`useMedia`](./docs/useMedia.md) — tracks state of a CSS media query. - [`useMediaDevices`](./docs/useMediaDevices.md) — tracks state of connected hardware devices. diff --git a/docs/useKeyPressEvent.md b/docs/useKeyPressEvent.md index 29257394..930f3174 100644 --- a/docs/useKeyPressEvent.md +++ b/docs/useKeyPressEvent.md @@ -23,26 +23,20 @@ import { useKeyPressEvent } from "react-use"; const Demo = () => { const [count, setCount] = useState(0); - const onKeyup = keys => { - console.log(`onKeyup: ${keys}`); - }; + const increment = () => setCount(count => ++count); + const decrement = () => setCount(count => --count); + const reset = () => setCount(count => 0); - const onKeydown = keys => { - console.log(`onKeydown: ${keys}`); - setCount(count => ++count); - }; - - useKeyPressEvent('h', onKeyup, onKeydown); - - useKeyPressEvent('l', () => { - console.log(`onKeydown for 'l'`); - setCount(count => ++count); - }); + useKeyPressEvent(']', increment, increment); + useKeyPressEvent('[', decrement, decrement); + useKeyPressEvent('r', reset); return (
-

Try pressing h or l to see the count increment

-

Count: {countOfPressed}

+

+ Try pressing [, ], and r to + see the count incremented and decremented.

+

Count: {count}

); }; @@ -52,6 +46,5 @@ const Demo = () => { ```js useKeyPressEvent('', onKeydown); - useKeyPressEvent('', onKeyup, onKeydown); ``` diff --git a/src/__stories__/useKeyPressEvent.story.tsx b/src/__stories__/useKeyPressEvent.story.tsx new file mode 100644 index 00000000..045a1464 --- /dev/null +++ b/src/__stories__/useKeyPressEvent.story.tsx @@ -0,0 +1,30 @@ +import { storiesOf } from "@storybook/react"; +import * as React from "react"; +import { useKeyPressEvent } from ".."; +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); + + useKeyPressEvent(']', increment, increment); + useKeyPressEvent('[', decrement, decrement); + useKeyPressEvent('r', reset); + + return ( +
+