| author | |
| committer | |
| log | e9ffd5752bb56854f8693f4a37dee3b3b7afcd3e |
| tree | c77a6410939cda78873215eb10fbc587da59ec68 |
| parent | 24122b17629451e4614d34f3b771769e87b99d79 |
- 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) { |
| 3468 | 3468 | onDismiss={() => setThreadError(activeThread.id, null)} |
| 3469 | 3469 | /> |
| 3470 | 3470 | {/* 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"> | |
| 3472 | 3472 | {/* Chat column */} |
| 3473 | 3473 | <div className="flex min-h-0 min-w-0 flex-1 flex-col"> |
| 3474 | 3474 | |
| ... | ... | @@ -3953,6 +3953,15 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 3953 | 3953 | </form> |
| 3954 | 3954 | </div> |
| 3955 | 3955 | |
| 3956 | {isGitRepo && ( | |
| 3957 | <BranchToolbar | |
| 3958 | threadId={activeThread.id} | |
| 3959 | onEnvModeChange={onEnvModeChange} | |
| 3960 | envLocked={envLocked} | |
| 3961 | onComposerFocusRequest={scheduleComposerFocus} | |
| 3962 | /> | |
| 3963 | )} | |
| 3964 | ||
| 3956 | 3965 | </div>{/* end chat column */} |
| 3957 | 3966 | |
| 3958 | 3967 | {/* Plan sidebar */} |
| ... | ... | @@ -3974,15 +3983,6 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 3974 | 3983 | ) : null} |
| 3975 | 3984 | </div>{/* end horizontal flex container */} |
| 3976 | 3985 | |
| 3977 | {isGitRepo && ( | |
| 3978 | <BranchToolbar | |
| 3979 | threadId={activeThread.id} | |
| 3980 | onEnvModeChange={onEnvModeChange} | |
| 3981 | envLocked={envLocked} | |
| 3982 | onComposerFocusRequest={scheduleComposerFocus} | |
| 3983 | /> | |
| 3984 | )} | |
| 3985 | ||
| 3986 | 3986 | {(() => { |
| 3987 | 3987 | if (!terminalState.terminalOpen || !activeProject) { |
| 3988 | 3988 | return null; |
apps/web/src/components/ui/sidebar.logic.ts created+2| ... | ... | @@ -0,0 +1,2 @@ |
| 1 | export 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 @@ |
| 1 | import { describe, expect, it } from "vitest"; | |
| 2 | ||
| 3 | import { SIDEBAR_INSET_BASE_CLASSNAME } from "./sidebar.logic"; | |
| 4 | ||
| 5 | describe("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 { |
| 18 | 18 | import { Skeleton } from "~/components/ui/skeleton"; |
| 19 | 19 | import { Tooltip, TooltipPopup, TooltipTrigger } from "~/components/ui/tooltip"; |
| 20 | 20 | import { useMediaQuery } from "~/hooks/useMediaQuery"; |
| 21 | import { SIDEBAR_INSET_BASE_CLASSNAME } from "./sidebar.logic"; | |
| 21 | 22 | |
| 22 | 23 | const SIDEBAR_COOKIE_NAME = "sidebar_state"; |
| 23 | 24 | const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7; |
| ... | ... | @@ -595,7 +596,7 @@ function SidebarInset({ className, ...props }: React.ComponentProps<"main">) { |
| 595 | 596 | return ( |
| 596 | 597 | <main |
| 597 | 598 | className={cn( |
| 598 | "relative flex w-full flex-1 flex-col bg-background", | |
| 599 | SIDEBAR_INSET_BASE_CLASSNAME, | |
| 599 | 600 | "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", |
| 600 | 601 | className, |
| 601 | 602 | )} |