Skip to content

Commit

Permalink
feat: add useWindowScroll hook
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich authored Mar 23, 2019
2 parents 3e50e81 + 2fd08f8 commit 076d0de
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
- [`useNetwork`](./docs/useNetwork.md) — tracks state of user's internet connection.
- [`useOrientation`](./docs/useOrientation.md) — tracks state of device's screen orientation.
- [`useSize`](./docs/useSize.md) — tracks some HTML element's dimensions.
- [`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)
<br/>
<br/>
Expand Down
20 changes: 20 additions & 0 deletions docs/useWindowScroll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# `useWindowSize`

React sensor hook that re-renders on window scroll

## Usage

```jsx
import {useWindowScroll} from 'react-use';

const Demo = () => {
const {x, y} = useWindowScroll();

return (
<div>
<div>x: {x}</div>
<div>y: {y}</div>
</div>
);
};
```
30 changes: 30 additions & 0 deletions src/__stories__/useWindowScroll.story.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import * as React from 'react';
import {storiesOf} from '@storybook/react';
import {useWindowScroll} from '..';
import ShowDocs from '../util/ShowDocs';

const Demo = () => {
const {x, y} = useWindowScroll();

return (
<div style={{
width: "200vw",
height: "200vh"
}}>
<div style={{
position: "fixed",
left: 0,
right: 0}}
>
<div>x: {x}</div>
<div>y: {y}</div>
</div>
</div>
);
};

storiesOf('Sensors/useWindowScroll', module)
.add('Docs', () => <ShowDocs md={require('../../docs/useWindowScroll.md')} />)
.add('Demo', () =>
<Demo/>
)
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import useTween from './useTween';
import useUnmount from './useUnmount';
import useUpdate from './useUpdate';
import useVideo from './useVideo';
import useWindowScroll from './useWindowScroll';
import useWindowSize from './useWindowSize';
import useWait from './useWait';
import useUpdateEffect from './useUpdateEffect'
Expand Down Expand Up @@ -101,6 +102,7 @@ export {
useUnmount,
useUpdate,
useVideo,
useWindowScroll,
useWindowSize,
useWait,
useUpdateEffect
Expand Down
39 changes: 39 additions & 0 deletions src/useWindowScroll.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {useState, useEffect, useRef} from 'react';
import {isClient} from './util';

export interface State {
x: number;
y: number;
}

const useWindowScroll = (): State => {
const frame = useRef(0);
const [state, setState] = useState<State>({
x: isClient ? window.scrollX : 0,
y: isClient ? window.scrollY : 0
})

useEffect(() => {
const handler = () => {
cancelAnimationFrame(frame.current)

frame.current = requestAnimationFrame(() => {
setState({
x: window.scrollX,
y: window.scrollY
})
})
}

window.addEventListener('scroll', handler, {
capture: false,
passive: true
})

return () => window.removeEventListener('scroll', handler)
}, [])

return state
}

export default useWindowScroll

0 comments on commit 076d0de

Please sign in to comment.