@@ -45,15 +45,35 @@ const Navigation = () => {
4545 }
4646 } ;
4747
48+ // Keyboard navigation handler for navigation links
49+ const handleKeyDown = ( e , idx ) => {
50+ if ( e . key === "ArrowDown" || e . key === "ArrowRight" ) {
51+ e . preventDefault ( ) ;
52+ const next = document . querySelectorAll ( '[role="menuitem"]' ) [ idx + 1 ] ;
53+ if ( next ) next . focus ( ) ;
54+ } else if ( e . key === "ArrowUp" || e . key === "ArrowLeft" ) {
55+ e . preventDefault ( ) ;
56+ const prev = document . querySelectorAll ( '[role="menuitem"]' ) [ idx - 1 ] ;
57+ if ( prev ) prev . focus ( ) ;
58+ } else if ( e . key === "Home" ) {
59+ e . preventDefault ( ) ;
60+ const first = document . querySelectorAll ( '[role="menuitem"]' ) [ 0 ] ;
61+ if ( first ) first . focus ( ) ;
62+ } else if ( e . key === "End" ) {
63+ e . preventDefault ( ) ;
64+ const items = document . querySelectorAll ( '[role="menuitem"]' ) ;
65+ if ( items . length ) items [ items . length - 1 ] . focus ( ) ;
66+ }
67+ } ;
68+
4869 return (
4970 < >
5071 { /* Mobile Menu Button */ }
5172 < div className = "lg:hidden fixed top-4 left-4 z-50" >
5273 < button
5374 onClick = { ( ) => setIsMobileMenuOpen ( ! isMobileMenuOpen ) }
54- className = "p-3 bg-white rounded-lg shadow-lg hover:shadow-xl transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
55- aria-label = { isMobileMenuOpen ? 'Close navigation menu' : 'Open navigation menu' }
56- aria-expanded = { isMobileMenuOpen }
75+ className = "p-2 bg-white rounded-lg shadow-lg"
76+ aria-label = "Open main navigation menu"
5777 >
5878 < div className = "w-6 h-6 flex flex-col justify-center space-y-1" >
5979 < motion . div
@@ -88,7 +108,7 @@ const Navigation = () => {
88108 transition = { { type : 'spring' , damping : 30 , stiffness : 300 } }
89109 className = "fixed left-0 top-0 h-full w-64 bg-white shadow-xl z-40 lg:z-auto"
90110 role = "navigation"
91- aria-label = "Primary "
111+ aria-label = "Main Navigation "
92112 >
93113 < div className = "p-6 border-b border-gray-200" >
94114 < div className = "flex items-center space-x-3" >
@@ -108,18 +128,22 @@ const Navigation = () => {
108128 </ div >
109129
110130 < div className = "p-4" >
111- < ul className = "space-y-2" >
112- { navigationItems . map ( ( item ) => (
113- < li key = { item . path } >
131+ < ul className = "space-y-2" role = "menubar" aria-label = "Main menu" >
132+ { navigationItems . map ( ( item , idx ) => (
133+ < li key = { item . path } role = "none" >
114134 < Link
115135 to = { item . path }
116136 onClick = { ( ) => setIsMobileMenuOpen ( false ) }
117- className = { `flex items-center space-x-3 px-4 py-3 rounded-lg transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 ${
137+ className = { `flex items-center space-x-3 px-4 py-3 rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 ${
118138 location . pathname === item . path
119139 ? 'bg-blue-50 text-blue-700 border-r-2 border-blue-700 shadow-sm'
120140 : 'text-gray-700 hover:bg-gray-50 hover:text-gray-900'
121141 } `}
122- aria-current = { location . pathname === item . path ? 'page' : undefined }
142+ aria-label = { item . label + ( location . pathname === item . path ? ' (current page)' : '' ) }
143+ role = "menuitem"
144+ tabIndex = { 0 }
145+ aria-current = { location . pathname === item . path ? "page" : undefined }
146+ onKeyDown = { e => handleKeyDown ( e , idx ) }
123147 >
124148 < span className = "text-xl" aria-hidden = "true" > { item . icon } </ span >
125149 < span className = "font-medium" > { item . label } </ span >
@@ -184,6 +208,8 @@ const Navigation = () => {
184208 exit = { { opacity : 0 } }
185209 onClick = { ( ) => setIsMobileMenuOpen ( false ) }
186210 className = "fixed inset-0 bg-black bg-opacity-50 z-30 lg:hidden"
211+ aria-label = "Close main navigation menu"
212+ tabIndex = { 0 }
187213 />
188214 ) }
189215 </ AnimatePresence >
0 commit comments