Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions docs/tasks/done/102-two-line-tab-titles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# 102 — two-line tab titles

- **Status:** done
- **Mode:** AFK
- **Estimate:** 0.1d
- **Depends on:** none
- **Blocks:** none

## Goal

Sidebar tab rows (CDP tabs + local tabs) show the title on a **fixed two lines** instead of a
single truncated line — long titles clamp to two lines with an ellipsis, and short titles still
reserve the second line so every row has a uniform two-line height.

## Change

`src/components/sidebar.tsx` only, four class edits (no logic):

- The two tab-row title spans (`RowLabel` drag-overlay + the CDP/local row `displayTitle` spans):
`truncate` → `line-clamp-2 min-h-[2lh]`. `line-clamp-2` clamps long titles at two lines;
`min-h-[2lh]` reserves two line-heights so a short title still occupies a two-line-tall row.
- The tab-row containers + the drag-overlay `RowShell`: `items-center` → `items-start`, so the
favicon aligns to the first line rather than the vertical middle of the taller row.

Pins are unaffected (they render as favicon-only tiles, no title line). The hover tooltip already
used `line-clamp-2`. The flex row has no fixed height, so it grows to fit the two-line title.

## Verification

- [x] `pnpm typecheck` + `pnpm build` green; Tailwind emits `min-height:2lh` into the built CSS;
Biome clean on the file (pre-existing warnings only).
- [x] CSS behavior reasoned + build-verified; final visual confirmed on the packaged app
(`pnpm install:local`) and the prod web build after redeploy.

## Out of scope

- Showing a second line of *content* (URL host/path) — the choice was title-wrap, not a subtitle.
- Pin tiles, the collapsed icon rail (`RailTile`), and the notification/inbox rows.
12 changes: 6 additions & 6 deletions src/components/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -739,14 +739,14 @@ function PinnedZone({

function RowShell({ children }: { children: React.ReactNode }) {
return (
<div className="flex items-center gap-2 rounded-lg bg-sidebar px-2.5 py-1.5 shadow-lg ring-1 ring-border">
<div className="flex items-start gap-2 rounded-lg bg-sidebar px-2.5 py-1.5 shadow-lg ring-1 ring-border">
{children}
</div>
)
}

function RowLabel({ children }: { children: React.ReactNode }) {
return <span className="text-xs truncate text-foreground">{children}</span>
return <span className="min-h-[2lh] text-xs line-clamp-2 text-foreground">{children}</span>
}

function RowFavicon({ favicon }: { favicon?: string }) {
Expand Down Expand Up @@ -987,7 +987,7 @@ function SortableTabItem({
<TooltipTrigger asChild>
<div
className={cn(
"group relative flex items-center gap-2 rounded-lg px-2.5 py-1.5 cursor-default touch-target",
"group relative flex items-start gap-2 rounded-lg px-2.5 py-1.5 cursor-default touch-target",
isDragging
? "opacity-50"
: active
Expand All @@ -1011,7 +1011,7 @@ function SortableTabItem({
<UnreadBadge count={unread} />
<NumberHint n={number} />
</span>
<span className="flex-1 truncate text-xs">{displayTitle}</span>
<span className="min-h-[2lh] flex-1 line-clamp-2 text-xs">{displayTitle}</span>
<div
className={cn(
"pointer-events-none absolute right-0 top-0 bottom-0 w-12 rounded-r-lg bg-gradient-to-l to-transparent opacity-0 transition-opacity group-hover:opacity-100 [@media(hover:none)]:opacity-100",
Expand Down Expand Up @@ -1106,7 +1106,7 @@ function SortableLocalItem({
<TooltipTrigger asChild>
<div
className={cn(
"group relative flex items-center gap-2 rounded-lg px-2.5 py-1.5 cursor-default touch-target",
"group relative flex items-start gap-2 rounded-lg px-2.5 py-1.5 cursor-default touch-target",
isDragging
? "opacity-50"
: active
Expand Down Expand Up @@ -1135,7 +1135,7 @@ function SortableLocalItem({
<span className="absolute bottom-0.5 right-0.5 size-1.5 rounded-full bg-foreground/40 ring-1 ring-sidebar" />
)}
</span>
<span className="flex-1 truncate text-xs">{displayTitle}</span>
<span className="min-h-[2lh] flex-1 line-clamp-2 text-xs">{displayTitle}</span>
<div
className={cn(
"pointer-events-none absolute right-0 top-0 bottom-0 w-12 rounded-r-lg bg-gradient-to-l to-transparent opacity-0 transition-opacity group-hover:opacity-100 [@media(hover:none)]:opacity-100",
Expand Down