Hide bottom navigation when virtual keyboard is open

- Added visualViewport API detection for keyboard state
- Bottom nav fades out when keyboard opens (opacity + pointer-events)
- Prevents nav from jumping up with keyboard on mobile
This commit is contained in:
PEDZEO
2026-01-21 02:18:20 +03:00
parent 215a65dbae
commit fb46c84b58

View File

@@ -129,6 +129,7 @@ export default function Layout({ children }: LayoutProps) {
const location = useLocation() const location = useLocation()
const { user, logout, isAdmin, isAuthenticated } = useAuthStore() const { user, logout, isAdmin, isAuthenticated } = useAuthStore()
const [mobileMenuOpen, setMobileMenuOpen] = useState(false) const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
const [isKeyboardOpen, setIsKeyboardOpen] = useState(false)
const { toggleTheme, isDark } = useTheme() const { toggleTheme, isDark } = useTheme()
const [userPhotoUrl, setUserPhotoUrl] = useState<string | null>(null) const [userPhotoUrl, setUserPhotoUrl] = useState<string | null>(null)
const { isFullscreen, safeAreaInset, contentSafeAreaInset } = useTelegramWebApp() const { isFullscreen, safeAreaInset, contentSafeAreaInset } = useTelegramWebApp()
@@ -209,6 +210,26 @@ export default function Layout({ children }: LayoutProps) {
} }
}, [mobileMenuOpen]) }, [mobileMenuOpen])
// Detect virtual keyboard open/close using visualViewport API
useEffect(() => {
const viewport = window.visualViewport
if (!viewport) return
const handleResize = () => {
// Keyboard is considered open if viewport height is significantly smaller than window height
const heightDiff = window.innerHeight - viewport.height
setIsKeyboardOpen(heightDiff > 150)
}
viewport.addEventListener('resize', handleResize)
viewport.addEventListener('scroll', handleResize)
return () => {
viewport.removeEventListener('resize', handleResize)
viewport.removeEventListener('scroll', handleResize)
}
}, [])
// State to track if logo image has loaded // State to track if logo image has loaded
const [logoLoaded, setLogoLoaded] = useState(false) const [logoLoaded, setLogoLoaded] = useState(false)
@@ -629,8 +650,8 @@ export default function Layout({ children }: LayoutProps) {
</main> </main>
{/* Mobile Bottom Navigation - only core items */} {/* Mobile Bottom Navigation - only core items, hidden when keyboard is open */}
<nav className="bottom-nav lg:hidden"> <nav className={`bottom-nav lg:hidden transition-opacity duration-200 ${isKeyboardOpen ? 'opacity-0 pointer-events-none' : 'opacity-100'}`}>
<div className="flex justify-around"> <div className="flex justify-around">
{navItems.filter(item => {navItems.filter(item =>
['/', '/subscription', '/balance', '/referral', '/support'].includes(item.path) ['/', '/subscription', '/balance', '/referral', '/support'].includes(item.path)