Last active
July 16, 2024 21:57
-
-
Save MartijnHols/e9f4f787efa9190885a708468f63c5bb to your computer and use it in GitHub Desktop.
React hooks for getting the document height that updates when the On Screen Keyboard/Virtual Keyboard toggles
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The latest version is available at https://martijnhols.nl/gists/how-to-get-document-height-ios-safari-osk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useEffect } from 'react' | |
const useOnScreenKeyboardScrollFix = () => { | |
useEffect(() => { | |
const handleScroll = () => { | |
window.scrollTo(0, 0) | |
} | |
window.addEventListener('scroll', handleScroll) | |
return () => { | |
window.removeEventListener('scroll', handleScroll) | |
} | |
}, []) | |
} | |
export default useOnScreenKeyboardScrollFix |
You might need a few timeouts like I did in the useViewportSize
hook, but that will be kind of ugly for the user. Luckily it will only be ugly for the crazy browsers.
// Closing the OSK in iOS does not immediately update the visual viewport
// size :<
setTimeout(updateViewportSize, 1000)
One nice thing is that since you're setting scroll position to 0 every time, you can fairly easily start multiple timeouts without the user noticing.
It seems to work if I adjust the maxHeight instead of the height and it has a h-full class from tailwind ( which is just height:100% )
import { ElementType, HTMLAttributes } from "react";
import useViewportSize from "@/hooks/useViewportSize";
import useOnScreenKeyboardScrollFix from "@/hooks/useOnScreenKeyboardScrollFix";
import usePreventOverScrolling from "@/hooks/usePreventOverScrolling";
import useIsOnScreenKeyboardOpen from "@/hooks/useOnScreenKeyboardOpen";
interface Props extends HTMLAttributes<HTMLDivElement> {
element?: ElementType;
}
export function FullViewportContainer({
element: Element = "div",
...others
}: Props) {
useOnScreenKeyboardScrollFix();
const [, viewportHeight] = useViewportSize() ?? [];
const ref = usePreventOverScrolling();
const isOnScreenKeyboardOpen = useIsOnScreenKeyboardOpen();
return (
<Element
{...others}
ref={ref}
className="w-full h-full"
style={{
maxHeight: viewportHeight,
padding: isOnScreenKeyboardOpen
? "env(safe-area-inset-top) env(safe-area-inset-right) 0 env(safe-area-inset-left)"
: "env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)",
transition: "padding 100ms, height 100ms",
}}
/>
);
}
Aaaand it must be the direct children of the root it seems
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have added this line
So it always scrolls to 0 if the viewportHeight changes but it also doesnt work.
Browser is standard android google chrome btw