authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-03-09 10:01:33-07:00
committergravatar for jmarminge@gmail.comJulius Marminge <jmarminge@gmail.com> 2026-03-09 11:57:27-07:00
loge9ffd5752bb56854f8693f4a37dee3b3b7afcd3e
treec77a6410939cda78873215eb10fbc587da59ec68
parent24122b17629451e4614d34f3b771769e87b99d79

Fix plan composer layout and sidebar flex shrink behavior

- add `min-w-0` to chat/flex containers to prevent composer/sidebar overflow - move `BranchToolbar` into the chat column so layout stays aligned with plan sidebar - extract sidebar inset base classes to shared logic and add a regression test for `min-w-0`

4 files changed, 23 insertions(+), 11 deletions(-)

apps/web/src/components/ChatView.tsx+10-10
......@@ -3468,7 +3468,7 @@ export default function ChatView({ threadId }: ChatViewProps) {
34683468 onDismiss={() => setThreadError(activeThread.id, null)}
34693469 />
34703470 {/* Main content area with optional plan sidebar */}
3471 <div className="flex min-h-0 flex-1">
3471 <div className="flex min-h-0 min-w-0 flex-1">
34723472 {/* Chat column */}
34733473 <div className="flex min-h-0 min-w-0 flex-1 flex-col">
34743474
......@@ -3953,6 +3953,15 @@ export default function ChatView({ threadId }: ChatViewProps) {
39533953 </form>
39543954 </div>
39553955
3956 {isGitRepo && (
3957 <BranchToolbar
3958 threadId={activeThread.id}
3959 onEnvModeChange={onEnvModeChange}
3960 envLocked={envLocked}
3961 onComposerFocusRequest={scheduleComposerFocus}
3962 />
3963 )}
3964
39563965 </div>{/* end chat column */}
39573966
39583967 {/* Plan sidebar */}
......@@ -3974,15 +3983,6 @@ export default function ChatView({ threadId }: ChatViewProps) {
39743983 ) : null}
39753984 </div>{/* end horizontal flex container */}
39763985
3977 {isGitRepo && (
3978 <BranchToolbar
3979 threadId={activeThread.id}
3980 onEnvModeChange={onEnvModeChange}
3981 envLocked={envLocked}
3982 onComposerFocusRequest={scheduleComposerFocus}
3983 />
3984 )}
3985
39863986 {(() => {
39873987 if (!terminalState.terminalOpen || !activeProject) {
39883988 return null;
apps/web/src/components/ui/sidebar.logic.ts created+2
......@@ -0,0 +1,2 @@
1export const SIDEBAR_INSET_BASE_CLASSNAME =
2 "relative flex min-w-0 w-full flex-1 flex-col bg-background";
apps/web/src/components/ui/sidebar.test.tsx created+9
......@@ -0,0 +1,9 @@
1import { describe, expect, it } from "vitest";
2
3import { SIDEBAR_INSET_BASE_CLASSNAME } from "./sidebar.logic";
4
5describe("SidebarInset", () => {
6 it("stays shrinkable inside flex layouts", () => {
7 expect(SIDEBAR_INSET_BASE_CLASSNAME).toContain("min-w-0");
8 });
9});
apps/web/src/components/ui/sidebar.tsx+2-1
......@@ -18,6 +18,7 @@ import {
1818import { Skeleton } from "~/components/ui/skeleton";
1919import { Tooltip, TooltipPopup, TooltipTrigger } from "~/components/ui/tooltip";
2020import { useMediaQuery } from "~/hooks/useMediaQuery";
21import { SIDEBAR_INSET_BASE_CLASSNAME } from "./sidebar.logic";
2122
2223const SIDEBAR_COOKIE_NAME = "sidebar_state";
2324const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
......@@ -595,7 +596,7 @@ function SidebarInset({ className, ...props }: React.ComponentProps<"main">) {
595596 return (
596597 <main
597598 className={cn(
598 "relative flex w-full flex-1 flex-col bg-background",
599 SIDEBAR_INSET_BASE_CLASSNAME,
599600 "md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ms-2 md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ms-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm/5",
600601 className,
601602 )}