# All files / src useOrientation.ts

100% Statements 62/62
100% Branches 17/17
100% Functions 3/3
100% Lines 62/62

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
    631x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    195x
    2x
    2x
    193x
    193x
    193x
    193x
    195x
    3x
    3x
    190x
    190x
    190x
    195x
    195x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    322x
    322x
    177x
    177x
    177x
    177x
    2x
    177x
    175x
    175x
    177x
    177x
    177x
    2x
    177x
    175x
    175x
    177x
    322x
    322x
    322x
    322x
     "use client";
    import { useEffect, useState } from "react";

    /**
     * An extremely simple "polyfill" for the `window.screen.orientation` just for
     * the `type` value that is required for the `useOrientation` hook.
     *
     * @see {@link https://caniuse.com/screen-orientation}
     * @returns the orientation type either from the `window.screen.orientation` or
     * by comparing the `availHeight` and `availWidth` on the `window.screen`
     * @internal
     */
    export const getOrientationType = (): OrientationType => {
      if (typeof window === "undefined") {
        return "landscape-primary";
      }

      // Note: at the time of writing this, it looks like only Safari does not
      // support it from my list of browsers
      const screenOrientation = window.screen.orientation?.type;
      if (typeof screenOrientation === "string") {
        return screenOrientation;
      }

      const { availHeight, availWidth } = window.screen;

      return availHeight > availWidth ? "portrait-primary" : "landscape-primary";
    };

    /**
     * This hook uses the {@link https://developer.mozilla.org/en-US/docs/Web/API/ScreenOrientation} API
     * to determine if the screen is landscape or portrait. For browsers that do not
     * support this API yet, it will polyfill that behavior using a resize handler
     * instead.
     *
     * @internal
     * @see {@link https://caniuse.com/screen-orientation}
     * @returns the current orientation type
     */
    export function useOrientation(): OrientationType {
      const [orientation, setOrientation] = useState(getOrientationType);
      useEffect(() => {
        const handler = (): void => setOrientation(getOrientationType());

        const { orientation } = window.screen;
        if (orientation) {
          orientation.addEventListener("change", handler);
        } else {
          window.addEventListener("resize", handler);
        }

        return () => {
          if (orientation) {
            orientation.removeEventListener("change", handler);
          } else {
            window.removeEventListener("resize", handler);
          }
        };
      }, []);

      return orientation;
    }