From 2b9d87b6a79be4cf38d0a00a855c07e6e0546815 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 11 Nov 2026 14:50:37 +0000 Subject: [PATCH] Slide the phone bottom bar away while reading down a page It comes back after a short scroll up, at the top or end of a page, on every new page, and while it holds keyboard focus. Reduced motion fades it instead of sliding. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01PYdxvWr2QJdEqqD6VDcxfT --- src/App.tsx | 1 + src/components/BottomNav.tsx | 57 +++++++++++++++++++++++++++++++++++- src/styles/motion.css | 22 ++++++++++++++ 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/src/App.tsx b/src/App.tsx index d9827c41..aa4cfbae 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1297,6 +1297,7 @@ const AppContent = () => { tabs={navItems.filter(item => item.id !== 'admin')} activeTab={currentView === 'admin' ? 'settings' : currentTab} onSelect={id => handleTabSelect(id as ViewKey)} + pageKey={currentView} /> diff --git a/src/components/BottomNav.tsx b/src/components/BottomNav.tsx index 6dcb3b67..0c7b3261 100644 --- a/src/components/BottomNav.tsx +++ b/src/components/BottomNav.tsx @@ -22,12 +22,18 @@ interface NavTab { * strings give the page, so it stays, and its tab takes a few pixels more * than the rest. Each tab is rounded so the focus ring nests in the island * instead of cutting a square into the next tab's pill. + * + * Reading down a long page, the bar slides out of the way so it no longer + * sits over what's being read; a short scroll back up, the top of the page or + * its end brings it back, and so does every new page. `pageKey` is the page + * being shown, so the bar knows when that happens. */ const BottomNav: React.FC<{ tabs: NavTab[]; activeTab: string; onSelect: (id: string) => void; -}> = ({ tabs, activeTab, onSelect }) => { + pageKey?: string; +}> = ({ tabs, activeTab, onSelect, pageKey }) => { const navRef = useRef(null); const rowRef = useRef(null); const marks = useRef>({}); @@ -81,6 +87,8 @@ const BottomNav: React.FC<{ }; }, []); + const hidden = useScrollAway(pageKey); + useEffect(() => { if (!pill || placed) return; const frame = requestAnimationFrame(() => setPlaced(true)); @@ -90,6 +98,7 @@ const BottomNav: React.FC<{ return (