feat(mobile): rework Session and Project headers for narrow viewports
Session header: breadcrumb (Projects > project) wrapped in hidden sm:flex; active file path hidden on mobile; session name cap max-w-[140px] sm:max-w-[280px]; padding px-3 sm:px-4. Mobile gets just hamburger | session name | model pill. Project header: px-3 sm:px-6, py-2 sm:py-3, heading text-base sm:text-lg, project path hidden sm:block, "New session" button is icon-only on mobile via <span className="hidden sm:inline">. Both headers retain the safe-area-inset-top padding from v1.6. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -81,32 +81,32 @@ export function Project() {
|
|||||||
return (
|
return (
|
||||||
<div className="flex-1 flex flex-col">
|
<div className="flex-1 flex flex-col">
|
||||||
<header
|
<header
|
||||||
className="border-b px-6 py-3 flex items-center justify-between gap-2"
|
className="border-b px-3 sm:px-6 py-2 sm:py-3 flex items-center justify-between gap-2"
|
||||||
style={{ paddingTop: 'max(0.75rem, env(safe-area-inset-top))' }}
|
style={{ paddingTop: 'max(0.5rem, env(safe-area-inset-top))' }}
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-2 min-w-0">
|
<div className="flex items-center gap-2 min-w-0">
|
||||||
{isMobile && (
|
{isMobile && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setDrawerOpen(true)}
|
onClick={() => setDrawerOpen(true)}
|
||||||
className="inline-flex items-center justify-center -ml-2 min-w-[44px] min-h-[44px] rounded text-muted-foreground hover:bg-muted hover:text-foreground shrink-0"
|
className="inline-flex items-center justify-center -ml-1 min-w-[44px] min-h-[44px] rounded text-muted-foreground hover:bg-muted hover:text-foreground shrink-0"
|
||||||
aria-label="Open sidebar"
|
aria-label="Open sidebar"
|
||||||
>
|
>
|
||||||
<Menu className="size-5" />
|
<Menu className="size-5" />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
<div className="min-w-0">
|
<div className="min-w-0">
|
||||||
<h1 className="text-lg font-semibold tracking-tight truncate">
|
<h1 className="text-base sm:text-lg font-semibold tracking-tight truncate">
|
||||||
{project?.name ?? '…'}
|
{project?.name ?? '…'}
|
||||||
</h1>
|
</h1>
|
||||||
<div className="text-xs text-muted-foreground font-mono truncate">
|
<div className="text-xs text-muted-foreground font-mono truncate hidden sm:block">
|
||||||
{project?.path}
|
{project?.path}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Button onClick={handleNew} disabled={creating} className="shrink-0">
|
<Button onClick={handleNew} disabled={creating} className="shrink-0" aria-label="New session">
|
||||||
<Plus />
|
<Plus />
|
||||||
New session
|
<span className="hidden sm:inline">New session</span>
|
||||||
</Button>
|
</Button>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -87,21 +87,27 @@ export function Session() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex-1 flex flex-col min-h-0">
|
<div className="flex-1 flex flex-col min-h-0">
|
||||||
<header className="border-b px-4 py-2 flex items-center gap-1.5 shrink-0 text-sm" style={{ paddingTop: 'max(0.5rem, env(safe-area-inset-top))' }}>
|
<header
|
||||||
|
className="border-b px-3 sm:px-4 py-2 flex items-center gap-1.5 shrink-0 text-sm"
|
||||||
|
style={{ paddingTop: 'max(0.5rem, env(safe-area-inset-top))' }}
|
||||||
|
>
|
||||||
{isMobile && (
|
{isMobile && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setDrawerOpen(true)}
|
onClick={() => setDrawerOpen(true)}
|
||||||
className="inline-flex items-center justify-center -ml-1 mr-1 min-w-[44px] min-h-[44px] rounded text-muted-foreground hover:bg-muted hover:text-foreground"
|
className="inline-flex items-center justify-center -ml-1 min-w-[44px] min-h-[44px] rounded text-muted-foreground hover:bg-muted hover:text-foreground shrink-0"
|
||||||
aria-label="Open sidebar"
|
aria-label="Open sidebar"
|
||||||
>
|
>
|
||||||
<Menu className="size-5" />
|
<Menu className="size-5" />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
<Link to="/" className="text-muted-foreground hover:text-foreground">
|
|
||||||
|
{/* Breadcrumb — desktop only */}
|
||||||
|
<div className="hidden sm:flex items-center gap-1.5 min-w-0">
|
||||||
|
<Link to="/" className="text-muted-foreground hover:text-foreground shrink-0 text-xs">
|
||||||
Projects
|
Projects
|
||||||
</Link>
|
</Link>
|
||||||
<ChevronRight className="size-3 text-muted-foreground/60" />
|
<ChevronRight className="size-3 text-muted-foreground/60 shrink-0" />
|
||||||
{project ? (
|
{project ? (
|
||||||
<Link
|
<Link
|
||||||
to={`/project/${project.id}`}
|
to={`/project/${project.id}`}
|
||||||
@@ -113,7 +119,10 @@ export function Session() {
|
|||||||
) : (
|
) : (
|
||||||
<span className="text-muted-foreground/60">…</span>
|
<span className="text-muted-foreground/60">…</span>
|
||||||
)}
|
)}
|
||||||
<ChevronRight className="size-3 text-muted-foreground/60" />
|
<ChevronRight className="size-3 text-muted-foreground/60 shrink-0" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Session name — always visible, truncated, editable */}
|
||||||
{editingName ? (
|
{editingName ? (
|
||||||
<input
|
<input
|
||||||
autoFocus
|
autoFocus
|
||||||
@@ -127,30 +136,34 @@ export function Session() {
|
|||||||
setEditingName(false);
|
setEditingName(false);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className="bg-transparent border-b border-border px-1 py-0.5 text-sm font-medium outline-none focus:border-ring"
|
className="bg-transparent border-b border-border px-1 py-0.5 text-sm font-medium outline-none focus:border-ring min-w-0"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="text-sm font-medium hover:underline truncate max-w-[280px]"
|
className="text-sm font-medium hover:underline truncate max-w-[140px] sm:max-w-[280px] min-w-0"
|
||||||
onClick={() => setEditingName(true)}
|
onClick={() => setEditingName(true)}
|
||||||
title={session?.name ?? ''}
|
title={session?.name ?? ''}
|
||||||
>
|
>
|
||||||
{session?.name ?? '…'}
|
{session?.name ?? '…'}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Active file — desktop only */}
|
||||||
{showActiveFile && active.activeFile && (
|
{showActiveFile && active.activeFile && (
|
||||||
<>
|
<>
|
||||||
<span className="text-muted-foreground/40 mx-1">·</span>
|
<span className="text-muted-foreground/40 mx-1 hidden sm:inline">·</span>
|
||||||
<span
|
<span
|
||||||
className="text-xs font-mono text-muted-foreground truncate max-w-[320px]"
|
className="text-xs font-mono text-muted-foreground truncate max-w-[200px] hidden sm:inline"
|
||||||
title={active.activeFile}
|
title={active.activeFile}
|
||||||
>
|
>
|
||||||
{active.activeFile}
|
{active.activeFile}
|
||||||
</span>
|
</span>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<div className="ml-auto">
|
|
||||||
|
{/* Model picker — right-aligned */}
|
||||||
|
<div className="ml-auto shrink-0">
|
||||||
{session && (
|
{session && (
|
||||||
<div className="inline-flex items-center rounded-full bg-muted/40 hover:bg-muted/70 px-1">
|
<div className="inline-flex items-center rounded-full bg-muted/40 hover:bg-muted/70 px-1">
|
||||||
<ModelPicker
|
<ModelPicker
|
||||||
|
|||||||
Reference in New Issue
Block a user