the above shows a video of the issue (expires in 2 days).
but i have a react next js web app, in chrome it works fine but if i use safari or install the web app on android i get an issue where if the keyboard is active via my textArea and then i tap somewhere else, the whole screen zooms in & i lose my nav bar (rendered via _app, should always be anchored to the bottom of the screen).
Here is my code for the textBox
import React, { useState, useRef, useEffect } from 'react';
import styles from "../styles/postCreate.module.css";
import {Input, Textarea} from "@nextui-org/react";
import { postsModule } from "../API/PostsAPI";
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
export default function PostCreate(){
const [isOpen, setOpen] = useState(false);
const [thought, setThought] = useState('');
const [isPosting, setPostLoading] = useState(false);
const [posted, setPosted] = useState(false);
const [isPortrait, setIsPortrait] = useState(false);
const ClearTextArea = () => {
setThought('');
};
const handleBlur = (event) => {
// Check if the textarea is empty and close if needed
if (!thought.trim() && !isPosting) {
event.preventDefault();
setOpen(false);
}
};
const HandlePost = async () => {
setPosted(false);
setPostLoading(true);
var success = await postsModule.createPost(thought);
setPosted(true);
await wait(3000);
ClearTextArea();
setOpen(false);
await wait(1000);
setPostLoading(false);
setPosted(false);
}
var textAreaRef = useRef(null);
useEffect(() => {
// Focus on the textarea when it's rendered
if (isOpen && !isPosting && !posted && textAreaRef != null && textAreaRef.current != null) {
textAreaRef.current.focus();
}else{
textAreaRef = null;
setIsPortrait(window.outerWidth < window.outerHeight);
}
setIsPortrait(window.outerWidth < window.outerHeight);
const handleResize = () => {
setIsPortrait(window.outerWidth < window.outerHeight);
};
window.addEventListener('resize', handleResize);
return () =>{
document.body.style.touchAction = '';
window.removeEventListener('resize', handleResize);
}
}, [isOpen, isPosting, posted, isPortrait]);
return (
<>
<div className={`${isOpen ? styles.centerContOpen : styles.centerCont}`}>
<div className={`${isOpen ? styles.open : styles.closed}`}>
{ isPosting ?
<div className={`${styles.centerLoad}`}>
<div className={`${posted ? styles.success : styles.posting}`}>
</div>
</div>
:
<div>
<Textarea
ref={textAreaRef}
className={`${styles.textBox}`}
label="Create a thought"
placeholder="Enter your thought"
value={thought}
onChange={(e) => setThought(e.target.value)}
style={{
width: '60vw',
backgroundColor: 'rgba(50, 50, 50, 0)', // Set the background color
color: 'white', // Set the text color
fontSize : '20px',
border: 'none',
borderRadius: '5px',
resize: 'none',
fontWeight:'normal',
outline: 'none',
marginTop: '10px'
}}
maxLength={250}
maxRows={100}
onBlur={handleBlur}
/>
<button className={`${styles.postButton}`} onClick={HandlePost}>
<p className={`${styles.text}`}>POST!</p>
</button>
</div>
}
</div>
</div>
<div className={`${ (isPortrait ? styles.buttonContainerMobile : styles.buttonContainer) }`}>
<button className={`${isOpen ? styles.closeButton : styles.createButton}`} onClick={() => {
setOpen((prevOpen) => !prevOpen)
ClearTextArea();
}
}>
</button>
</div>
</>
)
}
and here is my css:
.centerCont{
display: flex;
justify-content: center;
width: 100vw;
align-items: center;
height: 100vh;
position: fixed;
z-index: 3;
pointer-events: none;
top: 0;
left: 0;
backdrop-filter: blur(0px);
transition: backdrop-filter 1s ease;
}
.centerContOpen{
display: flex;
justify-content: center;
width: 100vw;
align-items: center;
height: 100vh;
position: fixed;
z-index: 6;
top: 0;
left: 0;
backdrop-filter: blur(15px);
overflow: hidden;
transition: backdrop-filter 1s ease;
}
.open{
background-color: rgba(0, 0, 0, 0.342);
height: fit-content;
padding-bottom: 1vh;
padding-left: 20px;
padding-right: 20px;
width: fit-content;
border-radius: 30px;
backdrop-filter: blur(15px);
justify-content: center;
border: 2px;
border-color: rgba(179, 179, 179, 0.543);
border-style:solid;
transform: translateY(-60%);
}
.closed{
position: fixed;
background-color: rgba(0, 0, 0, 0.342);
height: fit-content;
padding-bottom: 1vh;
padding-left: 20px;
padding-right: 20px;
width: fit-content;
top: -30vh;
border-radius: 30px;
z-index: 2;
backdrop-filter: blur(15px);
justify-content: center;
border: 2px;
border-color: rgba(179, 179, 179, 0.543);
border-style:solid;
transform: translateY(-60%);
}
.textBox{
color: aliceblue;
font-size: 20px;
font-weight: bolder;
margin-top: 5vh;
border-radius: 20px;
}
.buttonContainer{
position: fixed;
width: 10vw;
height: 10vw;
z-index: 10;
bottom: 0vh;
right: 0vw;
border-radius: 50px;
}
.buttonContainerMobile{
position: fixed;
width: 10vw;
height: 10vw;
z-index: 10;
bottom: 30vh;
right: 0vw;
border-radius: 50px;
}
.createButton{
width: 5vw;
height: 5vw;
max-width: 80px;
max-height: 80px;
mask-image:url('/images/write.png');
mask-size:contain;
mask-repeat: no-repeat;
mask-position: center center;
background-color: white;
animation: none;
animation: show 0.7s ease-in 1;
}
.closeButton{
width: 5vw;
height: 5vw;
max-width: 80px;
max-height: 80px;
mask-image:url('/images/close.png');
mask-size:contain;
mask-repeat: no-repeat;
mask-position: center center;
background-color: white;
animation: none;
animation: hide 0.7s ease-in 1;
}
.postButton{
background-color: rgba(56, 56, 56, 0.183);
width: 60vw;
height: 4vh;
border-radius: 20px;
border: 1.5px;
border-style: solid;
border-color: rgba(240, 248, 255, 0.256);
right: 0;
}
.text{
color: rgba(255, 255, 255, 0.779);
font-size: 2vh;
font-weight: bolder;
}
.centerLoad{
display: flex;
justify-content: center;
width: 60vw;
}
.posting{
margin-top: 10vh;
height: 10vh;
width: 10vh;
mask-image:url('/images/loading.png');
mask-size: contain;
background-size: cover;
background: rgba(240, 248, 255, 0.192);
animation: load 1.8s linear infinite;
margin-bottom: 4vh;
}
.success{
margin-top: 10vh;
height: 10vh;
width: 10vh;
mask-image:url('/images/success.png');
mask-size:contain;
background: rgba(103, 103, 103, 0.279);
margin-bottom: 4vh;
animation: show 0.7s ease-in 1;
}
@keyframes load {
0% {
transform:rotate(0deg);
}
100% {
transform:rotate(360deg);
}
}
@keyframes show {
0% {
transform:scale(0);
}
80% {
transform:scale(1.1);
}
100% {
transform:scale(1);
}
}
@keyframes hide {
0% {
transform:scale(0);
}
80% {
transform:scale(1.1);
}
100% {
transform:scale(1);
}
}
i tried adding:
<Head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0,user-scalable=0" />
</Head>
to my _app but did not work, i also ensured that my texts' font-size is 16px or greater but i still get the odd behaviour