1- import React , { forwardRef , memo , useCallback , useEffect , useImperativeHandle , useMemo , useRef , useState } from "react"
1+ import React , {
2+ forwardRef ,
3+ memo ,
4+ useCallback ,
5+ useEffect ,
6+ useImperativeHandle ,
7+ useMemo ,
8+ useRef ,
9+ useState ,
10+ WheelEvent ,
11+ } from "react"
212import { useAppTranslation } from "@/i18n/TranslationContext"
313import {
414 CheckCheck ,
@@ -105,6 +115,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
105115 const confirmDialogHandler = useRef < ( ) => void > ( )
106116
107117 const [ cachedState , setCachedState ] = useState ( extensionState )
118+ const scrollContainerRef = useRef < HTMLDivElement > ( null ) // Ref for the scrollable container
108119
109120 const {
110121 alwaysAllowReadOnly,
@@ -342,25 +353,56 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
342353 }
343354 } , [ targetSection ] )
344355
345- // Add effect to scroll the active tab into view when it changes
356+ // Add effect to conditionally scroll the active tab into view when it changes
346357 useEffect ( ( ) => {
347358 const activeTabElement = tabRefs . current [ activeTab ] ?. current
348- const tabContainer = document . querySelector ( `. ${ settingsTabsContainer . split ( " " ) [ 0 ] } ` )
359+ const containerElement = scrollContainerRef . current
349360
350- if ( activeTabElement && tabContainer ) {
351- // Calculate the scroll position to center the tab
352- const containerWidth = tabContainer . clientWidth
353- const tabWidth = activeTabElement . offsetWidth
354- const tabLeft = activeTabElement . offsetLeft
355-
356- // Center the tab in the container
357- const scrollPosition = tabLeft - containerWidth / 2 + tabWidth / 2
361+ if ( activeTabElement && containerElement ) {
362+ // Calculate the visible range within the scroll container
363+ const visibleLeft = containerElement . scrollLeft
364+ const visibleRight = containerElement . scrollLeft + containerElement . clientWidth
358365
359- // Set the scroll position directly for a snappier experience
360- tabContainer . scrollLeft = scrollPosition
366+ // Calculate the tab's position within the scroll container
367+ const tabLeft = activeTabElement . offsetLeft
368+ const tabRight = activeTabElement . offsetLeft + activeTabElement . offsetWidth
369+
370+ // Check if the tab is fully within the visible range
371+ const isVisible = tabLeft >= visibleLeft && tabRight <= visibleRight
372+
373+ // Only scroll if the tab is not fully visible
374+ if ( ! isVisible ) {
375+ activeTabElement . scrollIntoView ( {
376+ behavior : "auto" , // Use instant scrolling
377+ block : "nearest" ,
378+ inline : "center" ,
379+ } )
380+ }
361381 }
362382 } , [ activeTab ] )
363383
384+ // Handle horizontal scrolling with mouse wheel
385+ const handleWheelScroll = useCallback ( ( event : WheelEvent < HTMLDivElement > ) => {
386+ const container = scrollContainerRef . current
387+ if ( container ) {
388+ // Use deltaY for vertical scroll wheels (most common)
389+ // Adjust sensitivity as needed
390+ const scrollAmount = event . deltaY * 2 // Multiplier for sensitivity
391+
392+ // Check if scrolling is possible
393+ if ( container . scrollWidth > container . clientWidth ) {
394+ container . scrollLeft += scrollAmount
395+ // Prevent default page scrolling if horizontal scroll happened
396+ if (
397+ ( scrollAmount < 0 && container . scrollLeft > 0 ) ||
398+ ( scrollAmount > 0 && container . scrollLeft < container . scrollWidth - container . clientWidth )
399+ ) {
400+ event . preventDefault ( )
401+ }
402+ }
403+ }
404+ } , [ ] )
405+
364406 return (
365407 < Tab >
366408 < TabHeader className = "flex justify-between items-center gap-2" >
@@ -393,9 +435,15 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
393435 </ TabHeader >
394436
395437 { /* Tab list with overflow dropdown */ }
396- < div className = "flex items-center" >
397- { /* Show only the first 5 tabs and the active tab if it's not in the first 5 */ }
398- < div className = { cn ( settingsTabsContainer , scrollbarHideClasses , "w-full" ) } >
438+ < div className = "flex items-center pr-5" >
439+ { " " }
440+ { /* Added pr-5 here */ }
441+ { /* Scrollable tab container */ }
442+ < div
443+ ref = { scrollContainerRef } // Assign ref
444+ className = { cn ( settingsTabsContainer , scrollbarHideClasses , "w-full" , "px-5" ) }
445+ onWheel = { handleWheelScroll } // Add wheel handler
446+ >
399447 < TabList
400448 value = { activeTab }
401449 onValueChange = { ( value ) => handleTabChange ( value as SectionName ) }
@@ -422,7 +470,6 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
422470 ) ) }
423471 </ TabList >
424472 </ div >
425-
426473 { /* "More" dropdown button - always show it */ }
427474 < DropdownMenu >
428475 < DropdownMenuTrigger asChild >
0 commit comments