fix(web): full-screen HTML pages fit their content and zoom by reflowing#22349

merged4
main
GitHub fork: fix/html-render-fullscreen-fit
opened23d agobyZZeus-Deus
View on GitHubTwo-way sync enabledPR last imported 1d ago

Problem

Opening an html_render page full screen made it hard to read. The page was written for the 728px reply column, but the dialog stretched it across 92vw (about 1700px on a typical display). Paragraphs became single long lines, and vw-sized type roughly doubled. The frame was always 86vh tall: a short page sat in an empty card, and a long one scrolled inside the iframe, where the injected CSS hides the scrollbar. Zoom used CSS zoom, which never changes the page's layout width. At 150% the page ran off the right and bottom edges with two nested scroll areas, and at 50% it shrank into a corner.

Change

All changes are in HtmlRenderDialog:

  • Width: the card is capped at min(92vw, 1176px), a 1144px page plus padding. That's the widest width the server measures a page at, so a page stays close to the layout it was written for.
  • Height: the frame takes the height the page already reports (onContentHeight). Before the first report, it falls back to the server-measured heights for that width. The card's old fixed height becomes its max-height, so short pages get a short card and tall ones scroll the card, never the iframe.
  • Zoom: kept, but it now divides the page's layout width. At every zoom level the page reflows to fill the card instead of overflowing it or leaving empty space.

HtmlRenderFrame now passes its HtmlRenderReference to the dialog instead of just the title. Mobile uses its own WebView with native scrolling and isn't affected.

Scope and approval

A small, focused fix for an obvious bug in the existing full-screen view (#17561): the view sized pages wrongly and its zoom didn't work properly. It adds no settings, contracts, or server changes.

Verification

  • vp test run src/components/chat/HtmlRenderDialog.browser.test.tsx src/components/chat/HtmlRenderFrame.browser.test.tsx (apps/web): 11/11 passed. Three new tests cover the width cap, fitting to the reported height with only the card scrolling, and zoom reflowing at 200% and 50%. Against the old dialog, all three fail: the card is 1766px wide, the frame stays 608px tall, and at 200% the page paints 2291px wide in a 1146px card.
  • Targeted vp lint and vp fmt on the changed files are clean. tsc-rs --noEmit for apps/web reports no errors.
  • The screenshots below are the real dialog component rendering a page wrapped with the real bootstrap, in the browser test runner at 1600Γ—900 (a throwaway test, not committed). I didn't check it in a running app.

#19909 changes the same height class to account for the desktop titlebar. Whichever lands second needs a one-line rebase onto the new max-h.

Investigation, fix and PR text by Claude Opus 5.5 (High) in Claude Code. The diagnosis was cross-checked by GPT 6.1 Sol (Extra High) and Opus 5.5 (High) subagents through T3 Code.

πŸ€– Generated with Claude Code

Checks

22 successful Β· 16 skipped
All checks passed
9f4a723

Added 1 commit

  • fix(web): full-screen HTML pages fit their content and zoom by reflowing4db31f3
apps/web/src/components/chat/HtmlRenderDialog.tsxlines 30–30Outdated Β· 4db31f3Open thread
……@@ -1,19 +1,39 @@
27+ const measureBox = (box: HTMLDivElement) => {
28+ setWidth(box.clientWidth);
29+ return observeResize(box, ([entry]) => {
30+ if (entry) setWidth(entry.contentRect.width);
MmacroscopeappBoton lines 30–3023d ago

🟑 Medium chat/HtmlRenderDialog.tsx:30

At fractional card widths, the dialog repeatedly re-renders while idle because each contentRect.width update replaces measureBox, whose setup writes the integer clientWidth and restarts the observer; the observer's initial notification then repeats the cycle. Round the observed width to match clientWidth so the initial notification does not trigger another render.

suggestion
1 if (entry) setWidth(Math.round(entry.contentRect.width));
πŸ€– Copy this AI Prompt to have your agent fix this:
text
1In file @apps/web/src/components/chat/HtmlRenderDialog.tsx around line 30:
2
3At fractional card widths, the dialog repeatedly re-renders while idle because each `contentRect.width` update replaces `measureBox`, whose setup writes the integer `clientWidth` and restarts the observer; the observer's initial notification then repeats the cycle. Round the observed width to match `clientWidth` so the initial notification does not trigger another render.
Synced from GitHub

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval β€” This focused fix changes the default fullscreen HTML presentation by introducing content-driven sizing, a width cap, and reflowing zoom for all existing users of that view. An unresolved Medium finding also reports possible idle re-rendering at fractional widths, so the change warrants human review.

Needs human approval because:

  • 1 blocking correctness issue found at or above your repo's Minimum Blocking Severity

Adjust the Minimum Blocking Severity for this repo β€” including turning it Off β€” in Settings. You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Explain Change β†’

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

External image Run configuration

External image Commits

Reviewing files that changed from the base of the PR and between 708fb32340a01ca73a07b0799007f9ca2ff249da and 9f4a723e17ee804b899897a9649604878cafb85d.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review

No actionable comments were generated in the recent review.

Walkthrough

The fullscreen HTML render dialog now receives render metadata and derives its title and preview dimensions from that reference. It measures popup width, uses document content-height updates, and constrains scrolling to the preview card.

Changes: HTML render dialog

Layer / File(s)Summary
Dialog sizing and validation
apps/web/src/components/chat/HtmlRenderDialog.tsx, apps/web/src/components/chat/HtmlRenderFrame.tsx, apps/web/src/components/chat/HtmlRenderDialog.browser.test.tsx
The dialog takes an htmlRender reference and derives the title from it. It sizes the preview using measured width, zoom, and document content height. The preview width is capped, and the card provides bounded scrolling. The frame passes the render reference. Browser tests check height updates, card scrolling, and zoom reflow.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Sequence Diagram(s)

mermaid
1sequenceDiagram
2 participant HtmlRenderDialog
3 participant observeResize
4 participant HtmlRenderDocument
5 participant PreviewCard
6 HtmlRenderDialog->>observeResize: Observe preview width
7 observeResize-->>HtmlRenderDialog: Report measured width
8 HtmlRenderDialog->>HtmlRenderDocument: Pass content-height callback
9 HtmlRenderDocument-->>HtmlRenderDialog: Report content height
10 HtmlRenderDialog->>PreviewCard: Render sized preview in scrollable card

Possibly related issues

  • pingdotgg/t3code#34055: The issue reports cropping during zoom-out in the fullscreen HTML dialog. This change reflows the page at a zoom-adjusted layout width and sizes the frame from reported content height.

Possibly related PRs

Suggested labels: bugfix

Suggested reviewers: bil0000

Merge Risk: External image Minimal Β· previous review 708fb

No actionable issue with the dialog change is established. It is mergeable after normal checks.

Pre-merge checks: Passed 4

Check nameStatusExplanation
Title checkPassedThe title clearly and concisely describes the primary change: fitting full-screen HTML pages to their content and reflowing them when zoomed. It uses a suitable conventional commit format.
Description checkPassedThe description includes all required sections: Problem, Change, Scope and approval, and Verification. It explains the defect, implementation, scope rationale, focused tests, observed results, screens…
Linked Issues checkPassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes checkPassedCheck skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description includes all required sections: Problem, Change, Scope and approval, and Verification. It explains the defect, implementation, scope rationale, focused tests, observed results, screenshots, limitations, and agent attribution.

Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix Β· Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
External image Recent review info

External image Run configuration

External image Commits

Reviewing files that changed from the base of the PR and between 4db31f3e4b7d0380fabee6b20ef9bb2330a80240 and 708fb32340a01ca73a07b0799007f9ca2ff249da.

External image Files selected for processing: 3

  • apps/web/src/components/chat/HtmlRenderDialog.browser.test.tsx
  • apps/web/src/components/chat/HtmlRenderDialog.tsx
  • apps/web/src/components/chat/HtmlRenderFrame.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Synced from GitHub

This would fix what I hit. An agent showed a 16:9 slide deck in html_render (images sized by width, Prev/Next buttons below). In full screen on a 16:9 monitor at 100%, the bottom of each slide and the Prev/Next buttons are cut off, with no scrollbar to reach them. Zooming out shrinks it into the corner instead.

Windows 11 desktop.

Added 3 commits

  • Merge remote-tracking branch 'origin/main' into fix/html-render-fullscreen-fitf6e49ed
  • fix(web): full-screen HTML width updates agree at fractional sizes708fb32
  • Merge remote-tracking branch 'origin/main' into fix/html-render-fullscreen-fit9f4a723

Evidence

Real web client, Chromium, 1920Γ—1080, identical synthetic pages on fresh isolated state. Open tall HTML full screen β†’ 100% β†’ 50% β†’ reset β†’ 150% β†’ 200% β†’ scroll card to bottom β†’ open short page at 100%.

The scenario failed on base and passed on head. Visually, base scales into a corner or clips content; head reflows within a capped-width card, reveals bottom navigation by scrolling, and fits the short page.

Scenario and synthetic page driver

AI-assisted; verified with the tests and tools listed above.

Not shown:

  • Desktop Electron shell was not run; the comparison exercised the real web client.
  • HTML publication and server-side measurement were bypassed with synthetic attachments and replayed tool responses; this proof covers the full-screen rendering and zoom behavior.