fix(sidebar): restore database-first sticky headers

This commit is contained in:
t8y2 committed 2026-08-25 10:33:13 +08:00
1 parent 418951c1e2
commit 0aa18257e7
4 files changed
+76 -13

No files matched your search

@@ -785,15 +785,14 @@ function readExpandedSidebarSchemas(): Array<{ id: string; label: string }> {
return expanded;
}
// The plain (non-virtualized) renderer keeps the sticky database/schema header
// via native CSS position: sticky on the container rows, mirroring the overlay
// the virtual branch renders. Only container rows stick; children scroll under
// them until the next container takes over.
function isPlainStickyContainerNode(node: TreeNode): boolean {
// The plain (non-virtualized) renderer uses the same container selection as the
// virtual sticky overlay: database containers take precedence, while schema
// containers stick only in trees without a database-level container.
function isPlainStickyContainerNode(index: number): boolean {
// Mirror the virtual branch's sticky overlay: both suppress sticky headers
// while a search filter is active so filtered rows don't pin at the top.
if (isTreeSearchFiltering.value) return false;
return DATABASE_LEVEL_TYPES.has(node.type) || SCHEMA_LEVEL_TYPES.has(node.type);
return flatTreeIndex.value.stickyContainerIndexByIndex[index] === index;
}
const sidebarLayoutMonitor = createSidebarLayoutMonitor({
@@ -2506,7 +2505,7 @@ defineExpose({ focusSearch, createNewGroup, collapseAllTreeNodes, locateTabInSid
/>
</template>
</RecycleScroller>
<div v-if="stickyNode" class="sticky-database-header pointer-events-auto absolute inset-x-0 top-0 z-[5] border-b border-border/60" :style="stickyHeaderStyle">
<div v-if="stickyNode" class="sticky-database-header pointer-events-auto absolute inset-x-0 top-0 z-[5]" :style="stickyHeaderStyle">
<TreeItem
:node="stickyNode.node"
:depth="stickyNode.depth"
@@ -2539,7 +2538,7 @@ defineExpose({ focusSearch, createNewGroup, collapseAllTreeNodes, locateTabInSid
<div ref="plainTreeScrollerRef" class="sidebar-tree connection-tree-scroller h-full overflow-y-auto" :class="sidebarTreeOverflowClass" :style="sidebarTreeScrollerStyle" @click="clearSidebarSelection" @scroll.passive="onTreeScroll">
<div class="connection-tree-content">
<TreeItem
v-for="item in flatNodes"
v-for="(item, index) in flatNodes"
:key="item.renderKey"
:node="item.node"
:depth="item.depth"
@@ -2548,7 +2547,7 @@ defineExpose({ focusSearch, createNewGroup, collapseAllTreeNodes, locateTabInSid
:pending-rename="pendingRenameNodeId === item.node.id"
:highlighted="highlightedNodeId === item.id"
:comment-label-width="sidebarCommentLabelWidths.get(item.node.id)"
:sticky-header="isPlainStickyContainerNode(item.node)"
:sticky-header="isPlainStickyContainerNode(index)"
@context-menu="(event, node) => openSidebarContextMenu(event, node, contextMenuSlot.onContextMenu)"
@rename-started="pendingRenameNodeId = null"
@group-created="startRenamingCreatedGroup"
@@ -1380,7 +1380,7 @@ function onKeydown(event: KeyboardEvent) {
</LightTooltip>
</div>
<div v-else @contextmenu="onTreeItemContextMenu">
<div v-else :class="{ 'sidebar-tree-item--sticky': stickyHeader }" @contextmenu="onTreeItemContextMenu">
<LightTooltip :text="visibleLabel(node)" :disabled="isTooltipDisabled()" side="right" :side-offset="8" :delay="0" :close-delay="30" :surface="detailTooltip ? 'popover' : 'foreground'">
<div
ref="rowRef"
@@ -1399,7 +1399,6 @@ function onKeydown(event: KeyboardEvent) {
'tree-item-active': selectionVisual.rowSelected,
'tree-item-active--selection-set': selectionVisual.usesSelectionSetHighlight && selectionVisual.rowSelected,
'tree-item-highlight': highlighted,
'sidebar-tree-item--sticky': stickyHeader,
},
]"
:tabindex="selectionVisual.selected || selectionVisual.multiSelected ? 0 : -1"
@@ -1635,7 +1634,6 @@ function onKeydown(event: KeyboardEvent) {
top: 0;
z-index: 2;
background-color: var(--background);
border-bottom: 1px solid var(--border);
}
.tree-item-connection-tint:hover::before {