| [a762898] | 1 | import { useCallback, useState } from 'react';
|
|---|
| 2 | var EPS = 1;
|
|---|
| 3 |
|
|---|
| 4 | /**
|
|---|
| 5 | * TODO this documentation does not reflect what this hook is doing, update it.
|
|---|
| 6 | * Stores the `offsetHeight`, `offsetLeft`, `offsetTop`, and `offsetWidth` of a DOM element.
|
|---|
| 7 | */
|
|---|
| 8 |
|
|---|
| 9 | /**
|
|---|
| 10 | * Use this to listen to element layout changes.
|
|---|
| 11 | *
|
|---|
| 12 | * Very useful for reading actual sizes of DOM elements relative to the viewport.
|
|---|
| 13 | *
|
|---|
| 14 | * @param extraDependencies use this to trigger new DOM dimensions read when any of these change. Good for things like payload and label, that will re-render something down in the children array, but you want to read the layout box of a parent.
|
|---|
| 15 | * @returns [lastElementOffset, updateElementOffset] most recent value, and setter. Pass the setter to a DOM element ref like this: `<div ref={updateElementOffset}>`
|
|---|
| 16 | */
|
|---|
| 17 | export function useElementOffset() {
|
|---|
| 18 | var extraDependencies = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|---|
| 19 | var [lastBoundingBox, setLastBoundingBox] = useState({
|
|---|
| 20 | height: 0,
|
|---|
| 21 | left: 0,
|
|---|
| 22 | top: 0,
|
|---|
| 23 | width: 0
|
|---|
| 24 | });
|
|---|
| 25 | var updateBoundingBox = useCallback(node => {
|
|---|
| 26 | if (node != null) {
|
|---|
| 27 | var rect = node.getBoundingClientRect();
|
|---|
| 28 | var box = {
|
|---|
| 29 | height: rect.height,
|
|---|
| 30 | left: rect.left,
|
|---|
| 31 | top: rect.top,
|
|---|
| 32 | width: rect.width
|
|---|
| 33 | };
|
|---|
| 34 | if (Math.abs(box.height - lastBoundingBox.height) > EPS || Math.abs(box.left - lastBoundingBox.left) > EPS || Math.abs(box.top - lastBoundingBox.top) > EPS || Math.abs(box.width - lastBoundingBox.width) > EPS) {
|
|---|
| 35 | setLastBoundingBox({
|
|---|
| 36 | height: box.height,
|
|---|
| 37 | left: box.left,
|
|---|
| 38 | top: box.top,
|
|---|
| 39 | width: box.width
|
|---|
| 40 | });
|
|---|
| 41 | }
|
|---|
| 42 | }
|
|---|
| 43 | },
|
|---|
| 44 | // eslint-disable-next-line react-hooks/exhaustive-deps
|
|---|
| 45 | [lastBoundingBox.width, lastBoundingBox.height, lastBoundingBox.top, lastBoundingBox.left, ...extraDependencies]);
|
|---|
| 46 | return [lastBoundingBox, updateBoundingBox];
|
|---|
| 47 | } |
|---|