From 26da524cf23d7ff31c9fa348cb724fa783367cc8 Mon Sep 17 00:00:00 2001 From: maria-rcks Date: Thu, 8 Oct 2026 00:36:09 +0000 Subject: [PATCH 1/3] fix(web): collapsed composer reserves room for wide send actions --- apps/web/src/components/chat/ChatComposer.tsx | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/apps/web/src/components/chat/ChatComposer.tsx b/apps/web/src/components/chat/ChatComposer.tsx index cfdb03d0f05c..43ed98b87eab 100644 --- a/apps/web/src/components/chat/ChatComposer.tsx +++ b/apps/web/src/components/chat/ChatComposer.tsx @@ -5220,6 +5220,19 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) useLayoutEffect(() => { onRestingChange(isComposerResting); }, [isComposerResting, onRestingChange]); + // The resting footer floats over the prompt row, so the row reserves its + // measured width. Wide actions like "Compact and send" vary too much for a fixed inset. + const [restingActionsElement, setRestingActionsElement] = useState(null); + const [restingActionsWidth, setRestingActionsWidth] = useState(null); + useLayoutEffect(() => { + if (!isComposerResting || !restingActionsElement) return; + const measure = () => setRestingActionsWidth(restingActionsElement.offsetWidth); + measure(); + if (typeof ResizeObserver === "undefined") return; + const observer = new ResizeObserver(measure); + observer.observe(restingActionsElement); + return () => observer.disconnect(); + }, [isComposerResting, restingActionsElement]); const restingImagePreviewCounts = getRestingComposerImagePreviewCounts( standaloneComposerImages.length, ); @@ -7379,14 +7392,12 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) className={cn( "relative", isComposerResting && "flex min-w-0 items-center gap-1", - isComposerResting && - ((settings.contextWindowMeterEnabled && activeContextWindow) || - reserveContextWindowMeter - ? "pr-28" - : showComposerAttachAction - ? "pr-20" - : "pr-12"), )} + style={ + isComposerResting && restingActionsWidth !== null + ? { paddingRight: `calc(${restingActionsWidth}px + 1rem)` } + : undefined + } > {previewFile ? ( Date: Thu, 8 Oct 2026 01:04:44 +0000 Subject: [PATCH 2/3] style(web): format resting composer row --- apps/web/src/components/chat/ChatComposer.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/web/src/components/chat/ChatComposer.tsx b/apps/web/src/components/chat/ChatComposer.tsx index 43ed98b87eab..04311110238c 100644 --- a/apps/web/src/components/chat/ChatComposer.tsx +++ b/apps/web/src/components/chat/ChatComposer.tsx @@ -7389,10 +7389,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) )}
Date: Thu, 8 Oct 2026 18:58:36 +0000 Subject: [PATCH 3/3] fix(web): describe compact chip in resting composer comment --- apps/web/src/components/chat/ChatComposer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/src/components/chat/ChatComposer.tsx b/apps/web/src/components/chat/ChatComposer.tsx index 04311110238c..4a92c9efa881 100644 --- a/apps/web/src/components/chat/ChatComposer.tsx +++ b/apps/web/src/components/chat/ChatComposer.tsx @@ -5221,7 +5221,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) onRestingChange(isComposerResting); }, [isComposerResting, onRestingChange]); // The resting footer floats over the prompt row, so the row reserves its - // measured width. Wide actions like "Compact and send" vary too much for a fixed inset. + // measured width. Wide actions like the compact-before-send chip vary too much for a fixed inset. const [restingActionsElement, setRestingActionsElement] = useState(null); const [restingActionsWidth, setRestingActionsWidth] = useState(null); useLayoutEffect(() => {