Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"presets": [
[
"@babel/preset-env",
{
"modules": "commonjs"
}
],
"@babel/preset-react",
"@babel/typescript"
]
}
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
Expand Down
8 changes: 8 additions & 0 deletions dist/LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
The MIT License (MIT)
Copyright © 2020 llldar

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
102 changes: 102 additions & 0 deletions dist/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
## React useHoverIntent

react-use-hoverintent is a react hook which allows you to use classic hoverintent behaviour in modern, react way.

"hoverIntent is a plug-in that attempts to determine the user's intent... like a crystal ball, only with mouse movement! It is similar to jQuery's hover method. However, instead of calling the handlerIn function immediately, hoverIntent waits until the user's mouse slows down enough before making the call."

Built with typescript, with official typing, with zero dependency, transpiled to es5.

Inspired by [jquery-hoverintent](https://github.com/briancherne/jquery-hoverIntent) [react-hoverintent](https://www.npmjs.com/package/react-hoverintent)

## Installation

```bash
yarn add react-use-hoverintent
```

or

```bash
npm install react-use-hoverintent
```

## Options

`ref`: the react element ref which you want hoverintent to be applied, required.

`timeout` : A simple delay, in milliseconds, before the `onMouseOut` callback is fired. If the user mouses back over the element before the timeout has expired the `onMouseOut` callback will not be called (nor will the `onMouseOver` callback be called). This is primarily to protect against sloppy/human mousing trajectories that temporarily (and unintentionally) take the user off of the target element... giving them time to return.

Default `timeout: 0`

`sensitivity` : If the mouse travels fewer than this number of pixels between polling intervals, then the `onMouseOver` callback will be called. With the minimum sensitivity threshold of 1, the mouse must not move between polling intervals. With higher sensitivity thresholds you are more likely to receive a false positive.

Default `sensitivity: 6`

`interval` : The number of milliseconds hoverIntent waits between reading/comparing mouse coordinates. When the user's mouse first enters the element its coordinates are recorded. The soonest the `onMouseOut` callback can be called is after a single polling interval. Setting the polling interval higher will increase the delay before the first possible `onMouseOver` call, but also increases the time to the next point of comparison.

Default `interval: 100`

## Usage

Basic usage

```javascript
import React from 'react';
import { useHoverIntent } from 'react-use-hoverintent';

export const MyFunctionalComponent = (props) => {
const [isHovering, ref] = useHoverIntent();
return <div ref={ref} className={`${isHovering ? 'hover' : ''}`}></div>;
};
```

With options

```javascript
import React from 'react';
import { useHoverIntent } from 'react-use-hoverintent';

export const MyFunctionalComponent = (props) => {
const [isHovering, ref] = useHoverIntent({
timeout: 100,
sensitivity: 10,
interval: 200,
});
return <div ref={ref} className={`${isHovering ? 'hover' : ''}`}></div>;
};
```

With ForwardRef

```js
import React from 'react';
import { useHoverIntent } from 'react-use-hoverintent';

export const MyFunctionalComponent = React.forwardRef((props, ref) => {
const [isHovering, intentRef] = useHoverIntent({ ref });
return <div ref={intentRef} className={`${isHovering ? 'hover' : ''}`}></div>;
});
```

With Custom UI lib

Check if they have `innerRef` prop or forwarded ref

```javascript
import React from 'react';
import { useHoverIntent } from 'react-use-hoverintent';

export const MyFunctionalComponent = (props) => {
const [isHovering, intentRef] = useHoverIntent();
return (
<Card
innerRef={intentRef}
className={`${isHovering ? 'hover' : ''}`}
></Card>
);
};
```

## License

MIT
9 changes: 9 additions & 0 deletions dist/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/// <reference types="react" />
interface optionType {
ref?: React.Ref<HTMLElement | null>;
sensitivity?: number;
interval?: number;
timeout?: number;
}
export declare function useHoverIntent(options: optionType): (boolean | import("react").RefObject<HTMLElement>)[];
export {};
130 changes: 130 additions & 0 deletions dist/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useHoverIntent = useHoverIntent;

var _react = require("react");

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

function useHoverIntent(options) {
var ref = options.ref,
_options$sensitivity = options.sensitivity,
sensitivity = _options$sensitivity === void 0 ? 6 : _options$sensitivity,
_options$interval = options.interval,
interval = _options$interval === void 0 ? 100 : _options$interval,
_options$timeout = options.timeout,
timeout = _options$timeout === void 0 ? 0 : _options$timeout;
var intentRef = (0, _react.useRef)(null);

var _useState = (0, _react.useState)(false),
_useState2 = _slicedToArray(_useState, 2),
isHovering = _useState2[0],
setIsHovering = _useState2[1];

var x = 0,
y = 0,
pX = 0,
pY = 0,
timer = 0;

var delay = function delay(e) {
if (timer) {
clearTimeout(timer);
}

return setIsHovering(false);
};

var tracker = function tracker(e) {
x = e.clientX;
y = e.clientY;
};

var compare = function compare(e) {
if (timer) {
clearTimeout(timer);
}

if (Math.abs(pX - x) + Math.abs(pY - y) < sensitivity) {
return setIsHovering(true);
} else {
pX = x;
pY = y;
timer = window.setTimeout(function () {
return compare(e);
}, interval);
}
};

var dispatchOver = function dispatchOver(e) {
if (timer) {
clearTimeout(timer);
}

if (intentRef.current) {
intentRef.current.removeEventListener('mousemove', tracker, false);
}

if (!isHovering) {
pX = e.clientX;
pY = e.clientY;

if (intentRef.current) {
intentRef.current.addEventListener('mousemove', tracker, false);
}

timer = window.setTimeout(function () {
return compare(e);
}, interval);
}
};

var dispatchOut = function dispatchOut(e) {
if (timer) {
clearTimeout(timer);
}

if (intentRef.current) {
intentRef.current.removeEventListener('mousemove', tracker, false);
}

if (isHovering) {
timer = window.setTimeout(function () {
return delay(e);
}, timeout);
}
};

(0, _react.useEffect)(function () {
var currentRef = intentRef.current;

if (currentRef) {
currentRef.addEventListener('mouseover', dispatchOver, false);
currentRef.addEventListener('mouseout', dispatchOut, false);
}

return function () {
if (currentRef) {
currentRef.removeEventListener('mouseover', dispatchOver, false);
currentRef.removeEventListener('mouseout', dispatchOut, false);
}
};
});
(0, _react.useImperativeHandle)(ref, function () {
return intentRef.current;
}, [intentRef]);
return [isHovering, intentRef];
}
1 change: 1 addition & 0 deletions dist/index.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions dist/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "@darius_rosendahl/react-use-hoverintent",
"version": "1.1.7",
"description": "React hook for hoverIntent",
"main": "dist/index.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"keywords": [
"hover",
"hoverintent",
"delay",
"react",
"hooks"
],
"author": "linlilulll@gmail.com",
"license": "MIT",
"devDependencies": {
"@types/react": "^16.9.35",
"react": "^16.13.1",
"typescript": "^3.9.2"
},
"repository": "https://github.com/llldar/react-use-hoverintent",
"peerDependencies": {
"react": "^16.8.0"
},
"exclude": [
"node_modules"
],
"scripts": {
"build": "tsc && babel src --out-dir dist --extensions .ts,.tsx,.js,.jsx && cp package.json LICENSE.md README.md ./dist"
},
"dependencies": {
"@babel/preset-env": "^7.12.1",
"@babel/preset-react": "^7.12.1",
"@babel/preset-typescript": "^7.12.1"
}
}
20 changes: 15 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
{
"name": "react-use-hoverintent",
"version": "1.0.4",
"name": "@darius_rosendahl/react-use-hoverintent",
"version": "1.1.7",
"description": "React hook for hoverIntent",
"main": "index.ts",
"main": "dist/index.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"keywords": [
"hover",
"hoverintent",
Expand All @@ -21,7 +23,15 @@
"peerDependencies": {
"react": "^16.8.0"
},
"exclude": [
"node_modules"
],
"scripts": {
"build": "tsc && cp package.json LICENSE.md README.md ./dist"
"build": "tsc && babel src --out-dir dist --extensions .ts,.tsx,.js,.jsx && cp package.json LICENSE.md README.md ./dist"
},
"dependencies": {
"@babel/preset-env": "^7.12.1",
"@babel/preset-react": "^7.12.1",
"@babel/preset-typescript": "^7.12.1"
}
}
}
File renamed without changes.
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@
"sourceMap": true,
"declaration": true
},
"include": ["index.ts"]
"include": ["./src/index.ts"]
}
Loading