diff --git a/frontend/src/components/MobileEventForm.jsx b/frontend/src/components/MobileEventForm.jsx index ac028ab..e1bccbc 100644 --- a/frontend/src/components/MobileEventForm.jsx +++ b/frontend/src/components/MobileEventForm.jsx @@ -72,43 +72,22 @@ function fmt12(val) { function TimeInputMobile({ value, onChange }) { const [open, setOpen] = useState(false); const [inputVal, setInputVal] = useState(fmt12(value)); - const [keyboardOffset, setKeyboardOffset] = useState(0); - const [dropdownPos, setDropdownPos] = useState({ top: 0, bottom: 'auto', left: 0 }); + const [dropdownPos, setDropdownPos] = useState({ top: 0, left: 0 }); const wrapRef = useRef(null); const listRef = useRef(null); useEffect(() => { setInputVal(fmt12(value)); }, [value]); - // Detect keyboard height via Visual Viewport API - useEffect(() => { - const handleViewportChange = () => { - if (window.visualViewport) { - const offset = window.innerHeight - window.visualViewport.height; - setKeyboardOffset(offset > 0 ? offset : 0); - } - }; - if (open) { - handleViewportChange(); - window.visualViewport?.addEventListener('resize', handleViewportChange); - return () => window.visualViewport?.removeEventListener('resize', handleViewportChange); - } else { - setKeyboardOffset(0); - } - }, [open]); - - // Calculate dropdown pixel position using getBoundingClientRect (required for position:fixed) + // Calculate dropdown position — always above the input. + // getBoundingClientRect() is relative to the visual viewport on mobile Chrome, + // so this correctly clears the keyboard regardless of its height. useEffect(() => { if (open && wrapRef.current) { const rect = wrapRef.current.getBoundingClientRect(); const dropdownHeight = 5 * 40; - const spaceBelow = window.innerHeight - rect.bottom - keyboardOffset; - if (spaceBelow >= dropdownHeight) { - setDropdownPos({ top: rect.bottom, bottom: 'auto', left: rect.left }); - } else { - setDropdownPos({ top: 'auto', bottom: window.innerHeight - rect.top + keyboardOffset, left: rect.left }); - } + setDropdownPos({ top: Math.max(0, rect.top - dropdownHeight), left: rect.left }); } - }, [open, keyboardOffset]); + }, [open]); useEffect(() => { if (!open || !listRef.current) return; @@ -151,7 +130,6 @@ function TimeInputMobile({ value, onChange }) { position: 'fixed', zIndex: 9999, top: dropdownPos.top, - bottom: dropdownPos.bottom, left: dropdownPos.left, background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 8, boxShadow: '0 4px 20px rgba(0,0,0,0.2)',