Skip to content

Commit

Permalink
feat: add onChange callback to useWindowSize
Browse files Browse the repository at this point in the history
  • Loading branch information
mahmoud-elgammal committed Dec 2, 2024
1 parent e1d0cd9 commit 3eb531a
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
15 changes: 15 additions & 0 deletions docs/useWindowSize.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,18 @@ const Demo = () => {
);
};
```

## Reference

```js
useWindowSize(options);
```

- `initialWidth` — Initial width value for non-browser environments.
- `initialHeight` — Initial height value for non-browser environments.
- `onChange` — Callback function triggered when the window size changes.

## Related hooks

- [useSize](./useSize.md)
- [useMeasure](./useMeasure.md)
17 changes: 16 additions & 1 deletion src/useWindowSize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,17 @@ import { useEffect } from 'react';
import useRafState from './useRafState';
import { isBrowser, off, on } from './misc/util';

const useWindowSize = (initialWidth = Infinity, initialHeight = Infinity) => {
interface Options {
initialWidth?: number;
initialHeight?: number;
onChange?: (width: number, height: number) => void;
}

const useWindowSize = ({
initialWidth = Infinity,
initialHeight = Infinity,
onChange,
}: Options = {}) => {
const [state, setState] = useRafState<{ width: number; height: number }>({
width: isBrowser ? window.innerWidth : initialWidth,
height: isBrowser ? window.innerHeight : initialHeight,
Expand All @@ -12,10 +22,15 @@ const useWindowSize = (initialWidth = Infinity, initialHeight = Infinity) => {
useEffect((): (() => void) | void => {
if (isBrowser) {
const handler = () => {
const width = window.innerWidth;
const height = window.innerHeight;

setState({
width: window.innerWidth,
height: window.innerHeight,
});

if (onChange) onChange(width, height);
};

on(window, 'resize', handler);
Expand Down
29 changes: 26 additions & 3 deletions tests/useWindowSize.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ describe('useWindowSize', () => {
expect(useWindowSize).toBeDefined();
});

function getHook(...args) {
return renderHook(() => useWindowSize(...args));
function getHook(options?: any) {
return renderHook(() => useWindowSize(options));
}

function triggerResize(dimension: 'width' | 'height', value: number) {
Expand All @@ -44,7 +44,7 @@ describe('useWindowSize', () => {
});

it('should use passed parameters as initial values in case of non-browser use', () => {
const hook = getHook(1, 1);
const hook = getHook({ initialWidth: 1, initialHeight: 1 });

expect(hook.result.current.height).toBe(isBrowser ? window.innerHeight : 1);
expect(hook.result.current.width).toBe(isBrowser ? window.innerWidth : 1);
Expand Down Expand Up @@ -85,4 +85,27 @@ describe('useWindowSize', () => {

expect(hook.result.current.width).toBe(2048);
});

it('should call onChange callback on window resize', () => {
const onChange = jest.fn();
getHook({ onChange });

act(() => {
triggerResize('width', 720);
triggerResize('height', 480);
requestAnimationFrame.step();
});

expect(onChange).toHaveBeenCalledWith(720, 480);
expect(onChange).toHaveBeenCalledTimes(2);

act(() => {
triggerResize('width', 1920);
triggerResize('height', 1080);
requestAnimationFrame.step();
});

expect(onChange).toHaveBeenCalledWith(1920, 1080);
expect(onChange).toHaveBeenCalledTimes(4);
});
});

0 comments on commit 3eb531a

Please sign in to comment.