Style the work drawer as a secondary-surface container

The work module's contents (label, branch chip, PR card) sit in a
rounded secondary-background container, the divider against the
conversation is gone, and the drawer eases open/closed on its width
(300ms ease-out) instead of popping — the panel stays mounted so the
close animates too.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
klopez4212
2026-07-07 07:46:14 +01:00
co-authored by Claude Fable 5
parent 4224f9d511
commit c201f0431a
3 changed files with 34 additions and 15 deletions
+2 -2
View File
@@ -624,8 +624,8 @@ export function ChatDetail({
/>
</div>
</div>
{workPanelHref && showWorkPanel ? (
<ChatWorkPanel prHref={workPanelHref} />
{workPanelHref ? (
<ChatWorkPanel open={showWorkPanel} prHref={workPanelHref} />
) : null}
</div>
</>
+30 -13
View File
@@ -5,14 +5,22 @@ import {
useGithubPullRequestQuery,
} from "@/shared/lib/githubPullRequest";
import { parseSupportedLinkPreview } from "@/shared/lib/linkPreview";
import { cn } from "@/shared/lib/cn";
import { GithubPullRequestCard } from "@/shared/ui/link-preview-attachment";
/**
* Right-hand work module for a chat whose agent produced a pull request:
* the PR's source branch and the live PR card (status, diff stats, link).
* The conversation column and composer shrink to make room.
* the PR's source branch and the live PR card (status, diff stats, link),
* grouped in a secondary-surface container. The drawer eases open/closed on
* its width so the conversation column and composer slide to make room.
*/
export function ChatWorkPanel({ prHref }: { prHref: string }) {
export function ChatWorkPanel({
open = true,
prHref,
}: {
open?: boolean;
prHref: string;
}) {
const preview = parseSupportedLinkPreview(prHref);
const ref = parseGithubPullRequestRef(prHref);
const query = useGithubPullRequestQuery(ref);
@@ -24,19 +32,28 @@ export function ChatWorkPanel({ prHref }: { prHref: string }) {
return (
<aside
className="flex w-80 shrink-0 flex-col gap-3 overflow-y-auto border-l border-border/40 px-4 py-4"
aria-hidden={!open}
className={cn(
"flex shrink-0 flex-col overflow-hidden transition-[width,opacity] duration-300 ease-out",
open ? "w-80 opacity-100" : "pointer-events-none w-0 opacity-0",
)}
data-testid="chat-work-panel"
>
<div className="text-2xs font-semibold uppercase tracking-wide text-muted-foreground">
Work
</div>
{branch ? (
<div className="flex items-center gap-1.5 rounded-lg border border-border/60 bg-muted/20 px-3 py-2 text-xs">
<GitBranch className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
<span className="min-w-0 truncate font-mono">{branch}</span>
{/* Fixed-width inner wrapper so content never reflows mid-slide. */}
<div className="w-80 overflow-y-auto py-4 pl-1 pr-4">
<div className="flex flex-col gap-3 rounded-2xl bg-secondary p-3">
<div className="text-2xs font-semibold uppercase tracking-wide text-muted-foreground">
Work
</div>
{branch ? (
<div className="flex items-center gap-1.5 rounded-lg bg-background/60 px-3 py-2 text-xs">
<GitBranch className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
<span className="min-w-0 truncate font-mono">{branch}</span>
</div>
) : null}
<GithubPullRequestCard className="w-full" preview={preview} />
</div>
) : null}
<GithubPullRequestCard className="w-full" preview={preview} />
</div>
</aside>
);
}
@@ -1,5 +1,6 @@
import { expect, test } from "@playwright/test";
import { waitForAnimations } from "../helpers/animations";
import { installMockBridge } from "../helpers/bridge";
test("first message in a new chat is sent and rendered", async ({ page }) => {
@@ -159,5 +160,6 @@ test("first message in a new chat is sent and rendered", async ({ page }) => {
await expect(workPanel).not.toBeVisible();
await page.getByTestId("toggle-work-panel").click();
await expect(workPanel).toBeVisible();
await waitForAnimations(page);
await page.screenshot({ path: "test-results/agent-pr-card.png" });
});