UNPKG

@kiwicom/orbit-components

Version:

Orbit-components is a React component library which provides developers with the easiest possible way of building Kiwi.com’s products.

97 lines (82 loc) 3.1 kB
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } import { useState, useEffect } from "react"; import useTheme from "./useTheme"; import { getBreakpointWidth } from "../utils/mediaQuery/index"; const debounce = (callback, time) => { let interval; return (...args) => { clearTimeout(interval); interval = setTimeout(() => { callback(...args); }, time); }; }; const useMediaQuery = () => { const theme = useTheme(); const [breakpointList, setBreakpointList] = useState([{ media: getBreakpointWidth("largeDesktop", theme), mapping: "isLargeDesktop", matches: null }, { media: getBreakpointWidth("desktop", theme), mapping: "isDesktop", matches: null }, { media: getBreakpointWidth("largeMobile", theme), mapping: "isLargeMobile", matches: null }, { media: getBreakpointWidth("mediumMobile", theme), mapping: "isMediumMobile", matches: null }, { media: getBreakpointWidth("tablet", theme), mapping: "isTablet", matches: null }]); let mediaList = []; if (typeof window !== "undefined") { // Tie listener to all MediaQueryList items mediaList = breakpointList.map(breakpoint => window.matchMedia(breakpoint.media)); } const findMatch = (mediaToMatch, list) => { const regex = /\d+/; // $FlowFixMe const res = list.find(el => el.media.match(regex)[0] === mediaToMatch.match(regex)[0]); if (res) { return res.matches; } return null; }; const updateMatch = () => { setBreakpointList(breakpointList.map(breakpoint => { return _objectSpread({}, breakpoint, { matches: findMatch(breakpoint.media, mediaList) }); })); }; useEffect(() => { if (typeof window !== "undefined") { // Initial value updateMatch(); // Tie listener to all MediaQueryList items mediaList.forEach(mediaListItem => mediaListItem.addListener(debounce(updateMatch, 150))); } return () => { if (typeof window !== "undefined") { // cleanup mediaList.forEach(mediaListItem => mediaListItem.removeListener(updateMatch)); } }; }, []); // Flatten to object and return const exportObj = Object.assign({ isDesktop: null, isLargeDesktop: null, isTablet: null, isLargeMobile: null, isMediumMobile: null }, ...breakpointList.map(item => ({ [item.mapping]: item.matches }))); return exportObj; }; export default useMediaQuery;