diff --git a/docs/useWindowSize.md b/docs/useWindowSize.md index e84501cf3b..836d8c10ec 100644 --- a/docs/useWindowSize.md +++ b/docs/useWindowSize.md @@ -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) \ No newline at end of file diff --git a/src/useWindowSize.ts b/src/useWindowSize.ts index 3137307e3a..10d9402767 100644 --- a/src/useWindowSize.ts +++ b/src/useWindowSize.ts @@ -3,29 +3,52 @@ import { useEffect } from 'react'; import useRafState from './useRafState'; import { isBrowser, off, on } from './misc/util'; -const useWindowSize = (initialWidth = Infinity, initialHeight = Infinity) => { +// Define the type for options that can be passed to the hook +interface Options { + initialWidth?: number; // Initial width of the window (Default value is Infinity) + initialHeight?: number; // Initial height of the window (Default value is Infinity) + onChange?: (width: number, height: number) => void; // Callback function to execute on window resize (optional) +} + +const useWindowSize = ({ + initialWidth = Infinity, + initialHeight = Infinity, + onChange, +}: Options = {}) => { + // Use the useRafState hook to maintain the current window size (width and height) const [state, setState] = useRafState<{ width: number; height: number }>({ width: isBrowser ? window.innerWidth : initialWidth, height: isBrowser ? window.innerHeight : initialHeight, }); useEffect((): (() => void) | void => { + // Only run the effect on the browser (to avoid issues with SSR) if (isBrowser) { const handler = () => { + const width = window.innerWidth; + const height = window.innerHeight; + + // Update the state with the new window size setState({ - width: window.innerWidth, - height: window.innerHeight, + width, + height, }); + + // If an onChange callback is provided, call it with the new dimensions + if (onChange) onChange(width, height); }; + // Add event listener for the resize event on(window, 'resize', handler); + // Cleanup function to remove the event listener when the component is unmounted (it's for performance optimization) return () => { off(window, 'resize', handler); }; } }, []); + // Return the current window size (width and height) return state; }; diff --git a/stories/useWindowSize.story.tsx b/stories/useWindowSize.story.tsx index 663b483a69..3265057d1c 100644 --- a/stories/useWindowSize.story.tsx +++ b/stories/useWindowSize.story.tsx @@ -1,10 +1,14 @@ import { storiesOf } from '@storybook/react'; import * as React from 'react'; import { useWindowSize } from '../src'; +import { action } from '@storybook/addon-actions'; // Import addon-actions import ShowDocs from './util/ShowDocs'; const Demo = () => { - const { width, height } = useWindowSize(); + const { width, height } = useWindowSize({ + // Log the resize event to the Storybook actions panel + onChange: action('window resize'), + }); return (