Spaces:
Running
Running
| import { useEffect } from 'react'; | |
| export function useViewportMetrics() { | |
| useEffect(() => { | |
| const root = document.documentElement; | |
| let frame = 0; | |
| const updateViewport = () => { | |
| cancelAnimationFrame(frame); | |
| frame = requestAnimationFrame(() => { | |
| const viewport = window.visualViewport; | |
| const height = Math.round(viewport?.height || window.innerHeight || 0); | |
| const width = Math.round(viewport?.width || window.innerWidth || 0); | |
| const layoutHeight = Math.round(document.documentElement.clientHeight || window.innerHeight || 0); | |
| const keyboardOpen = height > 0 && layoutHeight > 0 && layoutHeight - height > 120; | |
| if (height > 0) { | |
| root.style.setProperty('--app-height', `${height}px`); | |
| } | |
| if (width > 0) { | |
| root.style.setProperty('--app-width', `${width}px`); | |
| } | |
| root.dataset.keyboard = keyboardOpen ? 'open' : 'closed'; | |
| if (window.scrollX || window.scrollY) { | |
| window.scrollTo(0, 0); | |
| } | |
| }); | |
| }; | |
| updateViewport(); | |
| window.visualViewport?.addEventListener('resize', updateViewport); | |
| window.visualViewport?.addEventListener('scroll', updateViewport); | |
| window.addEventListener('resize', updateViewport); | |
| window.addEventListener('orientationchange', updateViewport); | |
| return () => { | |
| cancelAnimationFrame(frame); | |
| window.visualViewport?.removeEventListener('resize', updateViewport); | |
| window.visualViewport?.removeEventListener('scroll', updateViewport); | |
| window.removeEventListener('resize', updateViewport); | |
| window.removeEventListener('orientationchange', updateViewport); | |
| root.style.removeProperty('--app-height'); | |
| root.style.removeProperty('--app-width'); | |
| delete root.dataset.keyboard; | |
| }; | |
| }, []); | |
| } | |