From da17b8e53d70d7b820cf63d7c3c47bd852c35fcd Mon Sep 17 00:00:00 2001 From: AutumnNazi <104422820+AutumnNazi@users.noreply.github.com> Date: Thu, 6 Aug 2026 22:42:55 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix(sidebar):=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E8=BF=9E=E6=8E=A5=E6=A0=91=E6=9C=AB=E9=A1=B9=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E5=AE=8C=E6=95=B4=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sidebar/useSidebarSearchModel.tsx | 3 ++- .../sidebarV2Utils.tree-height.test.ts | 20 +++++++++++++++++++ frontend/src/components/sidebarV2Utils.ts | 20 +++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 frontend/src/components/sidebarV2Utils.tree-height.test.ts diff --git a/frontend/src/components/sidebar/useSidebarSearchModel.tsx b/frontend/src/components/sidebar/useSidebarSearchModel.tsx index 3374e1f8..5e1e13c3 100644 --- a/frontend/src/components/sidebar/useSidebarSearchModel.tsx +++ b/frontend/src/components/sidebar/useSidebarSearchModel.tsx @@ -37,6 +37,7 @@ import { filterV2CommandSearchTreeItems, filterV2ExplorerTreeByKind, resolveSidebarNodeConnectionId, + resolveSidebarTreeVirtualHeight, resolveV2ActiveConnectionId, type SidebarTreeNode as TreeNode, type V2CommandSearchItem, @@ -619,7 +620,7 @@ export const useSidebarSearchModel = ({ ), [sidebarTableMetadataFields, treeViewportWidth, v2VisibleTreeData], ); - const effectiveTreeHeight = treeHeight; + const effectiveTreeHeight = resolveSidebarTreeVirtualHeight(treeHeight, isV2Ui); const v2TreeMetrics = useMemo(() => { const databaseTableCounts = new Map(); const objectGroupCounts = new Map(); diff --git a/frontend/src/components/sidebarV2Utils.tree-height.test.ts b/frontend/src/components/sidebarV2Utils.tree-height.test.ts new file mode 100644 index 00000000..8f5dc202 --- /dev/null +++ b/frontend/src/components/sidebarV2Utils.tree-height.test.ts @@ -0,0 +1,20 @@ +import { describe, expect, it } from 'vitest'; + +import { resolveSidebarTreeVirtualHeight } from './sidebarV2Utils'; + +describe('resolveSidebarTreeVirtualHeight', () => { + it('matches the V2 tree virtual viewport to the visible holder height', () => { + expect(resolveSidebarTreeVirtualHeight(500, true)).toBe(464); + }); + + it('keeps the legacy tree height unchanged', () => { + expect(resolveSidebarTreeVirtualHeight(500, false)).toBe(500); + }); + + it('never returns a negative height and preserves subpixel measurements', () => { + expect(resolveSidebarTreeVirtualHeight(20, true)).toBe(0); + expect(resolveSidebarTreeVirtualHeight(Number.NaN, true)).toBe(0); + expect(resolveSidebarTreeVirtualHeight(500.9, true)).toBeCloseTo(464.9); + expect(resolveSidebarTreeVirtualHeight(500.9, false)).toBe(500.9); + }); +}); diff --git a/frontend/src/components/sidebarV2Utils.ts b/frontend/src/components/sidebarV2Utils.ts index b4905bec..c28cf78d 100644 --- a/frontend/src/components/sidebarV2Utils.ts +++ b/frontend/src/components/sidebarV2Utils.ts @@ -76,6 +76,26 @@ export interface SidebarTreeNode { type?: SidebarTreeNodeType; } +// Keep these values aligned with the V2 explorer tree layout in v2-theme.css. +const V2_TREE_HORIZONTAL_SCROLL_RESERVE_PX = 32; +const V2_TREE_CONTENT_TOP_PADDING_PX = 4; + +export const resolveSidebarTreeVirtualHeight = ( + containerHeight: number, + isV2Ui: boolean, +): number => { + if (!Number.isFinite(containerHeight)) return 0; + const normalizedHeight = Math.max(0, containerHeight); + return Math.max( + 0, + normalizedHeight - ( + isV2Ui + ? V2_TREE_HORIZONTAL_SCROLL_RESERVE_PX + V2_TREE_CONTENT_TOP_PADDING_PX + : 0 + ), + ); +}; + export const hasSidebarLazyChildren = (children: unknown): boolean => { return Array.isArray(children) && children.length > 0; };