hooks/orientation.jsxjavascript
/*
Tracks the physical device/viewport orientation via the CSS
`(orientation: ...)` media feature - the same signal the SCSS mixins
(src/styles/_mixins.scss) react to, so this hook and the stylesheets can
never disagree about which orientation is currently active.
Used by RotateOverlay (src/components/RotateOverlay/RotateOverlay.jsx)
together with useRequiredOrientation (src/services/orientation.js) to
detect when the kiosk is held the "wrong" way for the current route.
*/
import { useState, useEffect } from "react";
const getOrientation = () =>
window.matchMedia("(orientation: portrait)").matches ? "portrait" : "landscape";
/**
* @returns {"landscape"|"portrait"} The current viewport orientation, kept
* in sync live as the device is rotated/resized.
*/
export const useOrientation = () => {
const [orientation, setOrientation] = useState(getOrientation);
useEffect(() => {
const mediaQuery = window.matchMedia("(orientation: portrait)");
const handleChange = () => setOrientation(mediaQuery.matches ? "portrait" : "landscape");
handleChange();
mediaQuery.addEventListener("change", handleChange);
return () => mediaQuery.removeEventListener("change", handleChange);
}, []);
return orientation;
};