ideas icon indicating copy to clipboard operation
ideas copied to clipboard

useBoundingRects

Open aulneau opened this issue 5 years ago • 1 comments

Useful for things like tooltips that need to be aware of their parent and adjust based off of proximity.

import React, { useLayoutEffect, useState } from 'react';

const emptyRect = {
  top: 0,
  right: 0,
  bottom: 0,
  left: 0,
  width: 0,
  height: 0
};

const getRects = el => {
  if (!el)
    return {
      rect: undefined,
      parentRect: undefined
    };

  const parentNode = el.parentNode;

  const rect = el.getBoundingClientRect
    ? el.getBoundingClientRect()
    : emptyRect;

  const parentRect =
    parentNode && parentNode.getBoundingClientRect
      ? parentNode.getBoundingClientRect()
      : emptyRect;

  return { rect, parentRect };
};

export const useBoundingRects = ref => {
  let [{ rect, parentRect }, setRects] = useState(getRects(ref.current));

  const handleResize = () => {
    if (ref && ref.current) {
      setRects(getRects(ref.current));
    }
  };

  useLayoutEffect(() => {
    handleResize();
    window.addEventListener('resize', handleResize);

    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []);

  return [rect, parentRect];
};

aulneau avatar Oct 30 '18 13:10 aulneau

Thanks @aulneau! This gist is like yours, but a copy of component-size hook, with getBoundingClientRect, which uses resize observer (if not available falls back to 'resize' listener). https://gist.github.com/morajabi/523d7a642d8c0a2f71fcfa0d8b3d2846

morajabi avatar Feb 18 '19 14:02 morajabi