From 68fce52b4b1855fb388d67a331f7c95149434105 Mon Sep 17 00:00:00 2001
From: badcuban <108198679+badcuban@users.noreply.github.com>
Date: Fri, 4 Sep 2026 22:51:19 -0400
Subject: [PATCH] fix(web): pull request tab fits the narrow side panel
The pull request detail header only rearranged itself when the window was
phone-sized, so beside a thread, where the panel can be 272px wide on a
wide screen, the checks rollup was pushed past the edge, the author was
squeezed out of the updated line, and the number was clipped behind the
action buttons.
The panel is now its own container and the header answers to its width:
the actions wrap under the repository line, the title wraps to two lines,
the checkout command and the diff counts drop under their rows, and the
tab strip keeps its glyphs and hides the words beside them, with the
words in a tooltip and for screen readers. The Summary's meta rows wrap
rather than overflow.
---
.../pull-requests/PullRequestDetailPanel.tsx | 104 +++++++++++-------
.../pull-requests/PullRequestSummaryTab.tsx | 6 +-
.../pull-requests/pullRequestPresentation.tsx | 5 +-
3 files changed, 71 insertions(+), 44 deletions(-)
diff --git a/apps/web/src/components/pull-requests/PullRequestDetailPanel.tsx b/apps/web/src/components/pull-requests/PullRequestDetailPanel.tsx
index 6a288c73..e0790a86 100644
--- a/apps/web/src/components/pull-requests/PullRequestDetailPanel.tsx
+++ b/apps/web/src/components/pull-requests/PullRequestDetailPanel.tsx
@@ -400,7 +400,10 @@ export function PullRequestDetailPanel({
return (
{/* The order toggle shares the row but not the tablist: it is not a tab,
- and inside one it would answer to the arrow keys as though it were. */}
+ and inside one it would answer to the arrow keys as though it were.
+ The tabs are drawn whole at every width; in a narrow panel they close
+ ranks and the control beside them keeps its glyph and loses its words,
+ so nothing is pushed past the edge. */}
-
+
{activeTab === "timeline" ? (
-
+
+
) : null}
{/* The rollup the header used to spell out on a line of its own. It is
a way into the Summary's Checks section rather than a label, so it
@@ -600,7 +619,7 @@ function PullRequestDetailHeader({
return (
{/* Row 1: where it lives, and what can be done to it. */}
-
+
{/* On a phone the list is not on screen, so the way back sits where
a back arrow belongs: first, at the top left. */}
@@ -624,7 +643,7 @@ function PullRequestDetailHeader({
Auto-merge on
) : null}
-
+
{showCheckout ? (
{/* Row 3: who wrote it, when it last moved, and the one command that
- takes the branch on a machine this app is not running on. */}
-
-
+ takes the branch on a machine this app is not running on. The command
+ drops to a line of its own before it can squeeze the author out. */}
+
- {/* Row 4: the branches this joins, and how much it changes. Below `md`
- the counts drop to a line of their own: the branch names are what the
- row is for, and sharing the line leaves them a letter each. */}
+ {/* Row 4: the branches this joins, and how much it changes. In a narrow
+ panel the counts drop to a line of their own: the branch names are
+ what the row is for, and sharing the line leaves them a letter each. */}
@@ -717,7 +737,7 @@ function PullRequestDetailHeader({
) : null}
-
+
{pluralize(detail.changedFiles, "file")}
@@ -815,7 +835,8 @@ function PullRequestCheckoutMenu({
* The rollup of the checks, beside the tabs: a glyph, a phrase, and a way down
* to the rows it counts. The glyph is drawn here rather than taken whole from
* the presentation module, because inside a button a second tooltip trigger
- * would fight the button for the pointer.
+ * would fight the button for the pointer. In a narrow panel the phrase is for
+ * screen readers and the tooltip only, and the glyph stands for it.
*/
function PullRequestChecksRollup({
summary,
@@ -825,23 +846,26 @@ function PullRequestChecksRollup({
readonly onShowChecks: () => void;
}) {
const tone = pullRequestChecksTone(summary.state);
+ const headline = formatPullRequestChecksHeadline(summary);
return (
-
+
+
+
);
}
@@ -977,11 +1001,11 @@ function PullRequestTitle({
tabIndex={-1}
className="group/title flex min-w-0 flex-1 items-center gap-1.5 rounded-sm focus-ring"
>
- {/* A phone's column, and a tablet's, are narrow enough that one truncated
+ {/* A phone's column, and a sidebar's, are narrow enough that one truncated
line says almost nothing, so there it wraps to two before it gives
up. */}
{detail.title}
diff --git a/apps/web/src/components/pull-requests/PullRequestSummaryTab.tsx b/apps/web/src/components/pull-requests/PullRequestSummaryTab.tsx
index cfc28c08..24756a12 100644
--- a/apps/web/src/components/pull-requests/PullRequestSummaryTab.tsx
+++ b/apps/web/src/components/pull-requests/PullRequestSummaryTab.tsx
@@ -99,7 +99,7 @@ export function PullRequestSummaryTab({
} label="Reviewers">
{detail.reviewers.length === 0 ? (
- No reviewers
+ No reviewers
) : (
detail.reviewers.map((reviewer) => (
@@ -224,7 +224,9 @@ function PullRequestMetaRow({
{icon}
{label}
- {children}
+ {/* The row wraps rather than overflows: in a narrow panel the Request
+ button sits under the reviewers instead of past the edge. */}
+ {children}