# All files / src useWindowSize.ts

100% Statements 125/125
100% Branches 13/13
100% Functions 1/1
100% Lines 125/125

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
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    1261x
    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
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    61x
    61x
    61x
    61x
    61x
    61x
    61x
    61x
    61x
    61x
    61x
    61x
    61x
    61x
    9x
    4x
    4x
    4x
    4x
    4x
    5x
    5x
    5x
    5x
    5x
    5x
    61x
    61x
    61x
    61x
    61x
    61x
    61x
    61x
    61x
    9x
    9x
    9x
    9x
    9x
    9x
    9x
    9x
    9x
    9x
    9x
    9x
    9x
    61x
    61x
    61x
    61x
    61x
     "use client";
    import { useCallback, useState } from "react";
    import { useSsr } from "./SsrProvider.js";
    import { type ElementSize } from "./types.js";
    import {
      useResizeListener,
      type ResizeListenerOptions,
    } from "./useResizeListener.js";

    /**
     * @remarks \@since 6.0.0
     */
    export interface WindowSizeOptions
      extends Omit<ResizeListenerOptions, "disabled" | "onUpdate"> {
      /**
       * The default value to use in SSR environments for the window's height.
       *
       * @defaultValue `0`
       */
      ssrHeight?: number;

      /**
       * The default value to use in SSR environments for the window's width.
       *
       * @defaultValue `0`
       */
      ssrWidth?: number;

      /**
       * Set this to `true` to ignore resize events that only updated the height.
       * The hook can be disabled by setting this and {@link disableWidth} to
       * `true`.
       *
       * @defaultValue `false`
       */
      disableHeight?: boolean;

      /**
       * Set this to `true` to ignore resize events that only updated the width.
       * The hook can be disabled by setting this and {@link disableHeight} to
       * `true`.
       *
       * @defaultValue `false`
       */
      disableWidth?: boolean;
    }

    /**
     * This is just a convenience wrapper around the {@link useResizeListener}.
     *
     * @example
     * Simple Example
     * ```tsx
     * import { useWindowSize } from "@react-md/core";
     * import type { ReactElement } from "react";
     * import { useState } from "react";
     *
     * function Example(): ReactElement {
     *   const { height, width } = useWindowSize();
     *
     *   return (
     *     <>
     *       The current window size:
     *       <pre><code>{JSON.stringify(size, null, 2)}</code></pre>
     *     </>
     *   );
     * }
     * ```
     *
     * @remarks \@since 6.0.0
     */
    export function useWindowSize(options: WindowSizeOptions = {}): ElementSize {
      const {
        once,
        signal,
        capture,
        passive,
        throttle,
        ssrHeight = 0,
        ssrWidth = 0,
        disableWidth,
        disableHeight,
      } = options;

      const ssr = useSsr();
      const [size, setSize] = useState(() => {
        if (typeof window === "undefined" || ssr) {
          return {
            height: ssrHeight,
            width: ssrWidth,
          };
        }

        return {
          height: window.innerHeight,
          width: window.innerWidth,
        };
      });

      useResizeListener({
        once,
        signal,
        capture,
        passive,
        throttle,
        disabled: disableHeight && disableWidth,
        onUpdate: useCallback(() => {
          setSize((prevSize) => {
            const nextSize: ElementSize = {
              height: window.innerHeight,
              width: window.innerWidth,
            };

            const isHeightChange =
              !disableHeight && prevSize.height !== nextSize.height;
            const isWidthChange =
              !disableWidth && prevSize.width !== nextSize.width;

            return isHeightChange || isWidthChange ? nextSize : prevSize;
          });
        }, [disableHeight, disableWidth]),
      });

      return size;
    }