mirror of
https://github.com/streamich/react-use.git
synced 2026-01-18 14:06:52 +00:00
feat: 🎸 add useHover hook
This commit is contained in:
parent
73ce535f09
commit
406af205e3
@ -12,6 +12,7 @@
|
||||
- [`useMap`](./docs/useMap.md)
|
||||
- Sensors
|
||||
- [`useBattery`](./docs/useBattery.md)
|
||||
- [`useHover`](./docs/useHover.md)
|
||||
- [`useSize`](./docs/useSize.md)
|
||||
- [`useWindowSize`](./docs/useWindowSize.md)
|
||||
- Side effects
|
||||
|
||||
25
docs/useHover.md
Normal file
25
docs/useHover.md
Normal file
@ -0,0 +1,25 @@
|
||||
# `useHover`
|
||||
|
||||
React sensor hook that tracks size of some HTML element.
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```jsx
|
||||
import {useHover} from 'react-use';
|
||||
|
||||
const Demo = () => {
|
||||
const element = (hovered) =>
|
||||
<div>
|
||||
Hover me! {hovered && 'Thanks!'}
|
||||
</div>;
|
||||
const [hoverable, hovered] = useHover(element);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{hoverable}
|
||||
<div>{hovered ? 'HOVERED' : ''}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
@ -4,6 +4,7 @@
|
||||
"description": "Collection of React Hooks",
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
"start": "yarn storybook",
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build": "tsc",
|
||||
"test:story:build": "build-storybook",
|
||||
@ -23,5 +24,9 @@
|
||||
"ts-node": "^7.0.1",
|
||||
"ts-loader": "3",
|
||||
"babel-core": "^6.26.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "16.7.0-alpha.0",
|
||||
"react-dom": "16.7.0-alpha.0"
|
||||
}
|
||||
}
|
||||
|
||||
23
src/__stories__/useHover.story.tsx
Normal file
23
src/__stories__/useHover.story.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import {storiesOf} from '@storybook/react';
|
||||
import * as React from 'react';
|
||||
import {useHover} from '..';
|
||||
|
||||
const Demo = () => {
|
||||
const element = (hovered: boolean) =>
|
||||
<div>
|
||||
Hover me! {hovered && 'Thanks!'}
|
||||
</div>;
|
||||
const [hoverable, hovered] = useHover(element);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{hoverable}
|
||||
<div>{hovered ? 'HOVERED' : ''}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
storiesOf('useHover', module)
|
||||
.add('Example', () =>
|
||||
<Demo/>
|
||||
)
|
||||
@ -1,5 +1,6 @@
|
||||
import useBattery from './useBattery';
|
||||
import useCounter from './useCounter';
|
||||
import useHover from './useHover';
|
||||
import useList from './useList';
|
||||
import useMap from './useMap';
|
||||
import useSize from './useSize';
|
||||
@ -10,6 +11,7 @@ import useWindowSize from './useWindowSize';
|
||||
export {
|
||||
useBattery,
|
||||
useCounter,
|
||||
useHover,
|
||||
useList,
|
||||
useMap,
|
||||
useSize,
|
||||
|
||||
32
src/useHover.ts
Normal file
32
src/useHover.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import * as React from 'react';
|
||||
import {useState} from './react';
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
export type Element = ((state: boolean) => React.ReactElement<any>) | React.ReactElement<any>;
|
||||
|
||||
const useHover = (element: Element): [React.ReactElement<any>, boolean] => {
|
||||
const [state, setState] = useState(false);
|
||||
|
||||
const onMouseEnter = (originalOnMouseEnter?: any) => (event: any) => {
|
||||
(originalOnMouseEnter || noop)(event);
|
||||
setState(true);
|
||||
};
|
||||
const onMouseLeave = (originalOnMouseLeave?: any) => (event: any) => {
|
||||
(originalOnMouseLeave || noop)(event);
|
||||
setState(false);
|
||||
};
|
||||
|
||||
if (typeof element === 'function') {
|
||||
element = element(state);
|
||||
}
|
||||
|
||||
const el = React.cloneElement(element, {
|
||||
onMouseEnter: onMouseEnter(element.props.onMouseEnter),
|
||||
onMouseLeave: onMouseLeave(element.props.onMouseLeave)
|
||||
});
|
||||
|
||||
return [el, state];
|
||||
};
|
||||
|
||||
export default useHover;
|
||||
Loading…
x
Reference in New Issue
Block a user