All files / libs/ext/react/hooks/src/lib/use-resize-observer useResizeObserver.ts

0% Statements 0/42
0% Branches 0/1
0% Functions 0/1
0% Lines 0/42

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43                                                                                     
import { useEffect, useMemo, useState, type RefCallback } from 'react';

export type UseResizeObserverOptions<TElement extends Element> = {
  onResize: (dimensions: { height: number; width: number }, element: TElement) => void;
};

/**
 * Use this hook to detect when an element resizes.
 *
 * @param params - Params.
 * @param params.element - The element.
 * @param params.onResize - Callback when the element resizes.
 */
export const useResizeObserver = <TElement extends Element>({
  onResize,
}: UseResizeObserverOptions<TElement>): RefCallback<TElement> => {
  const [element, setElement] = useState<TElement | null>(null);

  const resizeObserver = useMemo(
    () =>
      new ResizeObserver(([target]) => {
        const { blockSize: height, inlineSize: width } = target.borderBoxSize[0];
        onResize({ height, width }, target.target as TElement);
      }),
    [onResize],
  );

  useEffect(() => {
    if (element) {
      resizeObserver.observe(element);

      return () => {
        onResize({ height: 0, width: 0 }, element);
        resizeObserver.disconnect();
      };
    }

    return undefined;
  }, [element, onResize, resizeObserver]);

  return setElement;
};