fix: hide navigation on keyboard visible
All checks were successful
Deploy to VPS (dist) / deploy (push) Successful in 1m32s

This commit is contained in:
Hewston Fox
2026-03-22 17:21:14 +02:00
parent 31d7eaf6ac
commit e5b3b97680
4 changed files with 97 additions and 17 deletions

View File

@@ -76,6 +76,10 @@
pointer-events: none;
}
.hidden {
display: none;
}
.menuOverlay > * {
pointer-events: auto;
}

View File

@@ -1,6 +1,7 @@
import { type AnyRoute, useMatchRoute, useNavigate } from "@tanstack/react-router";
import { useTranslation } from "react-i18next";
import { AnimatePresence } from "motion/react";
import { useCallback, useEffect, useRef, useState } from "react";
import GlassSurface from "@components/surface/GlassSurface";
@@ -12,7 +13,6 @@ import CashdeskRoute from "@/routes/cashdesk";
import RouletteRoute from "@/routes/roulette";
import TasksRoute from "@/routes/tasks";
import EarningsRoute from "@/routes/earnings";
import { useCallback, useEffect, useRef, useState } from "react";
import shopIcon from "./assets/shop.svg";
import apiaryIcon from "./assets/apiary.svg";
@@ -51,6 +51,37 @@ const MENU_ITEMS = [
{ key: "nav.earnings", route: EarningsRoute, icon: earningsIcon, delay: 0 },
];
// 200px is larger than any OS chrome resize but smaller than the smallest software keyboard
const KEYBOARD_THRESHOLD = 200;
function useKeyboardVisible(): boolean {
const [keyboardVisible, setKeyboardVisible] = useState(false);
const baselineHeight = useRef<number>(0);
useEffect(() => {
const vv = window.visualViewport;
if (!vv) return;
baselineHeight.current = vv.height;
const handleResize = () => {
const newHeight = vv.height;
if (baselineHeight.current - newHeight > KEYBOARD_THRESHOLD) {
setKeyboardVisible(true);
} else {
setKeyboardVisible(false);
baselineHeight.current = newHeight;
}
};
vv.addEventListener("resize", handleResize);
return () => vv.removeEventListener("resize", handleResize);
}, []);
return keyboardVisible;
}
type BarProps = {
labelKey: string;
icon: string;
@@ -167,6 +198,7 @@ export default function Navigation() {
const navigate = useNavigate();
const [menuOpen, setMenuOpen] = useState<number>(0);
const navRef = useRef<HTMLDivElement>(null);
const keyboardVisible = useKeyboardVisible();
const handleOutsideClick = useCallback((e: MouseEvent) => {
if (navRef.current && !navRef.current.contains(e.target as Node)) {
@@ -193,7 +225,7 @@ export default function Navigation() {
};
return (
<div ref={navRef}>
<div ref={navRef} className={keyboardVisible ? classes.hidden : undefined}>
<div className={classes.menuOverlay}>
<AnimatePresence>
{menuOpen &&