fix: preserve scroll position when switching tabs in settings

This commit is contained in:
淡草 2025-09-02 08:00:39 +08:00
parent ae8a639d6f
commit ad07bf4e0d
2 changed files with 21 additions and 6 deletions

View file

@ -17,7 +17,7 @@ export const TabHeader = ({ className, children, ...props }: TabProps) => (
</div>
)
export const TabContent = ({ className, children, ...props }: TabProps) => {
export const TabContent = forwardRef<HTMLDivElement, TabProps>(({ className, children, ...props }, ref) => {
const { renderContext } = useExtensionState()
const onWheel = useCallback(
@ -40,11 +40,11 @@ export const TabContent = ({ className, children, ...props }: TabProps) => {
)
return (
<div className={cn("flex-1 overflow-auto p-5", className)} onWheel={onWheel} {...props}>
<div ref={ref} className={cn("flex-1 overflow-auto p-5", className)} onWheel={onWheel} {...props}>
{children}
</div>
)
}
})
export const TabList = forwardRef<
HTMLDivElement,

View file

@ -112,6 +112,11 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
: "providers",
)
const scrollPositions = useRef<Record<SectionName, number>>(
Object.fromEntries(sectionNames.map((s) => [s, 0])) as Record<SectionName, number>,
)
const contentRef = useRef<HTMLDivElement | null>(null)
const prevApiConfigName = useRef(currentApiConfigName)
const confirmDialogHandler = useRef<() => void>()
@ -398,12 +403,22 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
// Handle tab changes with unsaved changes check
const handleTabChange = useCallback(
(newTab: SectionName) => {
// Directly switch tab without checking for unsaved changes
if (contentRef.current) {
scrollPositions.current[activeTab] = contentRef.current.scrollTop
}
setActiveTab(newTab)
},
[], // No dependency on isChangeDetected needed anymore
[activeTab],
)
useEffect(() => {
requestAnimationFrame(() => {
if (contentRef.current) {
contentRef.current.scrollTop = scrollPositions.current[activeTab] ?? 0
}
})
}, [activeTab])
// Store direct DOM element refs for each tab
const tabRefs = useRef<Record<SectionName, HTMLButtonElement | null>>(
Object.fromEntries(sectionNames.map((name) => [name, null])) as Record<SectionName, HTMLButtonElement | null>,
@ -579,7 +594,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
</TabList>
{/* Content area */}
<TabContent className="p-0 flex-1 overflow-auto">
<TabContent ref={contentRef} className="p-0 flex-1 overflow-auto">
{/* Providers Section */}
{activeTab === "providers" && (
<div>