diff --git a/README.md b/README.md index 74449a3cc6..ced7577257 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ - [`usePageLeave`](./docs/usePageLeave.md) — triggers when mouse leaves page boundaries. - [`useScroll`](./docs/useScroll.md) — tracks an HTML element's scroll position. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/sensors-usescroll--docs) - [`useSize`](./docs/useSize.md) — tracks an HTML element's dimensions. + - [`useStartTyping`](./docs/useStartTyping.md) — detects when user starts typing. - [`useWindowScroll`](./docs/useWindowScroll.md) — tracks `Window` scroll position. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/sensors-usewindowscroll--docs) - [`useWindowSize`](./docs/useWindowSize.md) — tracks `Window` dimensions. [![][img-demo]](https://codesandbox.io/s/m7ln22668)
diff --git a/docs/useStartTyping.md b/docs/useStartTyping.md new file mode 100644 index 0000000000..213810c28f --- /dev/null +++ b/docs/useStartTyping.md @@ -0,0 +1,16 @@ +# `useStartTyping` + +React sensor hook that fires a callback when user start typing. Can be use +to focus default input field on the page. + +## Usage + +```jsx +import useStartTyping from 'react-use/lib/useStartTyping'; + +const Demo = () => { + useStartTyping(() => alert('Started typing...')); + + return null; +}; +``` diff --git a/src/__stories__/useStartTyping.story.tsx b/src/__stories__/useStartTyping.story.tsx new file mode 100644 index 0000000000..f1cd9d01d4 --- /dev/null +++ b/src/__stories__/useStartTyping.story.tsx @@ -0,0 +1,41 @@ +import {storiesOf} from '@storybook/react'; +import * as React from 'react'; +import {useStartTyping} from '..'; +import ShowDocs from './util/ShowDocs'; + +const Demo = () => { + const input = React.useRef(null); + useStartTyping(() => { + if (input.current) { + input.current.focus(); + } + }); + + return ( +
+

Start typing, and below field will get focused.

+ + +
+
+ +

Try focusing below elements and see what happens.

+ +
+
+ +
+
+ +
+
+
Editable DIV
+
+ ); +}; + +storiesOf('Sensors|useStartTyping', module) + // .add('Docs', () => ) + .add('Demo', () => + + ) diff --git a/src/index.ts b/src/index.ts index 9b8f364024..6d3508b4a4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -51,6 +51,7 @@ import useSetState from './useSetState'; import useSize from './useSize'; import useSpeech from './useSpeech'; import useSpring from './useSpring'; +import useStartTyping from './useStartTyping'; import useThrottle from './useThrottle'; import useThrottleFn from './useThrottleFn'; import useTimeout from './useTimeout'; @@ -119,6 +120,7 @@ export { useSize, useSpeech, useSpring, + useStartTyping, useThrottle, useThrottleFn, useTimeout, diff --git a/src/useStartTyping.ts b/src/useStartTyping.ts new file mode 100644 index 0000000000..aeee4d3b9a --- /dev/null +++ b/src/useStartTyping.ts @@ -0,0 +1,42 @@ +import {useLayoutEffect} from 'react'; + +const isFocusedElementEditable = () => { + const {activeElement, body} = document; + + // If not element has focus, we assume it is not editable, too. + if (activeElement === body) return false; + + // Assume and