diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8d415c2..d13e645 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,13 @@
### Removed
+## [1.1.0] - 2020-02-15
+
+### Changed
+
+- set history as global state
+- accuracy becomes the max pointer size by type
+
## [1.0.1] - 2020-02-14
### Added
diff --git a/README.md b/README.md
index 63f4026..1ea4763 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
[![Build Status](https://travis-ci.org/idomusha/use-interaction.svg?branch=master)](https://travis-ci.org/idomusha/use-interaction)
[![npm version](https://badge.fury.io/js/use-interaction.svg)](https://badge.fury.io/js/use-interaction)
-[![Coverage Status](https://coveralls.io/repos/github/idomusha/use-interaction/badge.svg?branch=master)](https://coveralls.io/github/idomusha/use-interaction?branch=master)
+[![Coverage Status](https://coveralls.io/repos/github/idomusha/use-interaction/badge.svg?branch=master&service=github)](https://coveralls.io/github/idomusha/use-interaction?branch=master)
React hook `useInteraction()` allows to get the user interaction type: `touch`, `mouse` or `keyboard`.
@@ -68,7 +68,9 @@ export const Demo = () => {
`object`
-- **initialHover**: `boolean` - to not wait at first an action from the user, **canHover** can be defined via this parameter to be effective as soon as the page is loaded (i.e. `true`, default: `null`)
+| Property Name | Type | Description | Default Value |
+| :--------------- | :-------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------- | :-----------: |
+| **initialHover** | `boolean` | to not wait an action on the part of the user, **canHover** can be defined via this parameter to be effective as soon as the page is loaded (i.e. `true`) | `false` |
const [interaction, history, canHover, accuracy] = useInteraction({initialHover: true})
@@ -83,9 +85,9 @@ export const Demo = () => {
- **canHover**: `boolean` - if the user can hover (i.e. `true`, default: `null`)
- **accuracy**: `number` - pointer size in pixels (i.e. `23`, default: `null`), -->
-| Returned Array | Assigned Name | Type | Description | Default Value |
-| :------------- | :-----------: | :--------------: | :-------------------------------------------------------------------------- | :-----------: |
-| 1st element | interaction | `string` | interaction type of the user: `touch`, `mouse` or `keyboard` (i.e. `touch`) | `null` |
-| 2nd element | history | `Array.` | all interaction types used from the load (i.e. `['touch', 'mouse']`} | `[]` |
-| 3rd element | canHover | `boolean` | if the user can hover (i.e. `true`) | `false` |
-| 4th element | accuracy | `number` | pointer size in pixels (i.e. `23`) | `null` |
+| Returned Array | Type | Description | Default Value |
+| :------------------------ | :--------------: | :-------------------------------------------------------------------------- | :-----------: |
+| 1st element (interaction) | `string` | interaction type of the user: `touch`, `mouse` or `keyboard` (i.e. `touch`) | `null` |
+| 2nd element (history) | `Array.` | all interaction types used from the load (i.e. `['touch', 'mouse']`} | `[]` |
+| 3rd element (canHover) | `boolean` | if the user can hover (i.e. `true`) | `false` |
+| 4th element (accuracy) | `number` | pointer size in pixels (i.e. `23`) | `null` |
diff --git a/package.json b/package.json
index cea44a2..07b1e46 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "use-interaction",
- "version": "1.0.1",
+ "version": "1.1.0",
"private": false,
"description": "React hook for getting and following user interaction type",
"keywords": [
diff --git a/src/Demo.js b/src/Demo.js
index 3c65e1c..3a4ef49 100644
--- a/src/Demo.js
+++ b/src/Demo.js
@@ -40,20 +40,20 @@ const Demo = () => {
history{' '}
- keeps a record of all user interaction types. That way a user that
+ keeps a record of all user interaction types: that way a user that
interacts both with mouse and touch can easily be detected.
canHover{' '}
- is a shorcut for any type of interaction except mouse, and allows to
+ is a shorcut for any type of interaction except mouse: allows to
display hidden information to the user in this case.
accuracy{' '}
- is the size of contact geometry of the pointer. The higher the number,
+ is the size of contact geometry of the pointer: the higher the number,
the bigger the button size should be defined.
diff --git a/src/useInteraction.js b/src/useInteraction.js
index c42974a..418f760 100644
--- a/src/useInteraction.js
+++ b/src/useInteraction.js
@@ -1,8 +1,13 @@
import { useState, useEffect, useCallback } from 'react'
import PropTypes from 'prop-types'
import { round } from 'lodash'
+import { setGlobal, useGlobal } from 'reactn'
-let history = []
+setGlobal({
+ history: [],
+ prevInteraction: null,
+ accuracy: null,
+})
const getKey = event => (event.keyCode ? event.keyCode : event.which)
@@ -11,13 +16,15 @@ const getTarget = event => event.target || event.srcElement
const useInteraction = ({ initialHover = false } = {}) => {
const [interaction, setInteraction] = useState(null)
const [canHover, setCanHover] = useState(initialHover)
- const [accuracy, setAccuracy] = useState(null)
const [firedEvent, setFiredEvent] = useState({
touchStart: null,
mouseMove: null,
mouseOver: null,
keyDown: null,
})
+ const [history, setHistory] = useGlobal('history')
+ const [prevInteraction, setPrevInteraction] = useGlobal('prevInteraction')
+ const [accuracy, setAccuracy] = useGlobal('accuracy')
const inputs = ['input', 'select', 'textarea']
const keys = {
9: 'tab',
@@ -42,10 +49,10 @@ const useInteraction = ({ initialHover = false } = {}) => {
mouseMove: false,
}))
- history = [...new Set([...history, 'touch'])]
+ setHistory([...new Set([...history, 'touch'])])
setInteraction('touch')
setCanHover(false)
- }, [setFiredEvent])
+ }, [history, setHistory])
const handleInteractionMouse = useCallback(() => {
// prevent false positive on mousemove with touch devices
@@ -77,11 +84,17 @@ const useInteraction = ({ initialHover = false } = {}) => {
firedEvent.mouseMove === true ||
firedEvent.touchStart === false
) {
- history = [...new Set([...history, 'mouse'])]
+ setHistory([...new Set([...history, 'mouse'])])
setInteraction('mouse')
setCanHover(true)
}
- }, [firedEvent, setFiredEvent, setCanHover])
+ }, [
+ firedEvent.touchStart,
+ firedEvent.keyDown,
+ firedEvent.mouseMove,
+ setHistory,
+ history,
+ ])
const handleInteractionKeyboard = useCallback(
event => {
@@ -108,19 +121,23 @@ const useInteraction = ({ initialHover = false } = {}) => {
if (interaction === 'keyboard') return
- history = [...new Set([...history, 'keyboard'])]
+ setHistory([...new Set([...history, 'keyboard'])])
setInteraction('keyboard')
setCanHover(false)
}
},
- [inputs, keys, interaction, setFiredEvent]
+ [keys, inputs, interaction, setHistory, history]
)
const handleInteractionPointer = useCallback(
event => {
- setAccuracy(round(event.height, 1))
+ const nextAccuracy = round(event.height, 1)
+ if (nextAccuracy > accuracy || prevInteraction !== event.pointerType) {
+ setAccuracy(nextAccuracy)
+ }
+ setPrevInteraction(event.pointerType)
},
- [setAccuracy]
+ [accuracy, prevInteraction, setAccuracy, setPrevInteraction]
)
useEffect(() => {
diff --git a/src/useInteraction.test.js b/src/useInteraction.test.js
index ab52111..cf2d7f6 100644
--- a/src/useInteraction.test.js
+++ b/src/useInteraction.test.js
@@ -1,112 +1,114 @@
-import React from 'react'
-import { renderHook, cleanup, act } from '@testing-library/react-hooks'
-import { fireEvent, createEvent, render, wait } from '@testing-library/react'
-
-import useInteraction from './useInteraction'
-import Demo from './Demo'
-
-afterEach(cleanup)
-
-test('should init interaction type of the user', () => {
- const { result } = renderHook(() => useInteraction())
-
- expect(result.current[0]).toBe(null)
- expect(result.current[1]).toMatchObject([])
- expect(result.current[2]).toBeFalsy()
- expect(result.current[3]).toBe(null)
-})
-
-test('should init interaction type of the user with initialHover', () => {
- const { result } = renderHook(() => useInteraction({ initialHover: true }))
-
- expect(result.current[0]).toBe(null)
- expect(result.current[1]).toMatchObject([])
- expect(result.current[2]).toBeTruthy()
- expect(result.current[3]).toBe(null)
-})
-
-test('should set interaction type of the user to touch', () => {
- const { result } = renderHook(() => useInteraction())
-
- act(() => {
- fireEvent.touchStart(document.body, {})
- })
-
- expect(result.current[0]).toBe('touch')
- expect(result.current[2]).toBeFalsy()
-})
-
-test('should set interaction type of the user to mouse', () => {
- const { result } = renderHook(() => useInteraction())
-
- act(() => {
- fireEvent.mouseMove(document.body, {})
- })
-
- expect(result.current[0]).toBe('mouse')
- expect(result.current[2]).toBeTruthy()
-})
-
-test('should set interaction type of the user to keyboard', () => {
- const { result, unmount } = renderHook(() => useInteraction())
-
- act(() => {
- fireEvent.keyDown(document.body, {
- key: 'Tab',
- code: 'Tab',
- keyCode: 9,
- which: 9,
- })
- })
-
- expect(result.current[0]).toBe('keyboard')
- expect(result.current[2]).toBeFalsy()
- unmount()
-})
-
-test('should not set interaction type of the user to keyboard', () => {
- const { result } = renderHook(() => useInteraction())
- const { getByTestId } = render()
-
- act(() => {
- fireEvent.mouseMove(document.body, {})
- fireEvent.keyDown(getByTestId('test-input'), {
- key: ' ',
- code: 'Space',
- keyCode: 32,
- which: 32,
- })
- })
-
- expect(result.current[0]).toBe('mouse')
- expect(result.current[2]).toBeTruthy()
-})
-
-test('should set interaction type of the user to touch and then to mouse', () => {
- const { result } = renderHook(() => useInteraction())
-
- act(() => {
- fireEvent.touchStart(document.body, {})
- fireEvent.mouseMove(document.body, {})
- })
-
- wait(() => {
- expect(result.current[0]).toBe('mouse')
- expect(result.current[1]).toMatchObject(['touch', 'mouse'])
- expect(result.current[2]).toBeTruthy()
- })
-})
-
-test('should set accuracy of the pointer', () => {
- const { result } = renderHook(() => useInteraction())
-
- const pointerDown = createEvent.click(document.body, { height: 23.666666666 })
-
- act(() => {
- fireEvent(document.body, pointerDown)
- })
-
- wait(() => {
- expect(result.current[3]).toBe(23.7)
- })
-})
+import React from 'react'
+import { renderHook, cleanup, act } from '@testing-library/react-hooks'
+import { fireEvent, createEvent, render, wait } from '@testing-library/react'
+
+import useInteraction from './useInteraction'
+import Demo from './Demo'
+
+afterEach(cleanup)
+
+test('should init interaction type of the user', () => {
+ const { result } = renderHook(() => useInteraction())
+
+ expect(result.current[0]).toBe(null)
+ expect(result.current[1]).toMatchObject([])
+ expect(result.current[2]).toBeFalsy()
+ expect(result.current[3]).toBe(null)
+})
+
+test('should init interaction type of the user with initialHover', () => {
+ const { result } = renderHook(() => useInteraction({ initialHover: true }))
+
+ expect(result.current[0]).toBe(null)
+ expect(result.current[1]).toMatchObject([])
+ expect(result.current[2]).toBeTruthy()
+ expect(result.current[3]).toBe(null)
+})
+
+test('should set interaction type of the user to touch', () => {
+ const { result } = renderHook(() => useInteraction())
+
+ act(() => {
+ fireEvent.touchStart(document.body, {})
+ })
+
+ expect(result.current[0]).toBe('touch')
+ expect(result.current[2]).toBeFalsy()
+})
+
+test('should set interaction type of the user to mouse', () => {
+ const { result } = renderHook(() => useInteraction())
+
+ act(() => {
+ fireEvent.mouseMove(document.body, {})
+ })
+
+ expect(result.current[0]).toBe('mouse')
+ expect(result.current[2]).toBeTruthy()
+})
+
+test('should set interaction type of the user to keyboard', () => {
+ const { result, unmount } = renderHook(() => useInteraction())
+
+ act(() => {
+ fireEvent.keyDown(document.body, {
+ key: 'Tab',
+ code: 'Tab',
+ keyCode: 9,
+ which: 9,
+ })
+ })
+
+ expect(result.current[0]).toBe('keyboard')
+ expect(result.current[2]).toBeFalsy()
+ unmount()
+})
+
+test('should not set interaction type of the user to keyboard', () => {
+ const { result } = renderHook(() => useInteraction())
+ const { getByTestId } = render()
+
+ act(() => {
+ fireEvent.mouseMove(document.body, {})
+ fireEvent.keyDown(getByTestId('test-input'), {
+ key: ' ',
+ code: 'Space',
+ keyCode: 32,
+ which: 32,
+ })
+ })
+
+ expect(result.current[0]).toBe('mouse')
+ expect(result.current[2]).toBeTruthy()
+})
+
+test('should set interaction type of the user to touch and then to mouse', () => {
+ const { result } = renderHook(() => useInteraction())
+
+ act(() => {
+ fireEvent.touchStart(document.body, {})
+ fireEvent.mouseMove(document.body, {})
+ })
+
+ wait(() => {
+ expect(result.current[0]).toBe('mouse')
+ expect(result.current[1]).toMatchObject(['touch', 'mouse'])
+ expect(result.current[2]).toBeTruthy()
+ })
+})
+
+test('should set accuracy of the pointer', () => {
+ const { result } = renderHook(() => useInteraction())
+
+ const pointerDown = createEvent.pointerDown(document.body, {
+ height: 23.666666666,
+ })
+
+ act(() => {
+ fireEvent(document.body, pointerDown)
+ })
+
+ wait(() => {
+ expect(result.current[3]).toBe(23.7)
+ })
+})