UNPKG

@vimeo/iris

Version:
60 lines (57 loc) 2.47 kB
import { _ as __read, e as __spreadArray } from '../../tslib.es6-7f0e734f.js'; import { useRef, useState, cloneElement, useCallback, useLayoutEffect } from 'react'; import { createPortal } from 'react-dom'; import { createPortalOutlet } from '../DOM/createPortalOutlet.esm.js'; import { geometry } from '../DOM/geometry.esm.js'; import { removeElementByID } from '../DOM/removeElementByID.esm.js'; import { SSR } from '../DOM/SSR.esm.js'; import '../DOM/createElement.esm.js'; function useMeasure(Component, _a) { var _b = _a === void 0 ? {} : _a, _c = _b.depth, depth = _c === void 0 ? 0 : _c; var ref = useRef(null); var _d = __read(useState(false), 2), measured = _d[0], measuredSet = _d[1]; var ComponentWithRef = cloneElement(Component, { ref: ref }); var outlet = !measured && createPortalOutlet('measure'); var portal = !measured && createPortal(ComponentWithRef, outlet); var measureElements = useCallback(function () { var _a, _b; if (measured) return; var rect = geometry(ref.current); // TODO: write recursive children depth function for n depth if (depth > 0) { var children = (_b = (depth > 0 && ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.children))) !== null && _b !== void 0 ? _b : []; rect.children = __spreadArray([], __read(children), false).map(function (child) { return geometry(child); }); } // If measureElements() has been called but the elements // have not changed size or postion, return. if (!compareDOMRects(measured, rect)) return; measuredSet(rect); removeElementByID('measure'); }, [depth, measured, ref]); useLayoutEffect(function () { measureElements(); function resize() { measuredSet(false); measureElements(); } window.addEventListener('resize', resize); return function () { return window.removeEventListener('resize', resize); }; }, [measureElements]); if (SSR) return [Component, null]; var render = measured ? Component : portal; return [render, measured]; } function compareDOMRects(a, b) { return (a.width !== b.width || a.height !== b.height || a.left !== b.left || a.top !== b.top || a.bottom !== b.bottom || a.right !== b.right || a.x !== b.x || a.y !== b.y); } export { useMeasure };