Compare commits

...

3 Commits

Author SHA1 Message Date
Test 48a95565bc Revert "fix(app): stabilize titlebar tab width"
This reverts commit 90a7fb7058.
2026-06-25 03:40:14 +00:00
Test 90a7fb7058 fix(app): stabilize titlebar tab width 2026-06-25 03:39:07 +00:00
Test dff8020a58 fix(app): shrink titlebar tabs 2026-06-25 03:09:59 +00:00
2 changed files with 38 additions and 34 deletions
+13
View File
@@ -20,6 +20,7 @@
remaining scroll distance > 1px. Hidden defaults make an inactive timeline remaining scroll distance > 1px. Hidden defaults make an inactive timeline
(no overflow) a no-op. Unsupported browsers also degrade to no fades. */ (no overflow) a no-op. Unsupported browsers also degrade to no fades. */
[data-slot="titlebar-tabs"] { [data-slot="titlebar-tabs"] {
container-type: inline-size;
timeline-scope: --titlebar-tabs-scroll; timeline-scope: --titlebar-tabs-scroll;
[data-slot^="titlebar-tabs-fade-"] { [data-slot^="titlebar-tabs-fade-"] {
@@ -27,6 +28,18 @@
} }
} }
@container (max-width: 64px) {
[data-slot="titlebar-tab-link"] {
justify-content: center;
gap: 0;
padding-inline: 0;
}
[data-slot="titlebar-tab-title"] {
display: none;
}
}
@supports (animation-timeline: --titlebar-tabs-scroll) and (timeline-scope: --titlebar-tabs-scroll) { @supports (animation-timeline: --titlebar-tabs-scroll) and (timeline-scope: --titlebar-tabs-scroll) {
[data-slot="titlebar-tabs-scroll"] { [data-slot="titlebar-tabs-scroll"] {
scroll-timeline: --titlebar-tabs-scroll x; scroll-timeline: --titlebar-tabs-scroll x;
+25 -34
View File
@@ -3,7 +3,6 @@ import {
createMemo, createMemo,
createResource, createResource,
createRoot, createRoot,
createSignal,
For, For,
Match, Match,
onMount, onMount,
@@ -33,7 +32,6 @@ import { applyPath, backPath, forwardPath } from "./titlebar-history"
import { projectForSession } from "@/pages/layout/helpers" import { projectForSession } from "@/pages/layout/helpers"
import { SessionTabAvatar } from "@/pages/layout/session-tab-avatar" import { SessionTabAvatar } from "@/pages/layout/session-tab-avatar"
import { makeEventListener } from "@solid-primitives/event-listener" import { makeEventListener } from "@solid-primitives/event-listener"
import { createResizeObserver } from "@solid-primitives/resize-observer"
import { createMediaQuery } from "@solid-primitives/media" import { createMediaQuery } from "@solid-primitives/media"
import { readSessionTabsRemovedDetail, SESSION_TABS_REMOVED_EVENT } from "@/components/titlebar-session-events" import { readSessionTabsRemovedDetail, SESSION_TABS_REMOVED_EVENT } from "@/components/titlebar-session-events"
import { useGlobal } from "@/context/global" import { useGlobal } from "@/context/global"
@@ -421,13 +419,6 @@ export function Titlebar(props: { update?: TitlebarUpdate }) {
].filter((v) => v !== undefined) ].filter((v) => v !== undefined)
}) })
const [tabsAreOverflowing, setTabsAreOverflowing] = createSignal(false)
let tabScrollRef!: HTMLDivElement
function refreshTabsAreOverflowing() {
setTabsAreOverflowing(tabScrollRef.scrollWidth > tabScrollRef.clientWidth)
}
return ( return (
<div <div
class="h-full flex-1 overflow-hidden flex flex-row items-center gap-1.5 px-2 md:pr-3" class="h-full flex-1 overflow-hidden flex flex-row items-center gap-1.5 px-2 md:pr-3"
@@ -465,19 +456,11 @@ export function Titlebar(props: { update?: TitlebarUpdate }) {
/> />
</TooltipV2> </TooltipV2>
<div data-slot="titlebar-tabs" class="relative min-w-0"> <div data-slot="titlebar-tabs" class="relative min-w-0 flex-1">
<div <div
data-slot="titlebar-tabs-scroll" class="flex min-w-0 flex-row items-center overflow-hidden [app-region:no-drag]"
class="flex min-w-0 flex-row items-center gap-1.5 overflow-x-auto no-scrollbar [app-region:no-drag]"
ref={(el) => {
tabScrollRef = el
createResizeObserver(el, refreshTabsAreOverflowing)
}}
> >
<div <div class="flex w-full min-w-0 flex-row items-center gap-[min(6px,1cqw)]">
class="flex min-w-0 flex-row items-center gap-1.5"
ref={(el) => createResizeObserver(el, refreshTabsAreOverflowing)}
>
<For each={tabsStore}> <For each={tabsStore}>
{(tab, i) => { {(tab, i) => {
let ref!: HTMLDivElement let ref!: HTMLDivElement
@@ -574,7 +557,6 @@ export function Titlebar(props: { update?: TitlebarUpdate }) {
onClose={() => tabsStoreActions.removeTab(i())} onClose={() => tabsStoreActions.removeTab(i())}
active={currentTab() === tab} active={currentTab() === tab}
activeServer={tab.server === server.key} activeServer={tab.server === server.key}
forceTruncate={tabsAreOverflowing()}
/> />
)} )}
</Show> </Show>
@@ -631,7 +613,6 @@ export function Titlebar(props: { update?: TitlebarUpdate }) {
aria-label={language.t("command.session.new")} aria-label={language.t("command.session.new")}
/> />
</Show> </Show>
<div class="flex-1" />
<TitlebarV2Right state={v2RightState()} /> <TitlebarV2Right state={v2RightState()} />
<Show when={windows() && !electronWindows()}> <Show when={windows() && !electronWindows()}>
<div data-tauri-decorum-tb class="flex flex-row" /> <div data-tauri-decorum-tb class="flex flex-row" />
@@ -882,7 +863,6 @@ function TabNavItem(props: {
onNavigate: () => void onNavigate: () => void
active?: boolean active?: boolean
activeServer: boolean activeServer: boolean
forceTruncate?: boolean
session: Session session: Session
}) { }) {
const closeTab = (event: MouseEvent) => { const closeTab = (event: MouseEvent) => {
@@ -900,7 +880,8 @@ function TabNavItem(props: {
return ( return (
<div <div
ref={props.ref} ref={props.ref}
class="group relative flex h-7 w-56 shrink-0 flex-row items-center gap-1.5 overflow-hidden whitespace-nowrap rounded-[6px] bg-[var(--tab-bg)] px-1.5 [--tab-bg:var(--v2-background-bg-deep)] hover:[--tab-bg:var(--v2-background-bg-layer-02)] data-[active='true']:[--tab-bg:var(--v2-background-bg-layer-02)]" data-slot="titlebar-tab"
class="group relative flex h-7 min-w-0 max-w-56 flex-1 basis-0 flex-row items-center overflow-hidden whitespace-nowrap rounded-[6px] bg-[var(--tab-bg)] [container-type:inline-size] [--tab-bg:var(--v2-background-bg-deep)] hover:[--tab-bg:var(--v2-background-bg-layer-02)] data-[active='true']:[--tab-bg:var(--v2-background-bg-layer-02)]"
data-active={props.active} data-active={props.active}
onMouseDown={(event) => { onMouseDown={(event) => {
if (event.button !== 1) return if (event.button !== 1) return
@@ -918,7 +899,8 @@ function TabNavItem(props: {
event.preventDefault() event.preventDefault()
props.onNavigate() props.onNavigate()
}} }}
class="flex h-full min-w-0 flex-1 flex-row items-center gap-1.5 text-[13px] font-medium text-v2-text-text-faint group-data-[active='true']:text-v2-text-text-base" data-slot="titlebar-tab-link"
class="flex h-full min-w-0 flex-1 flex-row items-center gap-1.5 px-1.5 text-[13px] font-medium text-v2-text-text-faint group-data-[active='true']:text-v2-text-text-base"
> >
<span data-slot="project-avatar-slot"> <span data-slot="project-avatar-slot">
<SessionTabAvatar <SessionTabAvatar
@@ -928,15 +910,16 @@ function TabNavItem(props: {
activeServer={props.activeServer} activeServer={props.activeServer}
/> />
</span> </span>
<span class="min-w-0 flex-1">{session().title}</span> <span data-slot="titlebar-tab-title" class="min-w-0 flex-1">
{session().title}
</span>
</a> </a>
) )
}} }}
</Show> </Show>
<div <div
class="absolute not-group-hover:not-group-data-[active=true]:not-data-[truncate=true]:left-52 group-hover:right-0 group-data-[active=true]:right-0 data-[truncate=true]:right-0 inset-y-0 flex flex-row items-center pr-1 py-1 w-8 pl-2" class="absolute not-group-hover:not-group-data-[active=true]:left-52 group-hover:right-0 group-data-[active=true]:right-0 inset-y-0 flex flex-row items-center pr-1 py-1 w-8 pl-2"
data-truncate={props.forceTruncate}
> >
<div <div
class="absolute inset-0 rounded-r-[6px] bg-(image:--inactive-bg) group-hover:bg-(image:--active-bg) group-data-[active=true]:bg-(image:--active-bg)" class="absolute inset-0 rounded-r-[6px] bg-(image:--inactive-bg) group-hover:bg-(image:--active-bg) group-data-[active=true]:bg-(image:--active-bg)"
@@ -974,7 +957,8 @@ function DraftTabItem(props: {
<div <div
ref={props.ref} ref={props.ref}
data-active={props.active} data-active={props.active}
class="group relative flex h-7 w-56 shrink-0 flex-row items-center gap-1.5 overflow-hidden rounded-[6px] bg-[var(--tab-bg)] pl-1.5 pr-8 whitespace-nowrap [--tab-bg:var(--v2-background-bg-deep)] hover:[--tab-bg:var(--v2-background-bg-layer-02)] data-[active='true']:[--tab-bg:var(--v2-overlay-simple-overlay-pressed)] focus-within:outline focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-[var(--v2-border-border-focus)]" data-slot="titlebar-tab"
class="group relative flex h-7 min-w-0 max-w-56 flex-1 basis-0 flex-row items-center overflow-hidden rounded-[6px] bg-[var(--tab-bg)] [container-type:inline-size] whitespace-nowrap [--tab-bg:var(--v2-background-bg-deep)] hover:[--tab-bg:var(--v2-background-bg-layer-02)] data-[active='true']:[--tab-bg:var(--v2-overlay-simple-overlay-pressed)] focus-within:outline focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-[var(--v2-border-border-focus)]"
onMouseDown={(event) => { onMouseDown={(event) => {
if (event.button !== 1) return if (event.button !== 1) return
closeTab(event) closeTab(event)
@@ -986,12 +970,15 @@ function DraftTabItem(props: {
event.preventDefault() event.preventDefault()
props.onNavigate() props.onNavigate()
}} }}
class="flex h-full min-w-0 flex-1 flex-row items-center gap-1.5 overflow-hidden text-[13px] font-medium leading-5 text-v2-text-text-faint group-data-[active='true']:text-[var(--v2-text-text-base)]" data-slot="titlebar-tab-link"
class="flex h-full min-w-0 flex-1 flex-row items-center gap-1.5 overflow-hidden pl-1.5 pr-8 text-[13px] font-medium leading-5 text-v2-text-text-faint group-data-[active='true']:text-[var(--v2-text-text-base)]"
> >
<span class="flex size-4 shrink-0 rotate-90 items-center justify-center"> <span class="flex size-4 shrink-0 rotate-90 items-center justify-center">
<IconV2 name="edit" /> <IconV2 name="edit" />
</span> </span>
<span class="truncate leading-5">{props.title}</span> <span data-slot="titlebar-tab-title" class="truncate leading-5">
{props.title}
</span>
</a> </a>
<div class="absolute right-0 inset-y-0 flex w-7 items-center justify-center"> <div class="absolute right-0 inset-y-0 flex w-7 items-center justify-center">
<IconButtonV2 <IconButtonV2
@@ -1019,7 +1006,8 @@ function NewSessionTabItem(props: { ref?: HTMLDivElement; href: string; title: s
return ( return (
<div <div
ref={props.ref} ref={props.ref}
class="group relative flex h-7 w-56 shrink-0 flex-row items-center gap-1.5 overflow-hidden rounded-[6px] bg-[var(--v2-overlay-simple-overlay-pressed)] pl-1.5 pr-8 whitespace-nowrap focus-within:outline focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-[var(--v2-border-border-focus)]" data-slot="titlebar-tab"
class="group relative flex h-7 min-w-0 max-w-56 flex-1 basis-0 flex-row items-center overflow-hidden rounded-[6px] bg-[var(--v2-overlay-simple-overlay-pressed)] [container-type:inline-size] whitespace-nowrap focus-within:outline focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-[var(--v2-border-border-focus)]"
onMouseDown={(event) => { onMouseDown={(event) => {
if (event.button !== 1) return if (event.button !== 1) return
closeTab(event) closeTab(event)
@@ -1028,12 +1016,15 @@ function NewSessionTabItem(props: { ref?: HTMLDivElement; href: string; title: s
<a <a
href={props.href} href={props.href}
aria-current="page" aria-current="page"
class="flex h-full min-w-0 flex-1 flex-row items-center gap-1.5 overflow-hidden text-[13px] font-medium leading-5 text-[var(--v2-text-text-base)]" data-slot="titlebar-tab-link"
class="flex h-full min-w-0 flex-1 flex-row items-center gap-1.5 overflow-hidden pl-1.5 pr-8 text-[13px] font-medium leading-5 text-[var(--v2-text-text-base)]"
> >
<span class="flex size-4 shrink-0 rotate-90 items-center justify-center"> <span class="flex size-4 shrink-0 rotate-90 items-center justify-center">
<IconV2 name="edit" /> <IconV2 name="edit" />
</span> </span>
<span class="truncate leading-5">{props.title}</span> <span data-slot="titlebar-tab-title" class="truncate leading-5">
{props.title}
</span>
</a> </a>
<div class="absolute right-0 inset-y-0 flex w-7 items-center justify-center"> <div class="absolute right-0 inset-y-0 flex w-7 items-center justify-center">
<IconButtonV2 <IconButtonV2