From 8b0580e98b017d2cb8b7de6212fb8c149ed935a0 Mon Sep 17 00:00:00 2001 From: streamich Date: Tue, 26 Mar 2019 11:10:54 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20move=20extra=20mouse=20f?= =?UTF-8?q?unctionality=20into=20useMouseHovered?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .storybook/addons.js | 2 +- src/__stories__/useMouse.story.tsx | 17 +++------ src/__stories__/useMouseHovered.story.tsx | 46 +++++++++++++++++++++++ src/index.ts | 2 + src/useMouse.ts | 25 ++++-------- src/useMouseHovered.ts | 27 +++++++++++++ 6 files changed, 89 insertions(+), 30 deletions(-) create mode 100644 src/__stories__/useMouseHovered.story.tsx create mode 100644 src/useMouseHovered.ts diff --git a/.storybook/addons.js b/.storybook/addons.js index 9467dbc52c..1d7ca1fc50 100644 --- a/.storybook/addons.js +++ b/.storybook/addons.js @@ -1,4 +1,4 @@ +import '@storybook/addon-knobs/register'; import '@storybook/addon-options/register'; import '@storybook/addon-actions/register'; -import '@storybook/addon-knobs/register'; import '@storybook/addon-notes/register'; diff --git a/src/__stories__/useMouse.story.tsx b/src/__stories__/useMouse.story.tsx index 1ed753c306..7954135435 100644 --- a/src/__stories__/useMouse.story.tsx +++ b/src/__stories__/useMouse.story.tsx @@ -1,22 +1,19 @@ import * as React from 'react'; import {storiesOf} from '@storybook/react'; -import {useMouse, useToggle} from '..'; +import {useMouse} from '..'; import ShowDocs from '../util/ShowDocs'; -const Demo = () => { - const [whenHovered, toggleWhenHovered] = useToggle(false); +const Demo: React.FC = () => { const ref = React.useRef(null); - const state = useMouse(ref, {whenHovered, bound: true}) + const state = useMouse(ref) return ( <>
         {JSON.stringify(state, null, 2)}
       
- +
+
{ storiesOf('Sensors|useMouse', module) .add('Docs', () => ) - .add('Demo', () => - - ) + .add('Demo', () => ) diff --git a/src/__stories__/useMouseHovered.story.tsx b/src/__stories__/useMouseHovered.story.tsx new file mode 100644 index 0000000000..87b840ad20 --- /dev/null +++ b/src/__stories__/useMouseHovered.story.tsx @@ -0,0 +1,46 @@ +import * as React from 'react'; +import {storiesOf} from '@storybook/react'; +import {withKnobs, boolean} from '@storybook/addon-knobs'; +import {useMouseHovered} from '..'; +import ShowDocs from '../util/ShowDocs'; + +const Demo: React.FC = ({whenHovered, bound}) => { + const ref = React.useRef(null); + const state = useMouseHovered(ref, {whenHovered, bound}) + + return ( + <> +
+        {JSON.stringify(state, null, 2)}
+      
+
+
+
+ + 🐭 + +
+ + ); +}; + +storiesOf('Sensors|useMouseHovered', module) + .addDecorator(withKnobs) + .add('Docs', () => ) + .add('Demo', () => { + const bound = boolean('bound', false); + const whenHovered = boolean('whenHovered', false); + return ; + }) diff --git a/src/index.ts b/src/index.ts index dad9bb57c5..a15d5acb03 100644 --- a/src/index.ts +++ b/src/index.ts @@ -28,6 +28,7 @@ import useMediaDevices from './useMediaDevices'; import useMotion from './useMotion'; import useMount from './useMount'; import useMouse from './useMouse'; +import useMouseHovered from './useMouseHovered'; import useNetwork from './useNetwork'; import useNumber from './useNumber'; import useObservable from './useObservable'; @@ -86,6 +87,7 @@ export { useMotion, useMount, useMouse, + useMouseHovered, useNetwork, useNumber, useObservable, diff --git a/src/useMouse.ts b/src/useMouse.ts index d01ae03443..9c64fdb2b0 100644 --- a/src/useMouse.ts +++ b/src/useMouse.ts @@ -1,5 +1,4 @@ import {useState, useEffect, useRef, RefObject} from 'react'; -import useHoverDirty from "./useHoverDirty"; export interface State { docX: number; @@ -12,12 +11,7 @@ export interface State { elW: number; } -export interface UseMouseOptions { - whenHovered?: boolean; - bound?: boolean; -} - -const useMouse = (ref: RefObject, {whenHovered = false, bound = false}: UseMouseOptions = {}): State => { +const useMouse = (ref: RefObject): State => { if (process.env.NODE_ENV === 'development') { if ((typeof ref !== 'object') || (typeof ref.current === 'undefined')) { console.error('useMouse expects a single ref argument.'); @@ -25,7 +19,6 @@ const useMouse = (ref: RefObject, {whenHovered = false, bound = fal } const frame = useRef(0); - const isHovered = useHoverDirty(ref, whenHovered); const [state, setState] = useState({ docX: 0, docY: 0, @@ -54,8 +47,8 @@ const useMouse = (ref: RefObject, {whenHovered = false, bound = fal docY: event.pageY, posX, posY, - elX: bound ? Math.max(0, Math.min(elX, elW)) : elX, - elY: bound ? Math.max(0, Math.min(elY, elH)) : elY, + elX, + elY, elH, elW, }); @@ -63,17 +56,13 @@ const useMouse = (ref: RefObject, {whenHovered = false, bound = fal }); } - if (isHovered || !whenHovered) { - document.addEventListener('mousemove', moveHandler); - } + document.addEventListener('mousemove', moveHandler); return () => { - if (isHovered || !whenHovered) { - cancelAnimationFrame(frame.current); - document.removeEventListener('mousemove', moveHandler); - } + cancelAnimationFrame(frame.current); + document.removeEventListener('mousemove', moveHandler); }; - }, [isHovered, whenHovered, ref]) + }, [ref.current]) return state; } diff --git a/src/useMouseHovered.ts b/src/useMouseHovered.ts new file mode 100644 index 0000000000..dba1323513 --- /dev/null +++ b/src/useMouseHovered.ts @@ -0,0 +1,27 @@ +import {RefObject} from 'react'; +import useHoverDirty from './useHoverDirty'; +import useMouse, {State} from './useMouse'; + +export interface UseMouseHoveredOptions { + whenHovered?: boolean; + bound?: boolean; +} + +const nullRef = {current: null}; + +const useMouseHovered = (ref: RefObject, options: UseMouseHoveredOptions = {}): State => { + const whenHovered = !!options.whenHovered; + const bound = !!options.bound; + + const isHovered = useHoverDirty(ref, whenHovered); + const state = useMouse(whenHovered && !isHovered ? nullRef : ref); + + if (bound) { + state.elX = Math.max(0, Math.min(state.elX, state.elW)); + state.elY = Math.max(0, Math.min(state.elY, state.elH)); + } + + return state; +} + +export default useMouseHovered;