1- import { type Component , type JSX , Show } from "solid-js" ;
1+ import { type Component , createSignal , type JSX , Show } from "solid-js" ;
22
33import { useStore } from "../../contexts/store" ;
44import { ScreenInfo } from "../screen-info" ;
@@ -9,9 +9,12 @@ export const Layout: Component<{
99 ref ?: HTMLElement ;
1010} > = ( props ) => {
1111 const [ store ] = useStore ( ) ;
12+ const [ isMobileMenuOpen , setIsMobileMenuOpen ] = createSignal ( false ) ;
13+
14+ const closeMobileMenu = ( ) => setIsMobileMenuOpen ( false ) ;
1215
1316 return (
14- < div class = { ` h-full ${ store . connectionState ( ) === 1 ? "grid grid-cols-[320px_1fr] gap-6 p-6" : "" } ` } >
17+ < div class = " h-full flex flex-col" >
1518 < Show
1619 when = { store . connectionState ( ) === 1 }
1720 fallback = {
@@ -22,12 +25,70 @@ export const Layout: Component<{
2225 </ main >
2326 }
2427 >
25- < aside class = "bg-white p-6 flex flex-col h-full rounded-2xl shadow-lg overflow-y-auto" >
26- { props . sidebar }
27- </ aside >
28- < main class = "h-full overflow-auto" ref = { props . ref } >
29- { props . content }
30- </ main >
28+ < div class = "flex-1 lg:grid lg:grid-cols-[320px_1fr] lg:gap-6 lg:p-6 relative overflow-hidden" >
29+ { /* Mobile Overlay */ }
30+ < Show when = { isMobileMenuOpen ( ) } >
31+ < button
32+ type = "button"
33+ class = "lg:hidden fixed inset-0 bg-black bg-opacity-50 z-40 border-0 p-0 cursor-default"
34+ onClick = { closeMobileMenu }
35+ onKeyDown = { ( e ) => {
36+ if ( e . key === "Enter" || e . key === " " || e . key === "Escape" ) {
37+ closeMobileMenu ( ) ;
38+ }
39+ } }
40+ />
41+ </ Show >
42+
43+ { /* Sidebar */ }
44+ < aside
45+ class = { `bg-white p-6 shadow-lg flex flex-col
46+ lg:relative lg:h-full lg:rounded-2xl
47+ fixed top-0 left-0 h-full w-full z-50
48+ transition-transform duration-300 ease-in-out
49+ ${ isMobileMenuOpen ( ) ? "translate-x-0" : "-translate-x-full lg:translate-x-0" } ` }
50+ onClick = { ( e ) => {
51+ // Close menu when clicks links in sidebar
52+ const target = e . target as HTMLElement ;
53+ if ( target . tagName === "A" || target . closest ( "a" ) ) {
54+ closeMobileMenu ( ) ;
55+ }
56+ } }
57+ onKeyDown = { ( e ) => {
58+ // Close menu when Enter is pressed on links in sidebar
59+ if ( e . key === "Enter" ) {
60+ const target = e . target as HTMLElement ;
61+ if ( target . tagName === "A" || target . closest ( "a" ) ) {
62+ closeMobileMenu ( ) ;
63+ }
64+ }
65+ } }
66+ >
67+ { props . sidebar }
68+ { /* Mobile Close Button */ }
69+ < button
70+ type = "button"
71+ onClick = { closeMobileMenu }
72+ class = "lg:hidden mt-4 w-full bg-gray-700 text-white border-0 px-4 py-3 uppercase text-sm leading-6 tracking-wider cursor-pointer font-bold hover:opacity-80 active:-translate-y-px transition-all rounded"
73+ >
74+ < i class = "fa-solid fa-times mr-2" />
75+ Close Menu
76+ </ button >
77+ </ aside >
78+
79+ < main class = "h-full overflow-auto lg:pb-0 pb-20" ref = { props . ref } >
80+ { props . content }
81+ </ main >
82+ </ div >
83+
84+ { /* Mobile Menu Button - Fixed at bottom */ }
85+ < button
86+ type = "button"
87+ onClick = { ( ) => setIsMobileMenuOpen ( ! isMobileMenuOpen ( ) ) }
88+ class = "lg:hidden fixed bottom-6 right-6 z-30 bg-gray-700 text-white border-0 p-4 rounded-full shadow-lg cursor-pointer font-bold hover:opacity-80 active:-translate-y-px transition-all"
89+ >
90+ < i class = "fa-solid fa-bars text-xl" />
91+ </ button >
3192 </ Show >
3293 </ div >
3394 ) ;
0 commit comments