-
Notifications
You must be signed in to change notification settings - Fork 2.5k
fix: preserve scroll position when switching tabs in settings #7587
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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>, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The scroll positions are stored indefinitely in the ref. While not critical for a small number of tabs, consider if any cleanup is needed when the component unmounts to prevent potential memory leaks in long-running sessions. |
||
| ) | ||
| const contentRef = useRef<HTMLDivElement | null>(null) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider using a more descriptive variable name like |
||
|
|
||
| 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]) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider adding test coverage for the scroll position preservation functionality. The PR checklist indicates "Testing" is unchecked. Adding tests would help ensure this feature works correctly and prevent regressions. You could test:
|
||
|
|
||
| // 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> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The forwardRef component should have a display name for better debugging and React DevTools support. Consider adding:
right after the component definition.