From 8eb851793dac0ef7509e74e1ab2ddbf5239d1f5a Mon Sep 17 00:00:00 2001 From: Alex Blank Date: Thu, 28 May 2026 14:10:06 +0200 Subject: [PATCH] feat: mobile auto-hide header and tabs for multi-session terminal - Add useAutoHide hook to TerminalPage for mobile header/tab strip - Header and tabs auto-hide after 3s, tap to reveal - Add CSS transitions for smooth show/hide on mobile - Fullscreen mobile mode hides header and tabs completely --- apps/web/src/pages/terminal.tsx | 64 ++++++++++++++++++--------------- apps/web/src/styles.css | 19 ++++++++++ 2 files changed, 55 insertions(+), 28 deletions(-) diff --git a/apps/web/src/pages/terminal.tsx b/apps/web/src/pages/terminal.tsx index 20c1af6..4a6a8ab 100644 --- a/apps/web/src/pages/terminal.tsx +++ b/apps/web/src/pages/terminal.tsx @@ -6,6 +6,7 @@ import { type TerminalSessionInfo, } from "../components/terminal-session-tabs"; import { useMobileViewport } from "../hooks/use-mobile-viewport"; +import { useAutoHide } from "../hooks/use-auto-hide"; import { useTerminalSessions } from "../hooks/use-terminal-sessions"; import type { TerminalSession } from "../api/terminal"; @@ -26,6 +27,7 @@ export const TerminalPage: React.FC = () => { const isMobile = useMobileViewport(); const [isFullscreen, setIsFullscreen] = useState(false); const terminalRefs = useRef>>({}); + const headerAutoHide = useAutoHide({ timeout: 3000, enabled: isMobile }); const { sessions, @@ -193,34 +195,40 @@ export const TerminalPage: React.FC = () => {
- {!isFullscreen && ( -
- -

Terminal

- -
- )} - +
headerAutoHide.show()} + > + +

Terminal

+ +
+
headerAutoHide.show()} + > + +
{error &&
{error}
} {sessions.map((session) => ( diff --git a/apps/web/src/styles.css b/apps/web/src/styles.css index f37d0db..5f4fbac 100644 --- a/apps/web/src/styles.css +++ b/apps/web/src/styles.css @@ -2904,6 +2904,25 @@ a.nav-item, opacity: 1; } +/* Mobile auto-hide header and tabs */ +.terminal-page.mobile .terminal-page-header, +.mobile-tabs-container { + transition: transform 0.3s ease, opacity 0.3s ease; +} + +.terminal-page.mobile .terminal-page-header.hidden, +.mobile-tabs-container.hidden { + transform: translateY(-100%); + opacity: 0; + pointer-events: none; +} + +.terminal-page.mobile .terminal-page-header.visible, +.mobile-tabs-container.visible { + transform: translateY(0); + opacity: 1; +} + /* Mobile fullscreen */ @media (max-width: 767px) { .terminal-page.fullscreen {