1717 */
1818import { useState } from 'react' ;
1919import { Link , useLocation } from 'react-router-dom' ;
20- import { Layout , Menu , Button , Space , Dropdown , Tooltip } from 'antd' ;
20+ import { Layout , Menu , Button , Space , Dropdown , Tooltip , Drawer , Grid } from 'antd' ;
2121import {
2222 FolderOutlined ,
2323 DatabaseOutlined ,
@@ -29,6 +29,7 @@ import {
2929 QuestionCircleOutlined ,
3030 RobotOutlined ,
3131 SettingOutlined ,
32+ MenuOutlined ,
3233} from '@ant-design/icons' ;
3334import { SunOutlined , MoonOutlined } from '@ant-design/icons' ;
3435import type { MenuProps } from 'antd' ;
@@ -62,6 +63,9 @@ export default function Navbar() {
6263 const location = useLocation ( ) ;
6364 const { isDark, toggle } = useTheme ( ) ;
6465 const [ prospectorSettingsOpen , setProspectorSettingsOpen ] = useState ( false ) ;
66+ const [ drawerOpen , setDrawerOpen ] = useState ( false ) ;
67+ const screens = Grid . useBreakpoint ( ) ;
68+ const isMobile = ! screens . md ;
6569
6670 // Determine selected nav key, handling sub-routes like /projects/:id, /datasources/:name
6771 let selectedKey = location . pathname ;
@@ -81,7 +85,7 @@ export default function Navbar() {
8185 style = { {
8286 display : 'flex' ,
8387 alignItems : 'center' ,
84- padding : '0 24px' ,
88+ padding : isMobile ? '0 12px' : '0 24px' ,
8589 background : navBg ,
8690 backdropFilter : 'blur(12px)' ,
8791 WebkitBackdropFilter : 'blur(12px)' ,
@@ -110,21 +114,26 @@ export default function Navbar() {
110114 < span style = { { fontSize : 16 , fontWeight : 600 } } > SQL Lab</ span >
111115 </ Link >
112116
113- { /* Main Navigation */ }
114- < Menu
115- theme = { isDark ? 'dark' : 'light' }
116- mode = "horizontal"
117- selectedKeys = { [ selectedKey ] }
118- items = { navItems . map ( ( item ) => ( {
119- key : item . key ,
120- icon : item . icon ,
121- label : < Link to = { item . key } > { item . label } </ Link > ,
122- } ) ) }
123- style = { { flex : 1 , minWidth : 0 , background : 'transparent' , borderBottom : 'none' } }
124- />
117+ { /* Main Navigation — hidden on mobile */ }
118+ { ! isMobile && (
119+ < Menu
120+ theme = { isDark ? 'dark' : 'light' }
121+ mode = "horizontal"
122+ selectedKeys = { [ selectedKey ] }
123+ items = { navItems . map ( ( item ) => ( {
124+ key : item . key ,
125+ icon : item . icon ,
126+ label : < Link to = { item . key } > { item . label } </ Link > ,
127+ } ) ) }
128+ style = { { flex : 1 , minWidth : 0 , background : 'transparent' , borderBottom : 'none' } }
129+ />
130+ ) }
131+
132+ { /* Spacer when nav is hidden */ }
133+ { isMobile && < div style = { { flex : 1 } } /> }
125134
126135 { /* Right side actions */ }
127- < Space >
136+ < Space size = { isMobile ? 4 : 8 } >
128137 < Tooltip title = { isDark ? 'Switch to Light Mode' : 'Switch to Dark Mode' } >
129138 < Button
130139 type = "text"
@@ -134,11 +143,13 @@ export default function Navbar() {
134143 />
135144 </ Tooltip >
136145
137- < Dropdown menu = { { items : adminMenuItems } } placement = "bottomRight" >
138- < Button type = "text" icon = { < SettingOutlined /> } style = { { color : textColor } } >
139- Admin
140- </ Button >
141- </ Dropdown >
146+ { ! isMobile && (
147+ < Dropdown menu = { { items : adminMenuItems } } placement = "bottomRight" >
148+ < Button type = "text" icon = { < SettingOutlined /> } style = { { color : textColor } } >
149+ Admin
150+ </ Button >
151+ </ Dropdown >
152+ ) }
142153
143154 < Tooltip title = "Prospector Settings" >
144155 < Button
@@ -149,11 +160,13 @@ export default function Navbar() {
149160 />
150161 </ Tooltip >
151162
152- < Dropdown menu = { { items : legacyMenuItems } } placement = "bottomRight" >
153- < Button type = "text" icon = { < HomeOutlined /> } style = { { color : textColor } } >
154- Drill UI
155- </ Button >
156- </ Dropdown >
163+ { ! isMobile && (
164+ < Dropdown menu = { { items : legacyMenuItems } } placement = "bottomRight" >
165+ < Button type = "text" icon = { < HomeOutlined /> } style = { { color : textColor } } >
166+ Drill UI
167+ </ Button >
168+ </ Dropdown >
169+ ) }
157170
158171 < Button
159172 type = "text"
@@ -162,8 +175,51 @@ export default function Navbar() {
162175 href = "https://drill.apache.org/docs/"
163176 target = "_blank"
164177 />
178+
179+ { /* Hamburger on mobile */ }
180+ { isMobile && (
181+ < Button
182+ type = "text"
183+ icon = { < MenuOutlined /> }
184+ style = { { color : textColor } }
185+ onClick = { ( ) => setDrawerOpen ( true ) }
186+ />
187+ ) }
165188 </ Space >
166189
190+ { /* Mobile Navigation Drawer */ }
191+ < Drawer
192+ title = "Menu"
193+ placement = "right"
194+ open = { drawerOpen }
195+ onClose = { ( ) => setDrawerOpen ( false ) }
196+ width = { 260 }
197+ >
198+ < Menu
199+ theme = { isDark ? 'dark' : 'light' }
200+ mode = "inline"
201+ selectedKeys = { [ selectedKey ] }
202+ items = { navItems . map ( ( item ) => ( {
203+ key : item . key ,
204+ icon : item . icon ,
205+ label : < Link to = { item . key } onClick = { ( ) => setDrawerOpen ( false ) } > { item . label } </ Link > ,
206+ } ) ) }
207+ style = { { background : 'transparent' , border : 'none' } }
208+ />
209+ < div style = { { borderTop : '1px solid var(--color-border)' , marginTop : 16 , paddingTop : 16 } } >
210+ < Dropdown menu = { { items : adminMenuItems } } placement = "bottomLeft" >
211+ < Button type = "text" icon = { < SettingOutlined /> } style = { { color : textColor , width : '100%' , textAlign : 'left' } } >
212+ Admin
213+ </ Button >
214+ </ Dropdown >
215+ < Dropdown menu = { { items : legacyMenuItems } } placement = "bottomLeft" >
216+ < Button type = "text" icon = { < HomeOutlined /> } style = { { color : textColor , width : '100%' , textAlign : 'left' } } >
217+ Drill UI
218+ </ Button >
219+ </ Dropdown >
220+ </ div >
221+ </ Drawer >
222+
167223 < ProspectorSettingsModal
168224 open = { prospectorSettingsOpen }
169225 onClose = { ( ) => setProspectorSettingsOpen ( false ) }
0 commit comments