From e36b5fe70b89b3bb6c5aaa28830647b4e374ff70 Mon Sep 17 00:00:00 2001 From: "kemal.earth" <606977+kemaldotearth@users.noreply.github.com> Date: Wed, 28 Jan 2026 14:21:33 +0000 Subject: [PATCH] feat(studio): scroll sql editor tabs to end when longer than container width (#42218) * feat: scroll sql editor tabs to end when longer than container width * feat: more fine tuned * feat: code clean up into hook * chore: run prettier * fix: remove remnant of old useEffect --- apps/studio/components/layouts/Tabs/Tabs.tsx | 5 ++ .../components/layouts/Tabs/Tabs.utils.ts | 50 ++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/apps/studio/components/layouts/Tabs/Tabs.tsx b/apps/studio/components/layouts/Tabs/Tabs.tsx index 02744f6c4e5..e0c3c98bd26 100644 --- a/apps/studio/components/layouts/Tabs/Tabs.tsx +++ b/apps/studio/components/layouts/Tabs/Tabs.tsx @@ -10,6 +10,7 @@ import { horizontalListSortingStrategy, SortableContext } from '@dnd-kit/sortabl import { AnimatePresence, motion } from 'framer-motion' import { Plus, X } from 'lucide-react' import { useRouter } from 'next/router' +import { useEffect } from 'react' import { useParams } from 'common' import { useDashboardHistory } from 'hooks/misc/useDashboardHistory' @@ -28,6 +29,7 @@ import { useEditorType } from '../editors/EditorsLayout.hooks' import { CollapseButton } from './CollapseButton' import { SortableTab } from './SortableTab' import { TabPreview } from './TabPreview' +import { useTabsScroll } from './Tabs.utils' export const EditorTabs = () => { const { ref, id } = useParams() @@ -132,6 +134,8 @@ export const EditorTabs = () => { tabs.handleTabNavigation(id, router) } + const { tabsListRef } = useTabsScroll({ activeTab: tabs.activeTab, tabCount: editorTabs.length }) + return ( { > (null) + const prevTabCountRef = useRef(tabCount) + const isInitialMount = useRef(true) + + useEffect(() => { + if (tabsListRef.current) { + tabsListRef.current.scrollLeft = tabsListRef.current.scrollWidth + } + }, []) + + useEffect(() => { + if (isInitialMount.current) { + isInitialMount.current = false + return + } + + if (!tabsListRef.current) return + + const tabCountIncreased = tabCount > prevTabCountRef.current + + if (tabCountIncreased) { + tabsListRef.current.scrollLeft = tabsListRef.current.scrollWidth + } else if (activeTab) { + const activeTabElement = tabsListRef.current.querySelector( + `[data-state="active"]` + ) as HTMLElement + + if (activeTabElement) { + activeTabElement.scrollIntoView({ + behavior: 'smooth', + block: 'nearest', + inline: 'nearest', + }) + } + } + + prevTabCountRef.current = tabCount + }, [activeTab, tabCount]) + + return { tabsListRef } +}