From 6027566141632b1ba6504dbabeb3f8a602577ae0 Mon Sep 17 00:00:00 2001 From: LukeParkerDev <10430890+Hona@users.noreply.github.com> Date: Mon, 5 Oct 2026 19:11:22 +1000 Subject: [PATCH 1/4] fix(app): clip side panel tabs at the + button --- packages/ui/src/navigation/tabs/tabs.css | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/packages/ui/src/navigation/tabs/tabs.css b/packages/ui/src/navigation/tabs/tabs.css index 04bb6230ed3d..5581e60061a4 100644 --- a/packages/ui/src/navigation/tabs/tabs.css +++ b/packages/ui/src/navigation/tabs/tabs.css @@ -600,27 +600,14 @@ flex: 1 1 0; min-width: 0; width: auto; + padding-inline-end: 0; border-bottom: none; } +/* The end gap lives inside the sticky "+" box. Sticky offsets respect the strip's padding, so padding there + would leave a gap after the "+" where scrolled tabs show through. */ :root body #review-panel [data-component="tabs"] .session-review-v2-tabs-bar [data-slot="tabs-list"] > .sticky { - padding-inline-end: 0; - - [data-component="icon-button-v2"] { - position: relative; - - &::after { - content: ""; - position: absolute; - inset-inline-start: 100%; - top: 50%; - transform: translateY(-50%); - width: 20px; - height: 28px; - background-color: var(--v2-background-bg-base); - pointer-events: none; - } - } + padding-inline-end: 12px; } :root From 6d8164aa9c394a8755ed623344f01abc1d5e9759 Mon Sep 17 00:00:00 2001 From: LukeParkerDev <10430890+Hona@users.noreply.github.com> Date: Tue, 6 Oct 2026 07:49:24 +1000 Subject: [PATCH 2/4] fix(app): align side panel tabs with the review toggle --- packages/app/e2e/regression/review.spec.ts | 19 ++++++++++++------- .../app/src/runtime/extension/side-region.tsx | 10 +++++++--- packages/ui/src/navigation/tabs/tabs.css | 1 + 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/packages/app/e2e/regression/review.spec.ts b/packages/app/e2e/regression/review.spec.ts index b2f35e1d1863..125d71c2d516 100644 --- a/packages/app/e2e/regression/review.spec.ts +++ b/packages/app/e2e/regression/review.spec.ts @@ -890,13 +890,18 @@ for (const direction of ["ltr", "rtl"] as const) { ) }) .toBe(true) - await expect - .poll(async () => { - const box = await panel.locator('[data-slot="session-side-panel-actions"]').boundingBox() - - return box ? box.y + box.height / 2 : undefined - }) - .toBe(closed.y + closed.height / 2) + for (const control of [ + panel.locator('[data-slot="session-side-panel-actions"]'), + panel.getByRole("button", { name: "Open file", exact: true }), + ]) { + await expect + .poll(async () => { + const box = await control.boundingBox() + + return box ? box.y + box.height / 2 : undefined + }) + .toBe(closed.y + closed.height / 2) + } await toggle.press("Enter") await expect(toggle).toHaveAttribute("aria-expanded", "false") await expect(toggle).toBeFocused() diff --git a/packages/app/src/runtime/extension/side-region.tsx b/packages/app/src/runtime/extension/side-region.tsx index 62d1ecb378ed..7c80efa42001 100644 --- a/packages/app/src/runtime/extension/side-region.tsx +++ b/packages/app/src/runtime/extension/side-region.tsx @@ -146,7 +146,12 @@ export function SideRegion(props: { props.region.select(value) }} > -
+ {/* Tabs and actions share the review toggle's row: the session header's 48px, or the 51px + above a side dock's divider. */} +
{ tabList = el @@ -189,8 +194,7 @@ export function SideRegion(props: {
event.stopPropagation()} onClick={(event) => event.stopPropagation()} > diff --git a/packages/ui/src/navigation/tabs/tabs.css b/packages/ui/src/navigation/tabs/tabs.css index 5581e60061a4..92523a0bbee7 100644 --- a/packages/ui/src/navigation/tabs/tabs.css +++ b/packages/ui/src/navigation/tabs/tabs.css @@ -600,6 +600,7 @@ flex: 1 1 0; min-width: 0; width: auto; + height: var(--tabs-bar-height); padding-inline-end: 0; border-bottom: none; } From c8ee366eefd85ae5c1fb543016cd25a14fbe8ec4 Mon Sep 17 00:00:00 2001 From: LukeParkerDev <10430890+Hona@users.noreply.github.com> Date: Tue, 6 Oct 2026 07:59:02 +1000 Subject: [PATCH 3/4] test(app): space the toggle alignment loop --- packages/app/e2e/regression/review.spec.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/app/e2e/regression/review.spec.ts b/packages/app/e2e/regression/review.spec.ts index 125d71c2d516..eee77ff6ea5b 100644 --- a/packages/app/e2e/regression/review.spec.ts +++ b/packages/app/e2e/regression/review.spec.ts @@ -890,6 +890,7 @@ for (const direction of ["ltr", "rtl"] as const) { ) }) .toBe(true) + for (const control of [ panel.locator('[data-slot="session-side-panel-actions"]'), panel.getByRole("button", { name: "Open file", exact: true }), @@ -902,6 +903,7 @@ for (const direction of ["ltr", "rtl"] as const) { }) .toBe(closed.y + closed.height / 2) } + await toggle.press("Enter") await expect(toggle).toHaveAttribute("aria-expanded", "false") await expect(toggle).toBeFocused() From 5d89cfc6d65589eb5978a95ebc07ea70314418f6 Mon Sep 17 00:00:00 2001 From: LukeParkerDev <10430890+Hona@users.noreply.github.com> Date: Tue, 6 Oct 2026 08:05:01 +1000 Subject: [PATCH 4/4] fix(app): stop clipping the left edge of file tab icons --- packages/gui-extensions/src/file/label.tsx | 2 +- packages/gui-extensions/src/file/tabs.css | 6 ++++++ packages/ui/src/navigation/tabs/tabs.css | 5 ----- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/gui-extensions/src/file/label.tsx b/packages/gui-extensions/src/file/label.tsx index a9696b4a04a5..164dcab5b42d 100644 --- a/packages/gui-extensions/src/file/label.tsx +++ b/packages/gui-extensions/src/file/label.tsx @@ -5,7 +5,7 @@ import { getFilename } from "@opencode/util/path" /** A file tab's trigger content. The selected tab's icon colour comes from the tab CSS. */ export function FileVisual(props: { path: string; temporary?: boolean; notFound?: boolean }): JSX.Element { return ( -
+
diff --git a/packages/gui-extensions/src/file/tabs.css b/packages/gui-extensions/src/file/tabs.css index 922af476cee6..57a4a81edd82 100644 --- a/packages/gui-extensions/src/file/tabs.css +++ b/packages/gui-extensions/src/file/tabs.css @@ -5,6 +5,12 @@ padding-inline-end: 4px; } +/* The pill's padding sets the file icon's inset; the trigger clips anything pulled past its edge. */ +:root body #review-panel [data-component="tabs"][data-variant="normal"][data-orientation="horizontal"] [data-slot="tabs-list"] [data-slot="tabs-trigger-wrapper"][data-value^="file://"] +{ + padding-inline-start: 8px; +} + :root body #review-panel [data-component="tabs"][data-variant="normal"][data-orientation="horizontal"] [data-slot="tabs-list"] [data-slot="tabs-trigger-wrapper"]:is([data-value="file:open"], [data-value^="file://"]) [data-slot="tabs-trigger-close-button"] { margin-inline-start: 0; diff --git a/packages/ui/src/navigation/tabs/tabs.css b/packages/ui/src/navigation/tabs/tabs.css index 92523a0bbee7..e46f52578582 100644 --- a/packages/ui/src/navigation/tabs/tabs.css +++ b/packages/ui/src/navigation/tabs/tabs.css @@ -568,11 +568,6 @@ color: var(--v2-text-text-base); } - .tab-fileicon-color, - .tab-fileicon-mono { - margin-inline-start: -2px; - } - .italic { font-style: italic !important; font-variation-settings: "slnt" -10 !important;