fix(desktop): restore tab bar after layout changes

This commit is contained in:
zipg authored and GitHub committed 2026-09-10 00:42:36 +08:00
1 parent ce3bd1c8ed
commit bc4ed3b89f
5 files changed
+36 -3

No files matched your search

@@ -92,7 +92,10 @@ const queryStore = useQueryStore();
const settingsStore = useSettingsStore();
const toolbar = inject(EDITOR_TOOLBAR_ACTIONS, createNoopEditorToolbarActions());
const tabBarPortal = inject(GROUP_TAB_BAR_PORTAL, null);
const tabBarTarget = computed(() => tabBarPortal?.targets.get(props.groupId));
const tabBarTarget = computed(() => {
if (!tabBarPortal?.active.value) return undefined;
return tabBarPortal.targets.get(props.groupId);
});
const groupTabs = computed(() => {
const byId = new Map(queryStore.tabs.map((tab) => [tab.id, tab]));
return props.tabIds.map((id) => byId.get(id)).filter((tab): tab is QueryTab => !!tab);
@@ -328,6 +328,28 @@ describe("AppTabBar group navigation portal", () => {
expect(warnings).toEqual([]);
});
it("moves a horizontal bar to the workspace rail after settings releases its portal", async () => {
const { host, settings, actions, warnings } = mountNavigation("top");
await settle();
const bar = element(host, ".editor-group[data-group-id='main'] [data-main-tab-bar]");
actions.activateSettingsPage();
await settle();
expect(element(host, "[data-special-page-tab-target='main']").contains(bar)).toBe(true);
actions.closeSettingsPage();
await settle();
expect(element(host, ".editor-group[data-group-id='main']").contains(bar)).toBe(true);
settings.editorSettings.tabGroupMode = "database-type";
settings.editorSettings.tabPlacement = "left";
await settle();
expect(element(host, "[data-workspace-tab-target='main']").contains(bar)).toBe(true);
expect(element(host, "[data-special-page-workspace]").style.display).toBe("none");
expect(warnings).toEqual([]);
});
it.each(["left", "right"] as const)("synchronizes %s rail width and collapse with the persistent bar", async (placement) => {
const { host, navigation, warnings } = mountNavigation(placement);
await settle();
@@ -14,6 +14,7 @@ describe("AppTabBar shared group navigation", () => {
expect(tabBarSource).not.toContain("data-return-tab");
expect(tabBarSource).not.toContain("createRenameDuplicateTabItems");
expect(groupSource).toContain("<Teleport defer");
expect(groupSource).toContain("if (!tabBarPortal?.active.value) return undefined;");
expect(groupSource).toContain(':disabled="!tabBarPortal?.active.value || !tabBarTarget"');
});
@@ -158,10 +158,11 @@ describe("EditorGroupTabBar semantic tab groups", () => {
expect(source).toContain(':data-group-mode="settingsStore.editorSettings.tabGroupMode"');
expect(sharedStyles).toContain(".app-tab-bar:not(.vertical-tab-layout) .tab-group-header");
expect(sharedStyles).toMatch(/\.app-tab-bar\.classic-tab-layout:not\(\.vertical-tab-layout\) \.tab-group-header-content\s*\{[^}]*height:\s*100%;[^}]*border-radius:\s*0;/s);
expect(sharedStyles).toMatch(/\.app-tab-bar\.classic-tab-layout:not\(\.vertical-tab-layout\):not\(:has\(\.wrap-mode\)\)\[data-group-mode="none"\] \.app-tab-pill\s*\{[^}]*border-right-width:\s*0\.5px;/s);
expect(sharedStyles).toMatch(/\.tab-overflow-control\s*\{[^}]*width:\s*34px;[^}]*flex:\s*0 0 34px;/s);
expect(sharedStyles).toContain("padding-inline-end: 2.125rem;");
expect(sharedStyles).toContain("inset-inline-end: 2.125rem;");
expect(sharedStyles).toMatch(/\.app-tab-bar:not\(\.vertical-tab-layout\)\[data-placement="top"\] \.tab-overflow-control::before\s*\{[^}]*inset-inline:\s*-0\.25rem 0;/s);
expect(sharedStyles).toMatch(/\.app-tab-bar:not\(\.vertical-tab-layout\)\[data-placement="top"\] \.tab-overflow-control::before\s*\{[^}]*inset-inline:\s*-0\.25rem 0;[^}]*background:\s*transparent;/s);
expect(sharedStyles).toMatch(/\.app-tab-scroll\.wrap-mode\.classic-wrap \.tab-group-header,[\s\S]*?\.tab-group-header-content\s*\{[^}]*height:\s*2rem !important;/s);
expect(sharedStyles).toMatch(/\.app-tab-scroll\.wrap-mode\.classic-wrap \.tab-group-header:not\(\.tab-group-header--collapsed\)::after\s*\{[^}]*right:\s*-1px;/s);
expect(sharedStyles).toContain(".app-tab-bar:not(.vertical-tab-layout) .tab-group-header::after");
@@ -213,7 +213,7 @@
z-index: -1;
inset-block: 0;
inset-inline: -0.25rem 0;
background: color-mix(in srgb, var(--background) 48%, transparent);
background: transparent;
pointer-events: none;
}
@@ -587,6 +587,12 @@
border-radius: 0;
}
/* A one-pixel CSS border becomes visually heavy on scaled displays. Keep the
* classic ungrouped single-row separators as the thinnest available rule. */
.app-tab-bar.classic-tab-layout:not(.vertical-tab-layout):not(:has(.wrap-mode))[data-group-mode="none"] .app-tab-pill {
border-right-width: 0.5px;
}
.app-tab-bar:not(.vertical-tab-layout) .tab-group-header:hover .tab-group-header-content,
.app-tab-bar:not(.vertical-tab-layout) .tab-group-header--active .tab-group-header-content {
background: color-mix(in srgb, var(--tab-group-color) 18%, transparent);