Chat header: action cluster slides to the panel's left edge when expanded

When the panel opened the cluster only shifted a fixed 168px, so the
Slack/Sessions/New icons stayed near the right instead of moving to the
middle. Now the open-state margin matches the panel width (phone 448px,
tablet/full 67%), so the cluster lands at the panel's LEFT edge — the
middle column beside the chat — mirroring WorkClaw's shrinking-pane move.
Animated with transition-[margin]. Verified at 1440: collapsed Computer
ends 1420 (flush right); tablet → 600 (panel left 593); phone → 972
(panel left 992). Device/Close overlay stays far-right; no overlap.

86 unit + 31 functional E2E green.

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
Omar Sobh
2026-06-11 11:58:04 -05:00
co-authored by Claude Fable 5
parent fa1f64803c
commit 0d49fb7099
+16 -5
View File
@@ -7,13 +7,23 @@ import { useQueryStates } from "nuqs";
import type { Agent } from "@/lib/api/schemas"; import type { Agent } from "@/lib/api/schemas";
import { Avatar } from "@/components/ui/Avatar"; import { Avatar } from "@/components/ui/Avatar";
import { DeviceSizeToggle } from "@/components/computer/DeviceSizeToggle"; import { DeviceSizeToggle } from "@/components/computer/DeviceSizeToggle";
import { panelParsers } from "@/lib/url/panel-params"; import { panelParsers, type DeviceSize } from "@/lib/url/panel-params";
/* WorkClaw's raised-chip treatment for the collapsed action buttons: /* WorkClaw's raised-chip treatment for the collapsed action buttons:
dark fill, inset hairline ring, bubble shadow (dark-only app). */ dark fill, inset hairline ring, bubble shadow (dark-only app). */
const CHIP = const CHIP =
"inline-flex size-9 items-center justify-center rounded-full bg-neutral-900 shadow-bubble ring-1 ring-white/[0.08] transition-colors duration-(--duration-normal) ease-app ring-inset"; "inline-flex size-9 items-center justify-center rounded-full bg-neutral-900 shadow-bubble ring-1 ring-white/[0.08] transition-colors duration-(--duration-normal) ease-app ring-inset";
/* When the panel opens, the right-aligned cluster slides left to the
panel's LEFT edge (its margin == the panel width) so the icons land in
the middle column beside the chat, mirroring WorkClaw's shrinking pane.
Closed → no margin (flush right). */
const OPEN_MARGIN: Record<DeviceSize, string> = {
phone: "md:mr-[448px]",
tablet: "md:mr-[67%]",
full: "md:mr-[67%]",
};
/** Chat header (measured): a two-zone toolbar. The identity sits left; the /** Chat header (measured): a two-zone toolbar. The identity sits left; the
* action cluster (Sessions / New / Computer) is centered as its own group; * action cluster (Sessions / New / Computer) is centered as its own group;
* and the device-size toggles + Close are a separate, absolutely-positioned * and the device-size toggles + Close are a separate, absolutely-positioned
@@ -50,11 +60,12 @@ export function ChatHeader({
{/* Action cluster — right-aligned in flow (measured: ml-auto), the {/* Action cluster — right-aligned in flow (measured: ml-auto), the
chipped action group (Slack / Sessions / New), a vertical chipped action group (Slack / Sessions / New), a vertical
separator, then the coral Computer toggle. When the panel is open separator, then the coral Computer toggle. When the panel opens it
it shifts left to clear the absolute device/Close overlay. */} slides left to the panel's left edge (the middle column), clearing
the absolute device/Close overlay on the far right. */}
<div <div
className={`ml-auto flex items-center gap-2.5 ${ className={`ml-auto flex items-center gap-2.5 transition-[margin] duration-(--duration-normal) ease-app ${
panelOpen ? "md:mr-[168px]" : "" panelOpen ? OPEN_MARGIN[device] : ""
}`} }`}
> >
<div className="hidden items-center gap-3 md:flex"> <div className="hidden items-center gap-3 md:flex">