fix(site/src/pages/AgentsPage): use h-dvh on root to fix mobile keyboard layout#24848
Closed
bpmct wants to merge 1 commit into
Closed
fix(site/src/pages/AgentsPage): use h-dvh on root to fix mobile keyboard layout#24848bpmct wants to merge 1 commit into
bpmct wants to merge 1 commit into
Conversation
…ard layout On iOS, the layout viewport does not shrink when the virtual keyboard opens. This means h-full (= 100% of layout viewport) keeps the root at the full device height (e.g. 844px) even after the keyboard appears. The browser then auto-scrolls to bring the focused input into view, which pushes the first/oldest messages off the top of the screen. Replacing h-full with h-dvh (100% dynamic viewport height) fixes this. dvh tracks the visual viewport on iOS, so the root shrinks when the keyboard opens and the layout naturally fits in the visible area. The input sits at the bottom above the keyboard with no browser scroll intervention needed. On Android and desktop, dvh behaves identically to svh/lvh and there is no visible change.
bpmct
added a commit
that referenced
this pull request
May 5, 2026
…at scroll keeps working (#24950) Linear: [CODAGT-313](https://linear.app/codercom/issue/CODAGT-313/unable-to-scroll-long-queued-messages-in-coder-agents) ## Summary When many messages are queued in the agent chat, the chat history becomes unscrollable: mouse wheel and scrollbar drag both stop responding. The input wrapper in `AgentChatPageView.tsx:496` is `shrink-0 overflow-y-auto` with **no `max-height`**, so `overflow-y-auto` is a no-op and the section grows unbounded as `QueuedMessagesList` adds rows. Its sibling `ChatScrollContainer` is `flex-1 min-h-0`, so it absorbs the shrinkage and `clientHeight` collapses to 0. The chat list is then a zero-height viewport with nothing to scroll. Measured against the actual `AgentChatPageView` rendered in Storybook with 20 queued messages (1280x800): | | scroll-container `clientHeight` | input wrapper height | scrollable? | |---|---:|---:|---| | 0 queued | 502 px | 270 px | yes | | 20 queued, `main` | **0 px** | 1182 px | **no** | | 20 queued, this PR | 258 px | 502 px | yes | ## Demo  Left (`main`): wheel-up does nothing because the chat scroll container has been crushed to zero height. Right (this PR): the queued list scrolls inside its own pane and the chat history scrolls normally. Recording is `AgentChatPageView` rendered through Storybook with the production component source. The same gesture (wheel-up over the chat history, then wheel-down over the queued list) is applied to both sides. Source for the recording is in `bpmct/codagt-313-assets`. ## Change ```diff - <div className={cn("flex w-full flex-col", className)}> + // Cap the queue at ~40% of the small viewport so a long queue + // does not push the chat history's scroll container down to + // zero height (CODAGT-313). The list scrolls inside its own pane. + <div + className={cn( + "flex w-full flex-col max-h-[40svh] overflow-y-auto [scrollbar-gutter:stable] [scrollbar-width:thin] [scrollbar-color:hsl(var(--surface-quaternary))_transparent]", + className, + )} + > ``` ## Why this spot, not the outer wrapper The composer textarea already self-caps at `max-h-[50vh]` in `ChatMessageInput.tsx:688`, so the only unbounded growth source in the input section is the queued list. Capping the list keeps the constraint colocated with the component that owns it, and any future consumer of `QueuedMessagesList` is automatically safe. `40svh` (small viewport height) so the queue doesn't fight with the iOS keyboard once it appears, matching the `h-dvh` decision in #24848. --- *Generated by Coder Agents.*
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
On iOS, the virtual keyboard does not shrink the layout viewport.
h-full(= 100% of the layout viewport) therefore keeps the root div at the full device height even after the keyboard appears. The browser then auto-scrolls the page to bring the focused chat input into view, which pushes the oldest/first messages above the visible fold.Replacing
h-fullwithh-dvh(100% dynamic viewport height) fixes this.dvhtracks the visual viewport, which shrinks when the keyboard opens on both iOS and Android. The container fits naturally in the remaining visible area, the input sits at the bottom above the keyboard, and no browser scroll adjustment is needed.On desktop and Android Chrome the change is effectively transparent:
dvhequalssvh/lvhwhen no keyboard is present, and Android already resizes the layout viewport on keyboard open.Change
h-dvhis a Tailwind v3.3+ built-in (height: 100dvh). The project uses Tailwind v3.4.18, so no extra configuration is needed.Generated by Coder Agents.