From 01df885b9d91c85af3495ff6f81175db84c70bbf Mon Sep 17 00:00:00 2001 From: Matheus Albuquerque Date: Wed, 26 Dec 2018 02:49:06 -0300 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20useKeyPress=20hook?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/useKeyPress.md | 38 +++++++++++++++++++++++++++ src/__stories__/useKeyPress.story.tsx | 30 +++++++++++++++++++++ src/index.ts | 2 ++ src/useKeyPress.ts | 32 ++++++++++++++++++++++ yarn.lock | 4 +-- 5 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 docs/useKeyPress.md create mode 100644 src/__stories__/useKeyPress.story.tsx create mode 100644 src/useKeyPress.ts diff --git a/docs/useKeyPress.md b/docs/useKeyPress.md new file mode 100644 index 0000000000..ee4808faa5 --- /dev/null +++ b/docs/useKeyPress.md @@ -0,0 +1,38 @@ +# `useKeyPress` + +React UI sensor hook that detects when the user is pressing a specific +key on their keyboard. + +## Usage + +```jsx +import { useKeyPress } from "react-use"; + +const Demo = () => { + const hasPressedQ = useKeyPress("q"); + const hasPressedW = useKeyPress("w"); + const hasPressedE = useKeyPress("e"); + const hasPressedR = useKeyPress("r"); + const hasPressedT = useKeyPress("t"); + const hasPressedY = useKeyPress("y"); + return ( +
+ Try pressing one of these: Q W E R T Y +
+ {hasPressedQ && "Q"} + {hasPressedW && "W"} + {hasPressedE && "E"} + {hasPressedR && "R"} + {hasPressedT && "T"} + {hasPressedY && "Y"} +
+
+ ); +}; +``` + +## Reference + +```js +const hasPressed = useKeyPress('key'); +``` diff --git a/src/__stories__/useKeyPress.story.tsx b/src/__stories__/useKeyPress.story.tsx new file mode 100644 index 0000000000..d4695dc1e3 --- /dev/null +++ b/src/__stories__/useKeyPress.story.tsx @@ -0,0 +1,30 @@ +import { storiesOf } from "@storybook/react"; +import * as React from "react"; +import { useKeyPress } from ".."; +import ShowDocs from "../util/ShowDocs"; + +const Demo = () => { + const hasPressedQ = useKeyPress("q"); + const hasPressedW = useKeyPress("w"); + const hasPressedE = useKeyPress("e"); + const hasPressedR = useKeyPress("r"); + const hasPressedT = useKeyPress("t"); + const hasPressedY = useKeyPress("y"); + return ( +
+ Try pressing one of these: Q W E R T Y +
+ {hasPressedQ && "Q"} + {hasPressedW && "W"} + {hasPressedE && "E"} + {hasPressedR && "R"} + {hasPressedT && "T"} + {hasPressedY && "Y"} +
+
+ ); +}; + +storiesOf("Sensors/useKeyPress", module) + .add("Docs", () => ) + .add("Demo", () => ); diff --git a/src/index.ts b/src/index.ts index 85884f2d6e..1509586e0e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,6 +14,7 @@ import useGetSetState from './useGetSetState'; import useHover from './useHover'; import useHoverDirty from './useHoverDirty'; import useIdle from './useIdle'; +import useKeyPress from './useKeyPress'; import useLifecycles from './useLifecycles'; import useList from './useList'; import useLocalStorage from './useLocalStorage'; @@ -63,6 +64,7 @@ export { useHover, useHoverDirty, useIdle, + useKeyPress, useLifecycles, useList, useLocalStorage, diff --git a/src/useKeyPress.ts b/src/useKeyPress.ts new file mode 100644 index 0000000000..317cb0186f --- /dev/null +++ b/src/useKeyPress.ts @@ -0,0 +1,32 @@ +import * as React from 'react'; + +const {useState, useEffect} = React; + +// kudos: https://usehooks.com +const useKeyPress = (targetKey: string) => { + const [state, setState] = useState(false); + + const downHandler = ({key}: KeyboardEvent) => { + if (key === targetKey) { + setState(true); + } + } + const upHandler = ({key}: KeyboardEvent) => { + if (key === targetKey) { + setState(false); + } + }; + + useEffect(() => { + window.addEventListener('keydown', downHandler); + window.addEventListener('keyup', upHandler); + return () => { + window.removeEventListener('keydown', downHandler); + window.removeEventListener('keyup', upHandler); + }; + }, []); + + return state; +} + +export default useKeyPress; diff --git a/yarn.lock b/yarn.lock index 0096ce12e6..b28f9ae0ad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7826,7 +7826,7 @@ react-docgen@^3.0.0-beta11: node-dir "^0.1.10" recast "^0.15.0" -react-dom@next: +react-dom@16.7.0-alpha.2: version "16.7.0-alpha.2" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.7.0-alpha.2.tgz#16632880ed43676315991d8b412cce6975a30282" integrity sha512-o0mMw8jBlwHjGZEy/vvKd/6giAX0+skREMOTs3/QHmgi+yAhUClp4My4Z9lsKy3SXV+03uPdm1l/QM7NTcGuMw== @@ -7961,7 +7961,7 @@ react-wait@^0.3.0: resolved "https://registry.yarnpkg.com/react-wait/-/react-wait-0.3.0.tgz#0cdd4d919012451a5bc3ab0a16d00c6fd9a8c10b" integrity sha512-kB5x/kMKWcn0uVr9gBdNz21/oGbQwEQnF3P9p6E9yLfJ9DRcKS0fagbgYMFI0YFOoyKDj+2q6Rwax0kTYJF37g== -react@next: +react@16.7.0-alpha.2: version "16.7.0-alpha.2" resolved "https://registry.yarnpkg.com/react/-/react-16.7.0-alpha.2.tgz#924f2ae843a46ea82d104a8def7a599fbf2c78ce" integrity sha512-Xh1CC8KkqIojhC+LFXd21jxlVtzoVYdGnQAi/I2+dxbmos9ghbx5TQf9/nDxc4WxaFfUQJkya0w1k6rMeyIaxQ==