diff --git a/src/components/utils/useViewportSize/__tests__/useViewportSize.test.tsx b/src/components/utils/useViewportSize/__tests__/useViewportSize.test.tsx new file mode 100644 index 000000000..8b5c5a742 --- /dev/null +++ b/src/components/utils/useViewportSize/__tests__/useViewportSize.test.tsx @@ -0,0 +1,25 @@ +import {act, fireEvent, renderHook} from '@testing-library/react'; + +import {useViewportSize} from '..'; + +test('Check useViewportSize correct work', () => { + const view = renderHook(() => useViewportSize()); + + act(() => { + window.innerHeight = 500; + window.innerWidth = 500; + }); + + fireEvent(window, new Event('resize')); + + expect(view.result.current).toEqual({height: 500, width: 500}); + + act(() => { + window.innerHeight = 1200; + window.innerWidth = 1200; + }); + + fireEvent(window, new Event('resize')); + + expect(view.result.current).toEqual({height: 1200, width: 1200}); +}); diff --git a/src/components/utils/useViewportSize/index.ts b/src/components/utils/useViewportSize/index.ts new file mode 100644 index 000000000..35c194400 --- /dev/null +++ b/src/components/utils/useViewportSize/index.ts @@ -0,0 +1,2 @@ +export {useViewportSize} from './useViewportSize'; +export type {ViewportSize} from './useViewportSize'; diff --git a/src/components/utils/useViewportSize/useViewportSize.tsx b/src/components/utils/useViewportSize/useViewportSize.tsx new file mode 100644 index 000000000..f481c32b1 --- /dev/null +++ b/src/components/utils/useViewportSize/useViewportSize.tsx @@ -0,0 +1,38 @@ +import React from 'react'; + +export interface ViewportSize { + width?: number; + height?: number; +} + +const getViewportSize = (): ViewportSize => ({ + width: window?.visualViewport?.width ?? window?.innerWidth ?? undefined, + height: window?.visualViewport?.height ?? window?.innerHeight ?? undefined, +}); + +/** + * A hook to get the size of the viewport when resizing + * + * @return - {width, height} + */ +export const useViewportSize = (): ViewportSize => { + const [size, setSize] = React.useState(getViewportSize()); + + React.useEffect(() => { + const onResize = () => { + let newSize = getViewportSize(); + if (newSize.width === size?.width && newSize.height === size?.height) { + newSize = size; + } + setSize(newSize); + }; + + (window.visualViewport ?? window).addEventListener('resize', onResize); + + return () => { + (window.visualViewport ?? window).removeEventListener('resize', onResize); + }; + }, [size]); + + return size; +};