| author | |
| committer | |
| log | f47e74004af232f0e3df8dc10093601d1c2c3ea3 |
| tree | f71a6148843dad621f5cb293bbfaa6f3f4f7ae3b |
| parent | 31c1c5996f88e3acf1566adc11c9b51ac7561554 |
| signature | Signed by PGP key B5690EEEBB952194 |
3 files changed, 28 insertions(+), 18 deletions(-)
apps/web/src/components/BranchToolbar.tsx+7-5| ... | @@ -265,8 +265,10 @@ function useLabelsOverflow(element: HTMLDivElement | null): boolean { | ... | @@ -265,8 +265,10 @@ function useLabelsOverflow(element: HTMLDivElement | null): boolean { |
| 265 | let needed = 0; | 265 | let needed = 0; |
| 266 | let groups = 0; | 266 | let groups = 0; |
| 267 | for (const child of current.children) { | 267 | for (const child of current.children) { |
| 268 | if (!(child instanceof HTMLElement) || child.offsetWidth <= 1) continue; | 268 | if (!(child instanceof HTMLElement)) continue; |
| 269 | needed += contentWidth(child); | 269 | const width = contentWidth(child); |
| 270 | if (width <= 1) continue; | ||
| 271 | needed += width; | ||
| 270 | groups += 1; | 272 | groups += 1; |
| 271 | } | 273 | } |
| 272 | needed += stripGap * Math.max(0, groups - 1); | 274 | needed += stripGap * Math.max(0, groups - 1); |
| ... | @@ -356,7 +358,7 @@ function useLabelsOverflow(element: HTMLDivElement | null): boolean { | ... | @@ -356,7 +358,7 @@ function useLabelsOverflow(element: HTMLDivElement | null): boolean { |
| 356 | // Label widths can change without the strip box moving (font family or | 358 | // Label widths can change without the strip box moving (font family or |
| 357 | // size preferences), so re-measure on every render as well as on resize | 359 | // size preferences), so re-measure on every render as well as on resize |
| 358 | // and font loads. | 360 | // and font loads. |
| 359 | useEffect(() => { | 361 | useLayoutEffect(() => { |
| 360 | measure(); | 362 | measure(); |
| 361 | }); | 363 | }); |
| 362 | 364 | ||
| ... | @@ -487,7 +489,7 @@ export const BranchToolbar = memo(function BranchToolbar({ | ... | @@ -487,7 +489,7 @@ export const BranchToolbar = memo(function BranchToolbar({ |
| 487 | onUsePreviousWorktree={onUsePreviousWorktree} | 489 | onUsePreviousWorktree={onUsePreviousWorktree} |
| 488 | /> | 490 | /> |
| 489 | ) : ( | 491 | ) : ( |
| 490 | <div className="flex min-w-0 flex-1 items-center gap-1"> | 492 | <div className="flex min-w-10 flex-1 items-center gap-1"> |
| 491 | {showEnvironmentIndicator && availableEnvironments && ( | 493 | {showEnvironmentIndicator && availableEnvironments && ( |
| 492 | <> | 494 | <> |
| 493 | <BranchToolbarEnvironmentSelector | 495 | <BranchToolbarEnvironmentSelector |
| ... | @@ -520,7 +522,7 @@ export const BranchToolbar = memo(function BranchToolbar({ | ... | @@ -520,7 +522,7 @@ export const BranchToolbar = memo(function BranchToolbar({ |
| 520 | 522 | ||
| 521 | {showGitControls ? ( | 523 | {showGitControls ? ( |
| 522 | <BranchToolbarBranchSelector | 524 | <BranchToolbarBranchSelector |
| 523 | className="min-w-0 flex-1 justify-end md:ml-auto md:flex-none" | 525 | className="min-w-0 flex-1 justify-end md:ml-auto md:flex-initial" |
| 524 | environmentId={environmentId} | 526 | environmentId={environmentId} |
| 525 | threadId={threadId} | 527 | threadId={threadId} |
| 526 | {...(draftId ? { draftId } : {})} | 528 | {...(draftId ? { draftId } : {})} |
apps/web/src/components/BranchToolbarEnvModeSelector.tsx+14-9| ... | @@ -51,20 +51,25 @@ export const BranchToolbarEnvModeSelector = memo(function BranchToolbarEnvModeSe | ... | @@ -51,20 +51,25 @@ export const BranchToolbarEnvModeSelector = memo(function BranchToolbarEnvModeSe |
| 51 | if (envLocked) { | 51 | if (envLocked) { |
| 52 | return ( | 52 | return ( |
| 53 | <span | 53 | <span |
| 54 | className="inline-flex h-7 shrink-0 items-center gap-1 border border-transparent px-[calc(--spacing(3)-1px)] text-sm font-medium text-muted-foreground/70 sm:h-6 sm:text-xs" | 54 | className="inline-flex h-7 min-w-0 items-center gap-1 border border-transparent px-[calc(--spacing(3)-1px)] text-sm font-medium text-muted-foreground/70 sm:h-6 sm:text-xs" |
| 55 | data-composer-context-control | 55 | data-composer-context-control |
| 56 | > | 56 | > |
| 57 | {activeWorktreePath ? ( | 57 | {activeWorktreePath ? ( |
| 58 | <> | 58 | <FolderGitIcon className="size-3 shrink-0" /> |
| 59 | <FolderGitIcon className="size-3" /> | ||
| 60 | {resolveLockedWorkspaceLabel(activeWorktreePath)} | ||
| 61 | </> | ||
| 62 | ) : ( | 59 | ) : ( |
| 63 | <> | 60 | <FolderIcon className="size-3 shrink-0" /> |
| 64 | <FolderIcon className="size-3" /> | ||
| 65 | {resolveLockedWorkspaceLabel(activeWorktreePath)} | ||
| 66 | </> | ||
| 67 | )} | 61 | )} |
| 62 | <span | ||
| 63 | data-composer-label | ||
| 64 | className="min-w-0 max-w-[240px] group-data-[compact]/composer-context:max-w-0" | ||
| 65 | > | ||
| 66 | <span | ||
| 67 | data-composer-label-motion | ||
| 68 | className="block w-full min-w-0 max-w-[240px] origin-left truncate transition-[opacity,transform] duration-180 ease-[cubic-bezier(0.32,0.72,0,1)] group-data-[compact]/composer-context:[transform:translateX(-0.25rem)_scaleX(0.95)] group-data-[compact]/composer-context:opacity-0 motion-reduce:transform-none motion-reduce:transition-opacity" | ||
| 69 | > | ||
| 70 | {resolveLockedWorkspaceLabel(activeWorktreePath)} | ||
| 71 | </span> | ||
| 72 | </span> | ||
| 68 | </span> | 73 | </span> |
| 69 | ); | 74 | ); |
| 70 | } | 75 | } |
apps/web/src/components/chat/ChatHeader.tsx+7-4| ... | @@ -288,13 +288,16 @@ export const ChatHeader = memo(function ChatHeader({ | ... | @@ -288,13 +288,16 @@ export const ChatHeader = memo(function ChatHeader({ |
| 288 | className="@container/header-actions flex min-w-0 flex-1 items-center gap-2 sm:gap-3" | 288 | className="@container/header-actions flex min-w-0 flex-1 items-center gap-2 sm:gap-3" |
| 289 | onContextMenu={handleHeaderContextMenu} | 289 | onContextMenu={handleHeaderContextMenu} |
| 290 | > | 290 | > |
| 291 | <WorkspaceBreadcrumb ariaLabel="Thread breadcrumb" className="flex-1"> | 291 | <WorkspaceBreadcrumb |
| 292 | ariaLabel="Thread breadcrumb" | ||
| 293 | className="flex-1 overflow-clip [overflow-clip-margin:2px]" | ||
| 294 | > | ||
| 292 | {/* The project always leads the header: knowing which project a | 295 | {/* The project always leads the header: knowing which project a |
| 293 | thread lives in is priority zero, and the thread title alone | 296 | thread lives in is priority zero, and the thread title alone |
| 294 | doesn't answer it. */} | 297 | doesn't answer it. */} |
| 295 | {activeProjectName ? ( | 298 | {activeProjectName ? ( |
| 296 | <> | 299 | <> |
| 297 | <WorkspaceBreadcrumbItem> | 300 | <WorkspaceBreadcrumbItem className="shrink"> |
| 298 | <Tooltip> | 301 | <Tooltip> |
| 299 | <TooltipTrigger | 302 | <TooltipTrigger |
| 300 | render={ | 303 | render={ |
| ... | @@ -302,7 +305,7 @@ export const ChatHeader = memo(function ChatHeader({ | ... | @@ -302,7 +305,7 @@ export const ChatHeader = memo(function ChatHeader({ |
| 302 | type="button" | 305 | type="button" |
| 303 | aria-label={`New thread in ${activeProjectName}`} | 306 | aria-label={`New thread in ${activeProjectName}`} |
| 304 | onClick={onNewThreadInProject} | 307 | onClick={onNewThreadInProject} |
| 305 | className="inline-flex min-w-0 cursor-pointer items-center gap-1.5 rounded-sm text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring" | 308 | className="inline-flex min-w-0 max-w-full cursor-pointer items-center gap-1.5 rounded-sm text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring" |
| 306 | /> | 309 | /> |
| 307 | } | 310 | } |
| 308 | > | 311 | > |
| ... | @@ -320,7 +323,7 @@ export const ChatHeader = memo(function ChatHeader({ | ... | @@ -320,7 +323,7 @@ export const ChatHeader = memo(function ChatHeader({ |
| 320 | <WorkspaceBreadcrumbSeparator /> | 323 | <WorkspaceBreadcrumbSeparator /> |
| 321 | </> | 324 | </> |
| 322 | ) : null} | 325 | ) : null} |
| 323 | <WorkspaceBreadcrumbItem current className="flex-1"> | 326 | <WorkspaceBreadcrumbItem current className="min-w-10 flex-1"> |
| 324 | {renamingTitle !== null ? ( | 327 | {renamingTitle !== null ? ( |
| 325 | <input | 328 | <input |
| 326 | autoFocus | 329 | autoFocus |