diff --git a/library/hooks/package.json b/library/hooks/package.json index 6f45663..8b4f29f 100644 --- a/library/hooks/package.json +++ b/library/hooks/package.json @@ -1,7 +1,7 @@ { "name": "@w3ux/hooks-source", "license": "GPL-3.0-only", - "version": "1.2.0", + "version": "1.2.1-beta.0", "type": "module", "scripts": { "clear": "rm -rf node_modules dist tsconfig.tsbuildinfo", diff --git a/library/hooks/src/index.ts b/library/hooks/src/index.ts index e906603..9534568 100644 --- a/library/hooks/src/index.ts +++ b/library/hooks/src/index.ts @@ -2,5 +2,6 @@ SPDX-License-Identifier: GPL-3.0-only */ export * from "./useEffectIgnoreInitial"; +export * from "./useOnResize"; export * from "./useOutsideAlerter"; export * from "./useSize"; diff --git a/library/hooks/src/useOnResize.tsx b/library/hooks/src/useOnResize.tsx new file mode 100644 index 0000000..5224050 --- /dev/null +++ b/library/hooks/src/useOnResize.tsx @@ -0,0 +1,40 @@ +import { MutableRefObject, useEffect, useRef } from "react"; + +interface UseOnResizeOptions { + outerElement?: MutableRefObject; + throttle?: number; +} + +// Hook to execute a callback function on window resize, with optional throttling. +export const useOnResize = ( + callback: () => void, + options: UseOnResizeOptions = {} +) => { + const { outerElement, throttle: throttleDuration = 100 } = options; + const lastExecutedRef = useRef(0); + + // Throttled resize handler + const handleResize = () => { + const now = Date.now(); + if (now - lastExecutedRef.current < throttleDuration) { + return; + } + + lastExecutedRef.current = now; + callback(); + }; + + useEffect(() => { + // Determine the target for the resize event listener. + // If `outerElement` is provided, listen to its resize events; otherwise, listen to the window's. + const listenFor = outerElement?.current || window; + + // Add event listener for resize on mount. + listenFor.addEventListener("resize", handleResize); + + // Clean up event listener on unmount. + return () => { + listenFor.removeEventListener("resize", handleResize); + }; + }, [throttleDuration, callback]); +};