@@ -20,15 +20,15 @@ export const enableTabs = () => {
2020
2121 // Handle arrow navigation between tabs in the tab list
2222 function handleKeydown ( this : HTMLElement , e : KeyboardEvent ) {
23- if ( e . keyCode === 39 || e . keyCode === 37 ) {
23+ if ( e . code === "ArrowRight" || e . code === "ArrowLeft" ) {
2424 const tabs = this . children ;
2525 let tabfocus = Number ( this . dataset . tabfocus || 0 ) ;
2626 tabs [ tabfocus ] . setAttribute ( "tabindex" , "-1" ) ;
27- if ( e . keyCode === 39 ) {
27+ if ( e . code === "ArrowRight" ) {
2828 // Move right
2929 // Increase tab index, wrap by # of tabs
3030 tabfocus = ( tabfocus + 1 ) % tabs . length ;
31- } else if ( e . keyCode === 37 ) {
31+ } else if ( e . code === "ArrowLeft" ) {
3232 // Move left
3333 tabfocus -- ;
3434 // If we're at the start, move to the end
@@ -39,21 +39,32 @@ export const enableTabs = () => {
3939
4040 // Update tabfocus values
4141 this . dataset . tabfocus = tabfocus + "" ;
42- // Focus + click selected tab
42+ // Focus selected tab
4343 const tab = tabs [ tabfocus ] as HTMLElement ;
4444 tab . setAttribute ( "tabindex" , "0" ) ;
4545 tab . focus ( ) ;
46- tab . click ( ) ;
4746
48- // Scroll onto screen in order to avoid jumping page locations
47+ // Check if tab list is within viewport
48+ const header = document . querySelector ( "#header-bar" ) ;
49+ const headerOffset = ( header ?. getBoundingClientRect ( ) . height ?? 0 ) + 20 ;
50+ const tabYPosition = tab . getBoundingClientRect ( ) . y ;
51+ const tabHeight = tab . getBoundingClientRect ( ) . height ;
52+ const isWithinViewport =
53+ tabYPosition > headerOffset &&
54+ tabYPosition < window . innerHeight - tabHeight ;
55+
56+ // Preserve scroll position if within viewport
57+ // Else scroll to 20px below header
58+ const offsetBeforeChangeTabs = tab . offsetTop - window . scrollY ;
59+ const offset = isWithinViewport ? offsetBeforeChangeTabs : headerOffset ;
60+
61+ const tabName = tab . dataset . tabname ;
62+ if ( ! tabName ) return ;
63+ changeTabs ( tabName ) ;
64+
65+ // Ensure tab list is within viewport after switching tabs
4966 setTimeout ( ( ) => {
50- if ( tab . scrollIntoView ) {
51- tab . scrollIntoView ( {
52- behavior : "auto" ,
53- block : "center" ,
54- inline : "center" ,
55- } ) ;
56- }
67+ window . scroll ( 0 , tab . offsetTop - offset ) ;
5768 } , 0 ) ;
5869 }
5970 }
@@ -63,18 +74,14 @@ export const enableTabs = () => {
6374 const tabName = target . dataset . tabname ;
6475 if ( ! tabName ) return ;
6576
77+ const offsetBeforeChangeTabs = target . offsetTop - window . scrollY ;
78+
6679 changeTabs ( tabName ) ;
6780
6881 if ( shouldScrollToTab ) {
6982 // Scroll onto screen in order to avoid jumping page locations
7083 setTimeout ( ( ) => {
71- if ( target . scrollIntoView ) {
72- target . scrollIntoView ( {
73- behavior : "auto" ,
74- block : "center" ,
75- inline : "center" ,
76- } ) ;
77- }
84+ window . scroll ( 0 , target . offsetTop - offsetBeforeChangeTabs ) ;
7885 } , 0 ) ;
7986 }
8087 }
0 commit comments