authorgravatar for maria@kuuro.netmaria <maria@kuuro.net> 2026-09-03 00:21:27-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-03 00:21:27-04:00
log2a3cfe456375fd34b906f849b04706109dc74170
tree9dc7e6c2c087480bd86730495b6c994883ce1a72
parent5f84efa1ec2fb3cd6f6c54545cc34bb77ac1ddb8
signature Signed by PGP key B5690EEEBB952194

fix(web): collapse PR header actions to icons when narrow (#9334)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

1 files changed, 179 insertions(+), 54 deletions(-)

apps/web/src/components/pullRequest/PullRequestDetailPanel.tsx+179-54
......@@ -1296,8 +1296,8 @@ export function PullRequestDetailPanel({
12961296
12971297 return (
12981298 <div className="flex h-full min-h-0 w-full flex-col bg-background">
1299 <div className="grid shrink-0 grid-cols-[minmax(0,1fr)_auto] items-start gap-x-2 border-b border-border/60">
1300 <div className="ml-4 grid h-7 min-w-0 items-center">
1299 <div className="@container/pr-header grid min-w-0 shrink-0 grid-cols-[minmax(0,1fr)_auto] items-start gap-x-2 border-b border-border/60">
1300 <div className="ml-4 grid h-7 min-w-0 items-center overflow-hidden">
13011301 <div
13021302 aria-hidden={condensed}
13031303 inert={condensed}
......@@ -1402,7 +1402,7 @@ export function PullRequestDetailPanel({
14021402 ) : null}
14031403 </div>
14041404 </div>
1405 <div className="mr-4 flex h-7 min-w-0 flex-nowrap items-center justify-end gap-1">
1405 <div className="mr-4 flex h-7 shrink-0 items-center justify-end gap-1">
14061406 {detail ? (
14071407 <>
14081408 {/* Checking a pull request out is the reason to open one here at all, so it is a
......@@ -1415,9 +1415,17 @@ export function PullRequestDetailPanel({
14151415 <MenuTrigger
14161416 disabled={handoff !== null}
14171417 render={
1418 <Button size="xs" variant="outline">
1418 <Button
1419 size="xs"
1420 variant="outline"
1421 aria-label={
1422 handoff?.startsWith("checkout") ? "Checking out..." : "Check out"
1423 }
1424 >
14191425 <GitBranchIcon aria-hidden className="size-3.5" />
1420 {handoff?.startsWith("checkout") ? "Checking out..." : "Check out"}
1426 <span className="@max-[35rem]/pr-header:hidden">
1427 {handoff?.startsWith("checkout") ? "Checking out..." : "Check out"}
1428 </span>
14211429 <ChevronDownIcon aria-hidden className="size-3.5 text-muted-foreground" />
14221430 </Button>
14231431 }
......@@ -1453,17 +1461,39 @@ export function PullRequestDetailPanel({
14531461 </Menu>
14541462 ) : null}
14551463 {workflowApprovalsRequired > 0 && can("approve-workflows") ? (
1456 <Button
1457 size="xs"
1458 variant="warning-outline"
1459 disabled={actionPending}
1460 onClick={() => setConfirmation({ open: true, action: "approve-workflows" })}
1461 >
1462 <PlayIcon className="size-3.5" />
1463 {pendingAction === "approve-workflows"
1464 ? "Approving..."
1465 : "Approve workflows to run"}
1466 </Button>
1464 <Tooltip>
1465 <TooltipTrigger
1466 render={
1467 <span className="inline-flex shrink-0">
1468 <Button
1469 size="xs"
1470 variant="warning-outline"
1471 disabled={actionPending}
1472 onClick={() =>
1473 setConfirmation({ open: true, action: "approve-workflows" })
1474 }
1475 aria-label={
1476 pendingAction === "approve-workflows"
1477 ? "Approving..."
1478 : "Approve workflows to run"
1479 }
1480 >
1481 <PlayIcon aria-hidden className="size-3.5" />
1482 <span className="@max-[40rem]/pr-header:hidden">
1483 {pendingAction === "approve-workflows"
1484 ? "Approving..."
1485 : "Approve workflows to run"}
1486 </span>
1487 </Button>
1488 </span>
1489 }
1490 />
1491 <TooltipPopup side="top">
1492 {pendingAction === "approve-workflows"
1493 ? "Approving..."
1494 : "Approve workflows to run"}
1495 </TooltipPopup>
1496 </Tooltip>
14671497 ) : null}
14681498 {/* Said where the Merge button is, because it is the answer to why nobody has
14691499 pressed it: the merge is already asked for, and the host is holding it. */}
......@@ -1471,62 +1501,150 @@ export function PullRequestDetailPanel({
14711501 <Tooltip>
14721502 <TooltipTrigger
14731503 render={
1474 <Badge size="control" variant="info">
1504 <Badge
1505 size="control"
1506 variant="info"
1507 role="img"
1508 aria-label={armedAutoMergeLabel}
1509 >
14751510 <GitMergeIcon aria-hidden className="size-3.5" />
1476 {armedAutoMergeLabel}
1511 <span className="@max-[30rem]/pr-header:hidden">{armedAutoMergeLabel}</span>
14771512 </Badge>
14781513 }
14791514 />
14801515 <TooltipPopup side="top">
1481 The host will merge this on its own once its requirements are met
1516 {armedAutoMergeLabel}: the host will merge this on its own once its requirements
1517 are met
14821518 </TooltipPopup>
14831519 </Tooltip>
14841520 ) : null}
14851521 {primaryAction === "resolve" ? (
1486 <Button
1487 size="xs"
1488 variant="destructive-outline"
1489 disabled={handoff !== null}
1490 onClick={startResolveConflicts}
1491 >
1492 <TriangleAlertIcon className="size-3.5" />
1493 {handoff === "conflicts" ? "Preparing..." : "Resolve conflicts"}
1494 </Button>
1522 <Tooltip>
1523 <TooltipTrigger
1524 render={
1525 <span className="inline-flex shrink-0">
1526 <Button
1527 size="xs"
1528 variant="destructive-outline"
1529 disabled={handoff !== null}
1530 onClick={startResolveConflicts}
1531 aria-label={
1532 handoff === "conflicts" ? "Preparing..." : "Resolve conflicts"
1533 }
1534 >
1535 <TriangleAlertIcon aria-hidden className="size-3.5" />
1536 <span className="@max-[30rem]/pr-header:hidden">
1537 {handoff === "conflicts" ? "Preparing..." : "Resolve conflicts"}
1538 </span>
1539 </Button>
1540 </span>
1541 }
1542 />
1543 <TooltipPopup side="top">
1544 {handoff === "conflicts" ? "Preparing..." : "Resolve conflicts"}
1545 </TooltipPopup>
1546 </Tooltip>
14951547 ) : primaryAction === "ready" ? (
1496 <Button size="xs" disabled={actionPending} onClick={() => void perform("ready")}>
1497 Ready for review
1498 </Button>
1548 <Tooltip>
1549 <TooltipTrigger
1550 render={
1551 <span className="inline-flex shrink-0">
1552 <Button
1553 size="xs"
1554 disabled={actionPending}
1555 onClick={() => void perform("ready")}
1556 aria-label="Ready for review"
1557 >
1558 <GitPullRequestIcon
1559 aria-hidden
1560 className="hidden size-3.5 @max-[30rem]/pr-header:inline"
1561 />
1562 <span className="@max-[30rem]/pr-header:hidden">Ready for review</span>
1563 </Button>
1564 </span>
1565 }
1566 />
1567 <TooltipPopup side="top">Ready for review</TooltipPopup>
1568 </Tooltip>
14991569 ) : primaryAction === "enable-auto-merge" ? (
1500 <Button
1501 size="xs"
1502 disabled={actionPending}
1503 onClick={() => setConfirmation({ open: true, action: "enable-auto-merge" })}
1504 >
1505 <GitMergeIcon className="size-3.5" />
1506 {pendingAction === "enable-auto-merge" ? "Enabling..." : pendingAutoMergeLabel}
1507 </Button>
1570 <Tooltip>
1571 <TooltipTrigger
1572 render={
1573 <span className="inline-flex shrink-0">
1574 <Button
1575 size="xs"
1576 disabled={actionPending}
1577 onClick={() =>
1578 setConfirmation({ open: true, action: "enable-auto-merge" })
1579 }
1580 aria-label={
1581 pendingAction === "enable-auto-merge"
1582 ? "Enabling..."
1583 : pendingAutoMergeLabel
1584 }
1585 >
1586 <GitMergeIcon aria-hidden className="size-3.5" />
1587 <span className="@max-[30rem]/pr-header:hidden">
1588 {pendingAction === "enable-auto-merge"
1589 ? "Enabling..."
1590 : pendingAutoMergeLabel}
1591 </span>
1592 </Button>
1593 </span>
1594 }
1595 />
1596 <TooltipPopup side="top">
1597 {pendingAction === "enable-auto-merge" ? "Enabling..." : pendingAutoMergeLabel}
1598 </TooltipPopup>
1599 </Tooltip>
15081600 ) : primaryAction === "auto-merge-armed" ? (
15091601 <Tooltip>
15101602 <TooltipTrigger
15111603 render={
1512 <Badge size="control" variant="info">
1513 <GitMergeIcon className="size-3.5" />
1514 {armedAutoMergeLabel}
1604 <Badge
1605 size="control"
1606 variant="info"
1607 role="img"
1608 aria-label={armedAutoMergeLabel}
1609 >
1610 <GitMergeIcon aria-hidden className="size-3.5" />
1611 <span className="@max-[30rem]/pr-header:hidden">{armedAutoMergeLabel}</span>
15151612 </Badge>
15161613 }
15171614 />
15181615 <TooltipPopup side="top">
1519 The host will merge this on its own once its requirements are met
1616 {armedAutoMergeLabel}: the host will merge this on its own once its requirements
1617 are met
15201618 </TooltipPopup>
15211619 </Tooltip>
15221620 ) : primaryAction === "merge" ? (
1523 <Button
1524 size="xs"
1525 disabled={actionPending}
1526 onClick={() => setConfirmation({ open: true, action: "merge" })}
1527 >
1528 {pendingAction === "merge" ? "Merging..." : selectedMergeMethodLabel}
1529 </Button>
1621 <Tooltip>
1622 <TooltipTrigger
1623 render={
1624 <span className="inline-flex shrink-0">
1625 <Button
1626 size="xs"
1627 disabled={actionPending}
1628 onClick={() => setConfirmation({ open: true, action: "merge" })}
1629 aria-label={
1630 pendingAction === "merge" ? "Merging..." : selectedMergeMethodLabel
1631 }
1632 >
1633 <GitMergeIcon
1634 aria-hidden
1635 className="hidden size-3.5 @max-[30rem]/pr-header:inline"
1636 />
1637 <span className="@max-[30rem]/pr-header:hidden">
1638 {pendingAction === "merge" ? "Merging..." : selectedMergeMethodLabel}
1639 </span>
1640 </Button>
1641 </span>
1642 }
1643 />
1644 <TooltipPopup side="top">
1645 {pendingAction === "merge" ? "Merging..." : selectedMergeMethodLabel}
1646 </TooltipPopup>
1647 </Tooltip>
15301648 ) : (primaryAction === "merged" || primaryAction === "closed") &&
15311649 statePresentation !== null ? (
15321650 <Badge size="control" variant="outline" className={statePresentation.toneClassName}>
......@@ -1857,10 +1975,17 @@ export function PullRequestDetailPanel({
18571975 {detail ? (
18581976 <div className="col-span-2 mt-1 min-w-0 px-4 pb-4">
18591977 {titleDraft === null ? (
1860 <div className="group flex min-w-0 items-start gap-1">
1861 <h1 className="min-w-0 flex-1 text-base font-semibold leading-snug">
1862 {detail.title}
1863 </h1>
1978 <div className="group flex min-w-0 items-center gap-1">
1979 <Tooltip>
1980 <TooltipTrigger
1981 render={
1982 <h1 className="min-w-0 flex-1 truncate text-base font-semibold leading-snug">
1983 {detail.title}
1984 </h1>
1985 }
1986 />
1987 <TooltipPopup side="top">{detail.title}</TooltipPopup>
1988 </Tooltip>
18641989 {canEditPullRequestChangeRequest(detail) ? (
18651990 <Button
18661991 size="icon-xs"