import { useEffect, useState } from 'react'; import breakpoints from '@digigov/css/screens.json' with { type: 'json' }; export type Breakpoints = 'xs' | 'sm' | 'md' | 'lg' | 'xl'; export const breakpointKeys: Breakpoints[] = Object.keys( breakpoints ) as Breakpoints[]; export const breakpointValues = Object.values(breakpoints) as number[]; function resolveScreenSize(width: number): Breakpoints { let breakpointIndex = 0; for (const breakpoint of breakpointValues) { if (width >= breakpoint && width < breakpointValues[breakpointIndex + 1]) { return breakpointKeys[breakpointIndex]; } breakpointIndex++; } return 'xl'; } const listeners = new Set<(width: number) => void>(); let resizeObserver: ResizeObserver | null = null; function createResizeObserver() { if (resizeObserver === null && typeof window !== 'undefined') { resizeObserver = new ResizeObserver(([body]) => { listeners.forEach((listener) => { listener(body.contentRect.width); }); }); resizeObserver.observe(window.document?.body); } return listeners; } export const useScreenSize = () => { const [screenSize, setSize] = useState( resolveScreenSize( typeof window !== 'undefined' ? window.document.body.clientWidth : 0 ) ); useEffect(() => { const listeners = createResizeObserver(); const listener = (width: number) => { setSize(resolveScreenSize(width)); }; listeners.add(listener); return () => { listeners.delete(listener); }; }, []); return { screenSize, screenWidth: typeof window !== 'undefined' && window.document.body.clientWidth, }; }; export default useScreenSize;