From 85f2b28d00750c8b329af3fa3368832a35b9ad3a Mon Sep 17 00:00:00 2001 From: gnacho Date: Wed, 7 Oct 2026 19:59:51 +0200 Subject: [PATCH] feat(nav): horizontally scrollable mobile bottom nav The fixed 6-column grid squeezed labels and left an empty column when expenses were disabled. The bottom nav is now a scrollable row that shows every section and auto-centers the active one (keynest #284 pattern). --- app/src/components/Layout.tsx | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/app/src/components/Layout.tsx b/app/src/components/Layout.tsx index 868b082..5a0726e 100644 --- a/app/src/components/Layout.tsx +++ b/app/src/components/Layout.tsx @@ -1,4 +1,4 @@ -import { useMemo, useEffect, useState } from 'react'; +import { useMemo, useEffect, useRef, useState } from 'react'; import { flushSync } from 'react-dom'; import { NavLink, Link, Outlet, useLocation, useNavigate, useParams } from 'react-router'; import { useTranslation } from 'react-i18next'; @@ -496,13 +496,23 @@ export default function Layout() { }`; const bnCls = (active: boolean) => - `flex flex-col items-center justify-center gap-1 transition-colors duration-150 rounded-lg ${ + `flex min-w-[68px] flex-1 flex-col items-center justify-center gap-1 transition-colors duration-150 rounded-lg ${ active ? 'text-brand' : 'text-faint hover:bg-hover hover:text-text-primary' }`; const isProjectsSection = location.pathname.startsWith('/projects') || boardView === 'project'; const lgMargin = collapsed ? 'lg:pl-16' : 'lg:pl-[232px]'; + /* Bottom-nav deslizable: centra el item activo en la fila scrolleable. */ + const bottomNavRef = useRef(null); + useEffect(() => { + const el = bottomNavRef.current; + const activeEl = el?.querySelector('[data-active="true"]'); + if (el && activeEl) { + activeEl.scrollIntoView({ inline: 'center', block: 'nearest' }); + } + }, [location.pathname]); + const boardSelect = boardView !== null && ( <>