feat(header): session tabs — a horizontal working set of open sessions

Web/desktop header replaces the single session title with a strip of
soft pill tabs, one per session the user has opened (sidebar, palette
or deep link — opening anywhere adds a tab once). The active tab is the
familiar title block — rename, meta row and the full session menu —
inside a gently selected pill; a brand-new draft shows as a transient
pill until its session exists. Inactive tabs show the title with a
hover-revealed "..." menu (close tab, close other tabs, copy id) that
nudges the text like sidebar rows, and close by middle-click too.

Tabs drag to reorder, scroll behind the right-side header buttons with
soft fade edges, respect the reserved window-controls inset, and
persist across reloads. Closing the active tab activates its neighbour
(or opens a new draft when it was the last). Tab ids whose session is
not in the loaded list stay stored but hidden, so a partial session
list never destroys the working set. VS Code keeps the plain title;
mobile is untouched.
This commit is contained in:
Bohdan Triapitsyn
2026-08-24 17:07:09 +03:00
parent 7bd27d44d6
commit a3813f57e9
15 changed files with 645 additions and 1 deletions
+4
View File
@@ -482,6 +482,10 @@ export const dict: Record<I18nKey, string> = {
'sessions.archivePage.deleteSessionAria': '{title} 삭제',
'sessions.archivePage.restoreSessionAria': '{title} 복원',
'sessions.switcher.openAria': '세션 전환기 열기',
'header.sessionTabs.stripAria': '열린 세션',
'header.sessionTabs.tabMenuAria': '세션 탭 작업',
'header.sessionTabs.closeTab': '탭 닫기',
'header.sessionTabs.closeOtherTabs': '다른 탭 닫기',
'sessions.switcher.empty': '최근 세션 없음',
'sessions.switcher.draftTitle': '새 세션',
'sessions.sidebar.updateCheck.errorTitle': '업데이트 확인 실패',