diff --git a/src/app.css b/src/app.css index 5881e52..584da6a 100644 --- a/src/app.css +++ b/src/app.css @@ -465,3 +465,10 @@ input[type="checkbox"]:checked::before { width: 100%; height: 100%; } + +/* Hamburger menu button - only show on non-touch devices under mobile breakpoint */ +@media (max-width: 767px) and (hover: hover) and (pointer: fine) { + .hamburger-menu-btn { + display: block !important; + } +} diff --git a/src/app.tsx b/src/app.tsx index 461bb9a..30b2747 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -1,6 +1,12 @@ import { Router } from "@solidjs/router"; import { FileRoutes } from "@solidjs/start/router"; -import { createEffect, ErrorBoundary, Suspense, onMount, onCleanup } from "solid-js"; +import { + createEffect, + ErrorBoundary, + Suspense, + onMount, + onCleanup +} from "solid-js"; import "./app.css"; import { LeftBar, RightBar } from "./components/Bars"; import { TerminalSplash } from "./components/TerminalSplash"; @@ -29,13 +35,13 @@ function AppLayout(props: { children: any }) { createEffect(() => { const handleResize = () => { const isMobile = window.innerWidth < 768; // md breakpoint - + // Show bars when switching to desktop if (!isMobile) { setLeftBarVisible(true); setRightBarVisible(true); } - + const newWidth = window.innerWidth - leftBarSize() - rightBarSize(); setCenterWidth(newWidth); }; @@ -77,12 +83,34 @@ function AppLayout(props: { children: any }) { }); }); + // ESC key to close sidebars on mobile + onMount(() => { + const handleKeyDown = (e: KeyboardEvent) => { + const isMobile = window.innerWidth < 768; // md breakpoint + + if (e.key === "Escape" && isMobile) { + if (leftBarVisible()) { + setLeftBarVisible(false); + } + if (rightBarVisible()) { + setRightBarVisible(false); + } + } + }; + + window.addEventListener("keydown", handleKeyDown); + + onCleanup(() => { + window.removeEventListener("keydown", handleKeyDown); + }); + }); + // Swipe gestures to reveal bars onMount(() => { let touchStartX = 0; let touchStartY = 0; - const EDGE_THRESHOLD = 50; // pixels from edge to trigger - const SWIPE_THRESHOLD = 100; // minimum swipe distance + const EDGE_THRESHOLD = 100; + const SWIPE_THRESHOLD = 100; const handleTouchStart = (e: TouchEvent) => { touchStartX = e.touches[0].clientX; @@ -111,7 +139,10 @@ function AppLayout(props: { children: any }) { setLeftBarVisible(true); } // Swipe left from right edge - reveal right bar - else if (touchStartX > window.innerWidth - EDGE_THRESHOLD && deltaX < -SWIPE_THRESHOLD) { + else if ( + touchStartX > window.innerWidth - EDGE_THRESHOLD && + deltaX < -SWIPE_THRESHOLD + ) { setRightBarVisible(true); } } @@ -129,16 +160,32 @@ function AppLayout(props: { children: any }) { return (