Tab strip scrolls horizontally on overflow

Tabs live in their own min-w-0 overflow-x-auto container (scrollbar hidden,
trackpad scrolls); the new-tab button and the options gear sit outside it and
stay pinned. The active tab scrolls into view when it changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jokin
2026-07-11 19:13:18 +02:00
co-authored by Claude Fable 5
parent 70947da129
commit 169d3ea4d8
+20 -2
View File
@@ -1,4 +1,4 @@
import { Component, inject, signal } from '@angular/core';
import { Component, ElementRef, effect, inject, signal, viewChild } from '@angular/core';
import { NgIcon } from '@ng-icons/core';
import { PanelsService } from '../panels.service';
import { IS_MAC_CHROME } from '../platform';
@@ -25,10 +25,15 @@ const CONCURRENCY_CHOICES = [2, 3, 4, 6, 8] as const;
[class.pl-20]="isMacChrome"
[class.pl-1.5]="!isMacChrome"
[class.pt-1]="!isMacChrome"
>
<div
#tabScroll
class="flex min-w-0 items-center gap-0.5 overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
>
@for (ws of panels.workspaces(); track ws.id; let i = $index) {
<div
class="group relative flex max-w-52 items-center rounded-md electrobun-webkit-app-region-no-drag"
[attr.data-tab-id]="ws.id"
class="group relative flex max-w-52 shrink-0 items-center rounded-md electrobun-webkit-app-region-no-drag"
[class.bg-accent]="ws.id === panels.activeWorkspaceId()"
[class.opacity-50]="draggedId() === ws.id"
[style.box-shadow]="dropIndicatorShadow(i)"
@@ -69,6 +74,7 @@ const CONCURRENCY_CHOICES = [2, 3, 4, 6, 8] as const;
}
</div>
}
</div>
<button
(click)="panels.newWorkspace()"
title="New tab (⌘T)"
@@ -201,6 +207,18 @@ export class TabBar {
readonly draggedId = signal<number | null>(null);
readonly dropTarget = signal<{ index: number; before: boolean } | null>(null);
private readonly tabScroll = viewChild.required<ElementRef<HTMLDivElement>>('tabScroll');
constructor() {
// keep the active tab visible when the strip overflows
effect(() => {
const id = this.panels.activeWorkspaceId();
this.tabScroll()
.nativeElement.querySelector(`[data-tab-id="${id}"]`)
?.scrollIntoView({ inline: 'nearest', block: 'nearest' });
});
}
close(event: MouseEvent, id: number): void {
event.stopPropagation();
this.panels.closeWorkspace(id);