1- // Skip to Main Content - Accessibility Component
1+ // Skip to Main Content - Enhanced Accessibility Component
22import { useEffect } from "react" ;
33
44export function SkipToContent ( ) {
@@ -16,36 +16,69 @@ export function SkipToContent() {
1616 }
1717 } ;
1818
19+ // Handle keyboard shortcut (Ctrl+/)
20+ const handleKeyboardShortcut = ( e : KeyboardEvent ) => {
21+ if ( e . ctrlKey && e . key === "/" ) {
22+ e . preventDefault ( ) ;
23+ const mainContent = document . getElementById ( "main-content" ) ;
24+ if ( mainContent ) {
25+ mainContent . focus ( ) ;
26+ mainContent . scrollIntoView ( { behavior : "smooth" } ) ;
27+ }
28+ }
29+ } ;
30+
1931 document . addEventListener ( "click" , handleSkipClick ) ;
20- return ( ) => document . removeEventListener ( "click" , handleSkipClick ) ;
32+ document . addEventListener ( "keydown" , handleKeyboardShortcut ) ;
33+
34+ return ( ) => {
35+ document . removeEventListener ( "click" , handleSkipClick ) ;
36+ document . removeEventListener ( "keydown" , handleKeyboardShortcut ) ;
37+ } ;
2138 } , [ ] ) ;
2239
2340 return (
24- < a
25- href = "#main-content"
26- className = "skip-to-content"
27- style = { {
28- position : "absolute" ,
29- left : "-9999px" ,
30- zIndex : 999 ,
31- padding : "1rem 1.5rem" ,
32- backgroundColor : "hsl(262.1, 83.3%, 57.8%)" ,
33- color : "white" ,
34- textDecoration : "none" ,
35- borderRadius : "0 0 0.375rem 0.375rem" ,
36- fontWeight : 600 ,
37- fontSize : "0.875rem" ,
38- transition : "left 0.2s ease-in-out" ,
39- } }
40- onFocus = { ( e ) => {
41- e . currentTarget . style . left = "1rem" ;
42- e . currentTarget . style . top = "1rem" ;
43- } }
44- onBlur = { ( e ) => {
45- e . currentTarget . style . left = "-9999px" ;
46- } }
47- >
48- Skip to Main Content
49- </ a >
41+ < >
42+ < a
43+ href = "#main-content"
44+ className = "skip-to-content"
45+ aria-label = "Skip to main content"
46+ role = "navigation"
47+ style = { {
48+ position : "absolute" ,
49+ left : "-9999px" ,
50+ zIndex : 999 ,
51+ padding : "1rem 1.5rem" ,
52+ backgroundColor : "hsl(262.1, 83.3%, 57.8%)" ,
53+ color : "white" ,
54+ textDecoration : "none" ,
55+ borderRadius : "0 0 0.375rem 0.375rem" ,
56+ fontWeight : 600 ,
57+ fontSize : "0.875rem" ,
58+ transition : "left 0.2s ease-in-out" ,
59+ boxShadow : "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)" ,
60+ } }
61+ onFocus = { ( e ) => {
62+ e . currentTarget . style . left = "1rem" ;
63+ e . currentTarget . style . top = "1rem" ;
64+ e . currentTarget . style . outline = "3px solid hsl(262.1, 83.3%, 57.8%)" ;
65+ e . currentTarget . style . outlineOffset = "2px" ;
66+ } }
67+ onBlur = { ( e ) => {
68+ e . currentTarget . style . left = "-9999px" ;
69+ e . currentTarget . style . outline = "none" ;
70+ } }
71+ >
72+ Skip to Main Content (Ctrl+/)
73+ </ a >
74+ < div
75+ role = "status"
76+ aria-live = "polite"
77+ aria-atomic = "true"
78+ className = "sr-only"
79+ >
80+ Press Tab to navigate, Ctrl+/ to skip to main content
81+ </ div >
82+ </ >
5083 ) ;
5184}
0 commit comments