All files / frontend/src/hooks useMediaQuery.ts

86.36% Statements 19/22
80% Branches 8/10
100% Functions 5/5
86.36% Lines 19/22

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 321x   1x 19x 18x 18x 18x   19x   19x 18x     18x       18x 18x   18x 19x   19x 19x     1x 1x 1x  
import { useEffect, useState } from 'react';
 
export const useMediaQuery = (query: string): boolean => {
    const [matches, setMatches] = useState(() => {
        if (typeof window !== 'undefined') {
            return window.matchMedia(query).matches;
        }
        return false;
    });
 
    useEffect(() => {
        const media = window.matchMedia(query);
 
        // Update state if initial value doesn't match
        if (media.matches !== matches) {
            setMatches(media.matches);
        }
 
        const listener = (e: MediaQueryListEvent) => setMatches(e.matches);
        media.addEventListener('change', listener);
 
        return () => media.removeEventListener('change', listener);
    }, [query]); // Only depend on query, not matches
 
    return matches;
};
 
// Common breakpoints
export const useIsMobile = () => useMediaQuery('(max-width: 768px)');
export const useIsTablet = () => useMediaQuery('(min-width: 769px) and (max-width: 1024px)');
export const useIsDesktop = () => useMediaQuery('(min-width: 1025px)');