@zohodesk/hooks
Version:
Unified Component Library - Hooks
64 lines (59 loc) • 2.49 kB
JavaScript
/**
* https://npm.io/package/react-cool-dimensions
* https://github.com/juggle/resize-observer
* https://npm.io/package/react-measure
* https://web.dev/resize-observer/
* https://web.dev/avoid-large-complex-layouts-and-layout-thrashing/
* https://github.com/wilsonpage/fastdom
* https://www.npmjs.com/package/react-matches
*
*
* Choosen Library with performance of one observer
* https://npm.io/package/@envato/react-breakpoints , https://github.com/envato/react-resize-observer-hook/
* https://github.com/envato/react-breakpoints
* https://github.com/envato/react-breakpoints/blob/main/docs/api.md
* https://github.com/envato/react-breakpoints/blob/main/docs/boxSizes.md
*
*/
import React, { useRef, useState, useCallback } from 'react';
import getMatchedQuery from "./utils/getMatchedQuery";
import isEqualMatchedQuery from "./utils/isEqualMatchedQuery";
import useEvent from "../utils/useEvent";
import useResizeObserver from "../utils/useResizeObserver";
import defaultResolve from "./utils/defaultResolve";
import getObersevedSizes from "./utils/getObersevedSizes";
/**
* data-cq-initalized - used firstime render without jerking the ui. no need to wait for Observer calc.
* @param {*} query { 'XS' : { minWidth, maxHeight } , 'SM' : { maxWidth } }
* @param {*} options
* @returns
*/
export default function useContainerQuery(getElement) {
let query = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
let resolveCallback = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : defaultResolve;
const matchedRef = useRef(null);
const [matchedQuery, setMatchedQuery] = useState(null);
const handleResize = useEvent(observedEntry => {
const observedBoxSize = getObersevedSizes(options, observedEntry);
const currentMatchedQuery = getMatchedQuery(query, observedBoxSize);
if (!isEqualMatchedQuery(matchedRef.current, currentMatchedQuery)) {
resolveCallback(observedEntry.target, query, currentMatchedQuery);
matchedRef.current = currentMatchedQuery;
setMatchedQuery(currentMatchedQuery);
}
});
useResizeObserver({
getElement,
callback: handleResize,
isObserve: true,
options
});
return matchedQuery;
}
/**
<Provider>
let [ observeRef , result ] = useContainerQuery( { 'XS' : { minWidth, maxHeight } , 'SM' : { maxWidth } } );
<div ref={observeRef}></div>
</Provider>
*/