use-element-dimensions
Version:
React Hook to figure out DOM Element dimensions with updates
74 lines (70 loc) • 2.7 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react')) :
typeof define === 'function' && define.amd ? define(['react'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.useDimensions = factory(global.React));
}(this, (function (react) { 'use strict';
var isServer = typeof window === "undefined";
var isSupported = !isServer && "ResizeObserver" in window;
var noop = function () { };
var noopObserver = { observe: noop, unobserve: noop };
var resizeObserver = !isSupported
? noopObserver
: new ResizeObserver(function (entries) {
for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
var entry = entries_1[_i];
var target = entry.target;
var boundingClient = target.getBoundingClientRect();
var set = target.$$useElementDimensionsSet;
if (set) {
set(Object.assign(boundingClient, entry));
}
}
});
var useIsomorphicLayoutEffect = isServer ? react.useEffect : react.useLayoutEffect;
// NOTE(danielkov): this is used to stub DOMRectReadonly on the server
var Rect = /** @class */ (function () {
function Rect() {
this.bottom = 0;
this.height = 0;
this.left = 0;
this.right = 0;
this.top = 0;
this.width = 0;
this.x = 0;
this.y = 0;
}
Rect.prototype.toJSON = function () {
return JSON.stringify(this);
};
return Rect;
}());
var contentRect = new Rect();
var domRect = new Rect();
var size = { inlineSize: 0, blockSize: 0 };
var defaultValue = Object.assign(domRect, {
contentBoxSize: size,
borderBoxSize: size,
contentRect: contentRect,
target: null,
});
var useDimensions = function () {
var ref = react.useRef(null);
var _a = react.useState(defaultValue), dimensions = _a[0], set = _a[1];
var setRef = react.useCallback(function (element) {
if (ref.current) {
resizeObserver.unobserve(ref.current);
}
if (element instanceof Element) {
element.$$useElementDimensionsSet = set;
resizeObserver.observe(element);
}
}, []);
useIsomorphicLayoutEffect(function () { return function () {
if (ref.current) {
resizeObserver.unobserve(ref.current);
}
}; }, []);
return [dimensions, setRef];
};
return useDimensions;
})));