diff --git a/apps/desktop/src/components/layout/EditorGroupTabBar.vue b/apps/desktop/src/components/layout/EditorGroupTabBar.vue index 55cbb46e7f..74cf19ceba 100644 --- a/apps/desktop/src/components/layout/EditorGroupTabBar.vue +++ b/apps/desktop/src/components/layout/EditorGroupTabBar.vue @@ -1104,6 +1104,11 @@ function tabColorStyle(tab: QueryTab): CSSProperties | undefined { : { borderColor: hexToRgba(color, 0.18) }), } as CSSProperties; } + // Keep horizontal tabs quiet by default; group headers and rails already + // provide the connection identity, while the selected tab gets the wash. + if (!isTabActive(tab)) { + return undefined; + } return sharedTabColorStyle(tab, isTabActive(tab), isClassicLayout.value); } diff --git a/apps/desktop/src/components/layout/__tests__/EditorGroupTabBar.groups.spec.ts b/apps/desktop/src/components/layout/__tests__/EditorGroupTabBar.groups.spec.ts index 21588985a3..c811364214 100644 --- a/apps/desktop/src/components/layout/__tests__/EditorGroupTabBar.groups.spec.ts +++ b/apps/desktop/src/components/layout/__tests__/EditorGroupTabBar.groups.spec.ts @@ -186,6 +186,41 @@ describe("EditorGroupTabBar group behavior", () => { }, ); + it.each(["classic", "separated"] as const)("keeps only the active horizontal grouped tab tinted across placement changes in %s layout", async (layout) => { + const store = useQueryStore(); + const settings = useSettingsStore(); + const connectionStore = useConnectionStore(); + connectionStore.connections = [{ id: "pg-1", name: "Postgres", db_type: "postgres", driver_profile: "postgres", color: "#3b82f6" } as ConnectionConfig]; + settings.editorSettings.appLayout = layout; + settings.editorSettings.tabGroupMode = "connection"; + settings.editorSettings.tabPlacement = "top"; + const activeTabId = store.createTab("pg-1", "app", "PG 1", "query"); + const inactiveTabId = store.createTab("pg-1", "app", "PG 2", "query"); + const { app, host } = mountBar(store.groups[0]!.id, store.tabs.slice(), activeTabId, pinia); + + try { + for (const placement of ["top", "bottom"] as const) { + settings.editorSettings.tabPlacement = placement; + await settle(); + // Changing placement may replace the strip's nodes; inspect the + // currently rendered tabs instead of retaining horizontal elements. + const activeTab = host.querySelector(`[data-tab-id="${activeTabId}"]`)!; + const inactiveTab = host.querySelector(`[data-tab-id="${inactiveTabId}"]`)!; + expect(activeTab.getAttribute("data-active-tab")).toBe("true"); + expect(activeTab.style.getPropertyValue("--app-tab-background")).not.toBe(""); + expect(inactiveTab.getAttribute("data-active-tab")).toBe("false"); + expect(inactiveTab.style.getPropertyValue("--app-tab-background")).toBe(""); + // Vertical grouped selection can be painted by CSS instead of an + // inline background. Returning to horizontal must restore its wash. + settings.editorSettings.tabPlacement = "left"; + await settle(); + } + } finally { + app.unmount(); + host.remove(); + } + }); + it("renders one header per connection cluster and collapses it to a count badge", async () => { const store = useQueryStore(); const settings = useSettingsStore(); diff --git a/docs/assets/pr-horizontal-tab-selection/horizontal-grouped-tabs.png b/docs/assets/pr-horizontal-tab-selection/horizontal-grouped-tabs.png new file mode 100644 index 0000000000..173d4c0a11 Binary files /dev/null and b/docs/assets/pr-horizontal-tab-selection/horizontal-grouped-tabs.png differ