fix(ui): stop mobile tab bar covering last row of content (#2)

On Cloud/files (and any scrolling view), the bottom of the list could sit behind
the fixed mobile tab bar. Cause: DashboardMobileNav measured the bar's
offsetHeight and wrote it to --mobile-tab-bar-height, but when the bar was hidden
or not yet laid out the measurement was 0 — and writing "0px" defeats the
", 88px" fallback in the .mobile-scroll-pad clearance calc (an explicit 0 is
still a set value), so the clearance collapsed and the ~88px bar overlapped the
last row.

- never write 0px: only set a real measured height, else remove the var so the
  88px fallback applies.
- re-measure after first paint (rAF) and after the WebView safe-area injection,
  so the clearance reflects the bar's final laid-out height.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
archipelago 2026-06-20 08:50:44 -04:00
parent 8f06d88fbf
commit a8c668ee0a

View File

@ -188,9 +188,17 @@ defineExpose({
function updateTabBarHeight() { function updateTabBarHeight() {
if (typeof window === 'undefined') return if (typeof window === 'undefined') return
if (mobileTabBar.value) { const el = mobileTabBar.value
const height = mobileTabBar.value.offsetHeight // offsetHeight is 0 when the bar is hidden (desktop `md:hidden`) or not yet
document.documentElement.style.setProperty('--mobile-tab-bar-height', `${height}px`) // laid out. Writing `--mobile-tab-bar-height: 0px` would DEFEAT the `, 88px`
// fallback baked into the `.mobile-scroll-pad` clearance calc (an explicit
// 0px is still "set"), so the fixed tab bar ends up covering the last row of
// content the Cloud/files "bottom elements cut off" bug. Only write a real
// measured height; otherwise remove the var so the fallback applies.
if (el && el.offsetHeight > 0) {
document.documentElement.style.setProperty('--mobile-tab-bar-height', `${el.offsetHeight}px`)
} else {
document.documentElement.style.removeProperty('--mobile-tab-bar-height')
} }
} }
@ -201,10 +209,15 @@ function onResize() {
onMounted(() => { onMounted(() => {
updateTabBarHeight() updateTabBarHeight()
// Re-measure after the first paint: on mount the bar may not have its final
// laid-out height yet (fonts/safe-area padding still settling), which would
// leave the clearance var short.
requestAnimationFrame(updateTabBarHeight)
readSafeAreaTop() readSafeAreaTop()
window.addEventListener('resize', onResize) window.addEventListener('resize', onResize)
// Re-read after WebView injection has had time to run // Re-read after WebView injection has had time to run. The injected
setTimeout(readSafeAreaTop, 500) // safe-area-bottom padding changes the bar's height, so re-measure too.
setTimeout(() => { readSafeAreaTop(); updateTabBarHeight() }, 500)
}) })
onBeforeUnmount(() => { onBeforeUnmount(() => {