All files / src/utils useDeviceInfo.ts

5% Statements 1/20
0% Branches 0/11
0% Functions 0/4
5% Lines 1/20

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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88                                                                          1x                                                                                                    
import { useMediaQuery } from 'react-responsive';
 
export type DeviceType = 'desktop' | 'tablet' | 'mobile';
export type DeviceOrientation = 'portrait' | 'landscape';
 
/**
 * Device widths categorized for our purposes.
 * Device widths
 * desktop width > 1023
 * tablet width = 1023 - 768
 * mobile width = < 768
 */
 
type DeviceChangeCallback = () => void;
 
type DeviceInfoProps = {
  onChange?: DeviceChangeCallback;
};
 
/**
 * This function returns properties on device type.
 *
 * {
 * type: 'desktop' | 'tablet' | 'mobile',
 * orientation: 'portrait' | 'landscape',
 * isDesktop: <boolean>,
 * isTablet: <boolean>,
 * isMobile: <boolean>,
 * isRetina: <boolean>,
 * }
 *
 * Clients can use whichever properties they see fit.
 *
 * This function also acceps a callback function to be called
 * if there's a change in any of our interested device properties.
 */
 
const useDeviceInfo = ({ onChange }: DeviceInfoProps = {}) => {
  const deviceChangeCallback = (matches: boolean) => {
    if (matches && onChange) {
      onChange();
    }
  };
 
  const isDesktop = useMediaQuery({ minWidth: 1024 }, undefined, deviceChangeCallback);
 
  const isTablet = useMediaQuery({ maxWidth: 1023, minWidth: 768 }, undefined, deviceChangeCallback);
 
  const isMobile = useMediaQuery({ maxWidth: 767 }, undefined, deviceChangeCallback);
 
  const isPortrait = useMediaQuery({ orientation: 'portrait' }, undefined, deviceChangeCallback);
 
  const isRetina = useMediaQuery({ query: '(min-resolution: 2dppx)' }, undefined, deviceChangeCallback);
 
  const getDeviceType = (): DeviceType => {
    if (isTablet) {
      return 'tablet';
    }
 
    if (isMobile) {
      return 'mobile';
    }
 
    return 'desktop';
  };
 
  const getDeviceOrientation = (): DeviceOrientation => {
    if (isPortrait) {
      return 'portrait';
    }
 
    return 'landscape';
  };
 
  return {
    type: getDeviceType(),
    orientation: getDeviceOrientation(),
    isRetina,
    isDesktop,
    isTablet,
    isMobile,
    isPortrait,
    isLandscape: !isPortrait,
  };
};
 
export default useDeviceInfo;