UNPKG

@shopgate/engage

Version:
26 lines 3.83 kB
function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}function _slicedToArray(arr,i){return _arrayWithHoles(arr)||_iterableToArrayLimit(arr,i)||_nonIterableRest();}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance");}function _iterableToArrayLimit(arr,i){var _arr=[];var _n=true;var _d=false;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break;}}catch(err){_d=true;_e=err;}finally{try{if(!_n&&_i["return"]!=null)_i["return"]();}finally{if(_d)throw _e;}}return _arr;}function _arrayWithHoles(arr){if(Array.isArray(arr))return arr;}import{useState,useEffect,useRef}from'react';import throttle from'lodash/throttle';/** * @typedef {Object} ElementSize * @property {number} height - The element's height in pixels. * @property {number} [width] - The element's width in pixels (optional). */ /** * @typedef {Object} UseElementSizeOptions * @property {number} [throttleMs=100] - Throttle delay in milliseconds. * @property {boolean} [includeWidth=false] - Whether to measure the element's width. */ /** * Tracks the height (and optionally width) of a DOM element using ResizeObserver, * with a fallback to window resize and MutationObserver in older browsers. * * @param {React.RefObject<HTMLElement>} ref - A ref to the element being measured. * @param {UseElementSizeOptions} [options={}] - Optional settings. * @returns {ElementSize} The current height (and optionally width) of the element. */export default function useElementSize(ref){var options=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var _options$throttleMs=options.throttleMs,throttleMs=_options$throttleMs===void 0?100:_options$throttleMs,_options$includeWidth=options.includeWidth,includeWidth=_options$includeWidth===void 0?false:_options$includeWidth;/** * Holds the current element size in state. */var _useState=useState(_extends({height:0},includeWidth&&{width:0})),_useState2=_slicedToArray(_useState,2),size=_useState2[0],setSize=_useState2[1];/** * Tracks the most recent measured size to prevent unnecessary state updates. */var sizeRef=useRef(size);useEffect(function(){var element=ref.current;if(!element)return undefined;/** * Measures the current size of the element and updates state if it changed. */var updateSize=function updateSize(){var newHeight=element.offsetHeight;var newWidth=includeWidth?element.offsetWidth:undefined;var hasChanged=newHeight!==sizeRef.current.height||includeWidth&&newWidth!==sizeRef.current.width;if(hasChanged){var newSize=_extends({height:newHeight},includeWidth?{width:newWidth}:{});sizeRef.current=newSize;setSize(newSize);}};/** * Throttles the update function to limit how often measurements occur. */var throttledUpdate=throttle(updateSize,throttleMs);/** * Sets up ResizeObserver or fallback observers to trigger measurement. */var cleanup=function cleanup(){};if('ResizeObserver'in window){var resizeObserver=new ResizeObserver(throttledUpdate);resizeObserver.observe(element);updateSize();cleanup=function cleanup(){resizeObserver.disconnect();throttledUpdate.cancel();};}else{window.addEventListener('resize',throttledUpdate);var mutationObserver=new MutationObserver(throttledUpdate);mutationObserver.observe(element,{childList:true,subtree:true,characterData:true});updateSize();cleanup=function cleanup(){window.removeEventListener('resize',throttledUpdate);mutationObserver.disconnect();throttledUpdate.cancel();};}return cleanup;},[ref,throttleMs,includeWidth]);return size;}