import { useState, useEffect } from 'react'; /** * Hook to detect media query matches * @param query - CSS media query string * @returns boolean indicating if the query matches */ export function useMediaQuery(query: string): boolean { const [matches, setMatches] = useState(false); useEffect(() => { const mediaQuery = window.matchMedia(query); // Set initial value setMatches(mediaQuery.matches); // Create event listener const handler = (event: MediaQueryListEvent) => { setMatches(event.matches); }; // Add listener mediaQuery.addEventListener('change', handler); // Cleanup return () => mediaQuery.removeEventListener('change', handler); }, [query]); return matches; } /** * Hook to detect current breakpoint * @returns current breakpoint name */ export function useBreakpoint() { const isXs = useMediaQuery('(max-width: 639px)'); const isSm = useMediaQuery('(min-width: 640px) and (max-width: 767px)'); const isMd = useMediaQuery('(min-width: 768px) and (max-width: 1023px)'); const isLg = useMediaQuery('(min-width: 1024px) and (max-width: 1279px)'); const isXl = useMediaQuery('(min-width: 1280px) and (max-width: 1535px)'); const is2Xl = useMediaQuery('(min-width: 1536px)'); if (isXs) return 'xs'; if (isSm) return 'sm'; if (isMd) return 'md'; if (isLg) return 'lg'; if (isXl) return 'xl'; if (is2Xl) return '2xl'; return 'lg'; // default } /** * Hook to detect if viewport is mobile size * @returns boolean indicating if viewport is mobile */ export function useIsMobile(): boolean { return useMediaQuery('(max-width: 767px)'); } /** * Hook to detect if viewport is tablet size * @returns boolean indicating if viewport is tablet */ export function useIsTablet(): boolean { return useMediaQuery('(min-width: 768px) and (max-width: 1023px)'); } /** * Hook to detect if viewport is desktop size * @returns boolean indicating if viewport is desktop */ export function useIsDesktop(): boolean { return useMediaQuery('(min-width: 1024px)'); }