# All files / src useElementSize.ts

100% Statements 83/83
100% Branches 5/5
100% Functions 1/1
100% Lines 83/83

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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    841x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    21x
    21x
    21x
    21x
    21x
    10x
    1x
    1x
    9x
    9x
    9x
    9x
    9x
    9x
    10x
    10x
    21x
    21x
    21x
    21x
    8x
    8x
    8x
    8x
    8x
    8x
    21x
    21x
    21x
    21x
    21x
    21x
    21x
    21x
     "use client";
    import { useCallback, useState, type RefCallback } from "react";
    import { type ElementSize, type UseStateInitializer } from "./types.js";
    import {
      useResizeObserver,
      type ResizeObserverHookOptions,
    } from "./useResizeObserver.js";

    /**
     * @remarks \@since 6.0.0
     */
    export interface ElementSizeOptions<E extends HTMLElement>
      extends Omit<ResizeObserverHookOptions<E>, "onUpdate"> {
      /** @defaultValue `{ height: 0, width: 0 }` */
      defaultValue?: UseStateInitializer<ElementSize>;
    }

    /**
     * @remarks \@since 6.0.0
     */
    export interface ElementSizeImplementation<E extends HTMLElement>
      extends ElementSize {
      elementRef: RefCallback<E>;
    }

    /**
     * A small wrapper around the {@link useResizeObserver} hook to calculate the
     * element's size.
     *
     * @example
     * Simple Example
     * ```tsx
     * import { useElementSize } from "@react-md/core";
     * import { type ReactElement } from "react";
     *
     * function Example(): ReactElement {
     *   const { height, width, elementRef } = useElementSize();
     *
     *   return (
     *     <div ref={elementRef}>
     *       {`height: ${height}, width: ${width}`}
     *     </div>
     *   );
     * }
     * ```
     *
     * @remarks \@since 6.0.0
     */
    export function useElementSize<E extends HTMLElement>(
      options: ElementSizeOptions<E> = {}
    ): ElementSizeImplementation<E> {
      const { defaultValue } = options;

      const [size, setSize] = useState<ElementSize>(() => {
        if (typeof defaultValue === "function") {
          return defaultValue();
        }

        return (
          defaultValue ?? {
            height: 0,
            width: 0,
          }
        );
      });

      const elementRef = useResizeObserver({
        ...options,
        onUpdate: useCallback((entry) => {
          const size = entry.borderBoxSize[0];

          setSize({
            height: size.blockSize,
            width: size.inlineSize,
          });
        }, []),
      });

      return {
        ...size,
        elementRef,
      };
    }