AgentBackGutter.tsx2.4 KBView on GitHub 'use client';
import { ArrowLeft } from 'lucide-react';
import { useState } from 'react';
import { useAgentBack } from '@/modules/agents/hooks/use-agent-back';
import { cn } from '@/lib/utils';
/**
* Full-height back gutter on the left edge of the agent workspace.
*
* A copy of ConversationBackGutter's geometry rather than a shared component: that
* one pops the conversation's inner drill-in stack first (a Slack thread, a file doc),
* which an agent has no equivalent of. Below that the two now agree — both leave through
* `useBackOrClose`, so an artifact is left by popping the entry its open pushed. The
* SHAPE is what has to match — same width formula, same hover wash, same arrow
* position — so the two views feel like one product. If a third caller appears,
* that is the moment to extract the shell and leave the back behaviour a prop.
*/
export function AgentBackGutter({ className }: { className?: string }) {
const goBack = useAgentBack();
const [hovered, setHovered] = useState(false);
return (
<button
type="button"
// Pops the entry the agent's own `?agentId=` push created, so back returns you to
// whatever you opened the agent from — and never pushes, which is what made this
// button and the one on the page behind it ping-pong. See useAgentBack.
onClick={goBack}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
aria-label="Back"
className={cn(
// Fills the left margin but stops 1rem short of the content column so neither
// the arrow nor its hover gradient crowds the content.
'sticky top-0 float-left z-10 h-screen w-[max(2rem,calc((100%-80ch)/2-1rem))] cursor-pointer',
className,
)}
style={{ marginBottom: '-100vh' }}
>
<div
className={cn(
'absolute inset-0 bg-gradient-to-r from-[#15803d]/[0.10] to-transparent transition-opacity duration-300 dark:from-[#15803d]/[0.14]',
hovered ? 'opacity-100' : 'opacity-0',
)}
/>
{/* top-4 centers the arrow on the title row — same arithmetic as the
conversation gutter: pt-1.5 + py-1 + a 28px text-xl line box. */}
<ArrowLeft
className={cn(
'absolute left-4 top-4 h-4 w-4 transition-opacity duration-200',
hovered ? 'opacity-80' : 'opacity-40',
)}
/>
</button>
);
}