diff --git a/apps/web/src/components/chat/TimelineWorkGroupRows.tsx b/apps/web/src/components/chat/TimelineWorkGroupRows.tsx index 2adbd81bd155e..c9a5541897e29 100644 --- a/apps/web/src/components/chat/TimelineWorkGroupRows.tsx +++ b/apps/web/src/components/chat/TimelineWorkGroupRows.tsx @@ -892,6 +892,12 @@ function WorkingWindowView({ window, itemKey }: { window: WorkingWindow; itemKey } const windowRef = useRef(null); const spacerRef = useRef(null); + const [collapseClips, setCollapseClips] = useState(false); + // oxlint-disable-next-line t3code/no-unreasoned-state-sync -- reads the expanded height before the collapse transition paints its first frame + useLayoutEffect(() => { + if (open) return; + setCollapseClips((windowRef.current?.scrollHeight ?? 0) > WORKING_WINDOW_COLLAPSED_HEIGHT); + }, [open]); // oxlint-disable-next-line t3code/no-unreasoned-state-sync -- older items stay mounted until the collapse transition finishes clipping them useEffect(() => { if (open || history === null) return; @@ -964,6 +970,7 @@ function WorkingWindowView({ window, itemKey }: { window: WorkingWindow; itemKey open ? "[height:calc-size(auto,size)]" : "[height:calc-size(auto,min(size,220px))] not-supports-[height:calc-size(auto,size)]:max-h-[220px]", + !open && history !== null && collapseClips && "working-window-collapse-fade", )} > {history === null ? ( @@ -1027,6 +1034,7 @@ function CollapsedWorkingWindow({ ); const content = contentRef.current; if (!viewport || !content) return; + viewport.scrollTop = viewport.scrollHeight; return observeResize([content, viewport], () => { if (followRef.current) viewport.scrollTop = viewport.scrollHeight; }); @@ -1101,6 +1109,7 @@ function workingWindowItemIsLive(item: WorkingWindowItem | undefined): boolean { } const WORKING_WINDOW_TAIL = 12; +const WORKING_WINDOW_COLLAPSED_HEIGHT = 220; const WORKING_HISTORY_BATCH = 50; diff --git a/apps/web/src/index.css b/apps/web/src/index.css index 3e7c41b9d9783..4927b8ee8d6b9 100644 --- a/apps/web/src/index.css +++ b/apps/web/src/index.css @@ -1155,6 +1155,11 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil var(--app-scrollbar-width) 100%; } +@utility working-window-collapse-fade { + -webkit-mask-image: linear-gradient(to bottom, transparent 0.5rem, black 2rem); + mask-image: linear-gradient(to bottom, transparent 0.5rem, black 2rem); +} + /* Stage-channel art needs a mask and pseudo-element gradient, so keep the behavior composable without tying it to the global components layer. */ @utility sidebar-stage-backdrop {