diff --git a/src/renderer/components/TabBar/TabBar.tsx b/src/renderer/components/TabBar/TabBar.tsx index 5a6eebc..0748a4f 100644 --- a/src/renderer/components/TabBar/TabBar.tsx +++ b/src/renderer/components/TabBar/TabBar.tsx @@ -20,51 +20,55 @@ export function TabBar() { const closeAllTabs = useTabStore(s => s.closeAllTabs) const closeTabsToRight = useTabStore(s => s.closeTabsToRight) - const tabBarRef = useRef(null) const tabListRef = useRef(null) const [menu, setMenu] = useState({ visible: false, x: 0, y: 0, tabId: '' }) - // 支持鼠标滚轮水平滚动标签栏 - useEffect(() => { - const tabBar = tabBarRef.current - if (!tabBar) return + // 滚动到活动标签 + const scrollToActiveTab = useCallback(() => { + const tabList = tabListRef.current + if (!tabList) return + const activeTab = tabList.querySelector('.tab-item.active') as HTMLElement + if (!activeTab) return - const handleWheel = (e: WheelEvent) => { - const tabList = tabListRef.current - if (!tabList) return + const listRect = tabList.getBoundingClientRect() + const tabRect = activeTab.getBoundingClientRect() - // 只有当标签列表有水平滚动空间时才处理 - const hasHorizontalScroll = tabList.scrollWidth > tabList.clientWidth - if (!hasHorizontalScroll) return - - // 阻止默认的垂直滚动 - e.preventDefault() - e.stopPropagation() - - // 计算滚动量:优先使用 deltaX(触控板左右滑动),否则用 deltaY(鼠标滚轮) - const scrollAmount = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? e.deltaX : e.deltaY - - // 应用滚动 - tabList.scrollLeft += scrollAmount + // 如果标签在可视区域左侧之外 + if (tabRect.left < listRect.left) { + tabList.scrollLeft -= (listRect.left - tabRect.left + 20) + } + // 如果标签在可视区域右侧之外 + else if (tabRect.right > listRect.right) { + tabList.scrollLeft += (tabRect.right - listRect.right + 20) } - - // 绑定到 #tab-bar 上,确保能捕获所有滚轮事件 - tabBar.addEventListener('wheel', handleWheel, { passive: false }) - return () => tabBar.removeEventListener('wheel', handleWheel) }, []) // 自动滚动到活动标签 useEffect(() => { - if (!tabListRef.current || !activeTabId) return - - // 使用 requestAnimationFrame 确保 DOM 已更新 - requestAnimationFrame(() => { - const activeTab = tabListRef.current?.querySelector('.tab-item.active') - if (activeTab) { - activeTab.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' }) - } - }) - }, [activeTabId]) + requestAnimationFrame(scrollToActiveTab) + }, [activeTabId, scrollToActiveTab]) + + // 支持鼠标滚轮水平滚动标签栏 + useEffect(() => { + const tabList = tabListRef.current + if (!tabList) return + + const handleWheel = (e: WheelEvent) => { + // 检查是否有水平溢出 + if (tabList.scrollWidth <= tabList.clientWidth) return + + // 阻止默认滚动 + e.preventDefault() + + // 计算滚动量:支持触控板 deltaX 和鼠标滚轮 deltaY + const delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? e.deltaX : e.deltaY + tabList.scrollLeft += delta + } + + // 直接绑定到 tabList,使用 passive: false 允许 preventDefault + tabList.addEventListener('wheel', handleWheel, { passive: false }) + return () => tabList.removeEventListener('wheel', handleWheel) + }, []) const handleClose = useCallback((e: React.MouseEvent, tabId: string) => { e.stopPropagation() @@ -144,7 +148,7 @@ export function TabBar() { if (tabs.length === 0) return null return ( -
+
{tabs.map(tab => (