codexmobile-relay / client /src /hooks /useViewportMetrics.js
Codex
deploy: CodexMobile Relay
90f0300
Raw
History Blame Contribute Delete
1.82 kB
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;
};
}, []);
}