@vimeo/iris
Version:
Vimeo Design System
60 lines (57 loc) • 2.47 kB
JavaScript
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 };