UNPKG

@react-awesome/use-breakpoint

Version:

useBreakpoint triggers callback when a container's size is equal to one specific breakpoint.

97 lines (96 loc) 3.12 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const react = require("react"); const smaller = require("../helpers/smaller/smaller.cjs"); const smallerOrEqual = require("../helpers/smallerOrEqual/smallerOrEqual.cjs"); const greater = require("../helpers/greater/greater.cjs"); const greaterOrEqual = require("../helpers/greaterOrEqual/greaterOrEqual.cjs"); const between = require("../helpers/between/between.cjs"); const DEFAULT_BREAKPOINTS = { sm: 640, md: 768, lg: 1024, xl: 1280, "2xl": 1536 }; function useBreakpoint(opts = {}) { const { breakpoints: BPS = DEFAULT_BREAKPOINTS, callbacks, fallbackValue, containerEl } = opts; const [currentBreakpoint, setCurrentBreakpoint] = react.useState(fallbackValue); const [el, setEl] = react.useState(null); const BPS_VALUES_ARR = react.useMemo( () => Object.values(BPS).sort((a, b) => a - b), [BPS] ); const BPS_BY_KEYS = react.useMemo( () => Object.keys(BPS).reduce((obj, key) => { const bpKey = BPS[key]; if (obj[bpKey]) { throw new Error( `Found two breakpoints has the same value: ${obj[bpKey]} and ${key}` ); } obj[bpKey] = key; return obj; }, {}), [BPS] ); const determineCurrentBreakpoint = react.useCallback( ({ width }) => { let currentBp = BPS_VALUES_ARR[0]; for (let i = 0; i < BPS_VALUES_ARR.length; i++) { currentBp = BPS_VALUES_ARR[i]; if (i === 0 && width <= currentBp) { setCurrentBreakpoint(BPS_BY_KEYS[currentBp.toString()]); break; } else if (width > BPS_VALUES_ARR[i - 1] && width <= currentBp) { setCurrentBreakpoint(BPS_BY_KEYS[currentBp.toString()]); break; } else if (i + 1 === BPS_VALUES_ARR.length && width > currentBp) { setCurrentBreakpoint(BPS_BY_KEYS[currentBp.toString()]); break; } } return BPS_BY_KEYS[currentBp]; }, [BPS_BY_KEYS, BPS_VALUES_ARR] ); react.useEffect(() => { if (typeof containerEl === "undefined") setEl(window.document.body); else if (containerEl !== el) setEl(containerEl); }, [containerEl, el]); react.useEffect(() => { if (!el) return; const callback = (entries) => { var _a; const [entry] = entries; const { width, height } = entry.contentRect; const currentBp = determineCurrentBreakpoint({ width, height }); (_a = callbacks == null ? void 0 : callbacks[currentBp]) == null ? void 0 : _a.call(callbacks); }; const resizeObserver = new ResizeObserver(callback); resizeObserver.observe(el); return () => { resizeObserver.disconnect(); }; }, [callbacks, determineCurrentBreakpoint, el]); return { currentBreakpoint, smaller: smaller.smaller(BPS, el), smallerOrEqual: smallerOrEqual.smallerOrEqual(BPS, el), greater: greater.greater(BPS, el), greaterOrEqual: greaterOrEqual.greaterOrEqual(BPS, el), between: between.between(BPS, el) }; } exports.useBreakpoint = useBreakpoint;