From e354e8697f490c729d7022b28e921f4c12e0a8ae Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Mon, 9 Mar 2026 11:17:43 -0700 Subject: [PATCH] Prevent compact diff sidebar from breaking chat composer layout - Add composer footer/action data attributes for targeted width measurement - Enforce a minimum composer width before allowing inline diff sidebar --- apps/web/src/components/ChatView.tsx | 3 ++- apps/web/src/routes/_chat.$threadId.tsx | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/apps/web/src/components/ChatView.tsx b/apps/web/src/components/ChatView.tsx index 4ce3398aa0ef22fd0d7aa4b6be8946c9ff55f06f..565ce201ff2a2192f828984bfe5aa192ecbe4be0 100644 --- a/apps/web/src/components/ChatView.tsx +++ b/apps/web/src/components/ChatView.tsx @@ -3707,6 +3707,7 @@ export default function ChatView({ threadId }: ChatViewProps) { ) : (
{/* Right side: send / stop button */} -
+
{isPreparingWorktree ? ( Preparing worktree... ) : null} diff --git a/apps/web/src/routes/_chat.$threadId.tsx b/apps/web/src/routes/_chat.$threadId.tsx index 2593eb7605a11a529cee7966c844b77c14f189fe..ccd2002777272e91af88e02a5f773f169f65b8ad 100644 --- a/apps/web/src/routes/_chat.$threadId.tsx +++ b/apps/web/src/routes/_chat.$threadId.tsx @@ -15,6 +15,7 @@ const DIFF_INLINE_LAYOUT_MEDIA_QUERY = "(max-width: 1180px)"; const DIFF_INLINE_SIDEBAR_WIDTH_STORAGE_KEY = "chat_diff_sidebar_width"; const DIFF_INLINE_DEFAULT_WIDTH = "clamp(28rem,48vw,44rem)"; const DIFF_INLINE_SIDEBAR_MIN_WIDTH = 26 * 16; +const COMPOSER_COMPACT_MIN_LEFT_CONTROLS_WIDTH_PX = 208; const DiffPanelSheet = (props: { children: ReactNode; @@ -91,8 +92,23 @@ const DiffPanelInlineSidebar = (props: { composerViewport.clientWidth - viewportPaddingLeft - viewportPaddingRight, ); const formRect = composerForm.getBoundingClientRect(); + const composerFooter = composerForm.querySelector("[data-chat-composer-footer='true']"); + const composerRightActions = composerForm.querySelector( + "[data-chat-composer-actions='right']", + ); + const composerRightActionsWidth = composerRightActions?.getBoundingClientRect().width ?? 0; + const composerFooterGap = composerFooter + ? Number.parseFloat(window.getComputedStyle(composerFooter).columnGap) || + Number.parseFloat(window.getComputedStyle(composerFooter).gap) || + 0 + : 0; + const minimumComposerWidth = + COMPOSER_COMPACT_MIN_LEFT_CONTROLS_WIDTH_PX + + composerRightActionsWidth + + composerFooterGap; const hasComposerOverflow = composerForm.scrollWidth > composerForm.clientWidth + 0.5; const overflowsViewport = formRect.width > viewportContentWidth + 0.5; + const violatesMinimumComposerWidth = composerForm.clientWidth + 0.5 < minimumComposerWidth; if (previousSidebarWidth.length > 0) { wrapper.style.setProperty("--sidebar-width", previousSidebarWidth); @@ -100,7 +116,7 @@ const DiffPanelInlineSidebar = (props: { wrapper.style.removeProperty("--sidebar-width"); } - return !hasComposerOverflow && !overflowsViewport; + return !hasComposerOverflow && !overflowsViewport && !violatesMinimumComposerWidth; }, [], ); -- 2.54.0