summaryrefslogtreecommitdiffhomepage
path: root/desktop/packages/mullvad-vpn/src/renderer/hooks/useMeasure.ts
blob: fafb1066c106a68cc1f62c1ee033ea2c0cbbc620 (plain)
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
import { RefCallback, useCallback, useLayoutEffect, useState } from 'react';

export interface MeasureSize {
  width: number;
  height: number;
}

export function useMeasure<T extends Element = HTMLElement>(): [RefCallback<T>, MeasureSize] {
  const [size, setSize] = useState<MeasureSize>({ width: 0, height: 0 });
  const [node, setNode] = useState<T | null>(null);

  const ref: RefCallback<T> = useCallback((instance: T | null) => {
    setNode(instance);
  }, []);

  useLayoutEffect(() => {
    if (!node) return;

    const measure = () => {
      window.requestAnimationFrame(() => {
        const rect = node.getBoundingClientRect();
        setSize({ width: rect.width, height: rect.height });
      });
    };

    measure();

    const resizeObserver = new ResizeObserver(measure);
    resizeObserver.observe(node);

    return () => {
      resizeObserver.disconnect();
    };
  }, [node]);

  return [ref, size];
}