| ... | ... | @@ -5220,6 +5220,19 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 5220 | 5220 | useLayoutEffect(() => { |
| 5221 | 5221 | onRestingChange(isComposerResting); |
| 5222 | 5222 | }, [isComposerResting, onRestingChange]); |
| 5223 | // The resting footer floats over the prompt row, so the row reserves its |
| 5224 | // measured width. Wide actions like the compact-before-send chip vary too much for a fixed inset. |
| 5225 | const [restingActionsElement, setRestingActionsElement] = useState<HTMLDivElement | null>(null); |
| 5226 | const [restingActionsWidth, setRestingActionsWidth] = useState<number | null>(null); |
| 5227 | useLayoutEffect(() => { |
| 5228 | if (!isComposerResting || !restingActionsElement) return; |
| 5229 | const measure = () => setRestingActionsWidth(restingActionsElement.offsetWidth); |
| 5230 | measure(); |
| 5231 | if (typeof ResizeObserver === "undefined") return; |
| 5232 | const observer = new ResizeObserver(measure); |
| 5233 | observer.observe(restingActionsElement); |
| 5234 | return () => observer.disconnect(); |
| 5235 | }, [isComposerResting, restingActionsElement]); |
| 5223 | 5236 | const restingImagePreviewCounts = getRestingComposerImagePreviewCounts( |
| 5224 | 5237 | standaloneComposerImages.length, |
| 5225 | 5238 | ); |
| ... | ... | @@ -7376,17 +7389,12 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 7376 | 7389 | )} |
| 7377 | 7390 | |
| 7378 | 7391 | <div |
| 7379 | | className={cn( |
| 7380 | | "relative", |
| 7381 | | isComposerResting && "flex min-w-0 items-center gap-1", |
| 7382 | | isComposerResting && |
| 7383 | | ((settings.contextWindowMeterEnabled && activeContextWindow) || |
| 7384 | | reserveContextWindowMeter |
| 7385 | | ? "pr-28" |
| 7386 | | : showComposerAttachAction |
| 7387 | | ? "pr-20" |
| 7388 | | : "pr-12"), |
| 7389 | | )} |
| 7392 | className={cn("relative", isComposerResting && "flex min-w-0 items-center gap-1")} |
| 7393 | style={ |
| 7394 | isComposerResting && restingActionsWidth !== null |
| 7395 | ? { paddingRight: `calc(${restingActionsWidth}px + 1rem)` } |
| 7396 | : undefined |
| 7397 | } |
| 7390 | 7398 | > |
| 7391 | 7399 | {previewFile ? ( |
| 7392 | 7400 | <Dialog |
| ... | ... | @@ -7565,6 +7573,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 7565 | 7573 | |
| 7566 | 7574 | {/* Right side: send / stop button */} |
| 7567 | 7575 | <div |
| 7576 | ref={setRestingActionsElement} |
| 7568 | 7577 | data-chat-composer-actions="right" |
| 7569 | 7578 | data-chat-composer-transition-actions="true" |
| 7570 | 7579 | data-chat-composer-primary-actions-compact={ |