From a8c668ee0a1e5dd90ef793b55f1c516ccac3bf36 Mon Sep 17 00:00:00 2001 From: archipelago Date: Sat, 20 Jun 2026 08:50:44 -0400 Subject: [PATCH] fix(ui): stop mobile tab bar covering last row of content (#2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- .../views/dashboard/DashboardMobileNav.vue | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/neode-ui/src/views/dashboard/DashboardMobileNav.vue b/neode-ui/src/views/dashboard/DashboardMobileNav.vue index 285bcd64..d6721dad 100644 --- a/neode-ui/src/views/dashboard/DashboardMobileNav.vue +++ b/neode-ui/src/views/dashboard/DashboardMobileNav.vue @@ -188,9 +188,17 @@ defineExpose({ function updateTabBarHeight() { if (typeof window === 'undefined') return - if (mobileTabBar.value) { - const height = mobileTabBar.value.offsetHeight - document.documentElement.style.setProperty('--mobile-tab-bar-height', `${height}px`) + const el = mobileTabBar.value + // offsetHeight is 0 when the bar is hidden (desktop `md:hidden`) or not yet + // 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(() => { 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() window.addEventListener('resize', onResize) - // Re-read after WebView injection has had time to run - setTimeout(readSafeAreaTop, 500) + // Re-read after WebView injection has had time to run. The injected + // safe-area-bottom padding changes the bar's height, so re-measure too. + setTimeout(() => { readSafeAreaTop(); updateTabBarHeight() }, 500) }) onBeforeUnmount(() => {