@shopgate/engage
Version:
Shopgate's ENGAGE library.
26 lines • 3.83 kB
JavaScript
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;}