From ea656f7e751b8366360ce2aa8238057bbbc1251a Mon Sep 17 00:00:00 2001 From: Mahmoud El-Gammal Date: Mon, 2 Dec 2024 17:02:44 +0200 Subject: [PATCH] feat: add onChange callback to useWindowSize --- src/useWindowSize.ts | 18 +++++++++++++----- stories/useWindowSize.story.tsx | 6 +++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/useWindowSize.ts b/src/useWindowSize.ts index 45f82de7c8..10d9402767 100644 --- a/src/useWindowSize.ts +++ b/src/useWindowSize.ts @@ -3,10 +3,11 @@ import { useEffect } from 'react'; import useRafState from './useRafState'; import { isBrowser, off, on } from './misc/util'; +// Define the type for options that can be passed to the hook interface Options { - initialWidth?: number; - initialHeight?: number; - onChange?: (width: number, height: number) => void; + 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 = ({ @@ -14,33 +15,40 @@ const useWindowSize = ({ 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 (