# Files changed · PR \#22671 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/pull/22671/diffs)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

[refactor\(web\): the pull requests column lives in its own component](https://git.cafe/pingdotgg/t3code/pull/22671.md)

Version: 6

Head commit: 0f7b1fa34cfd384b42d234f9485a91dbb2d8d188

Base commit: 6a6c84f9906cbdfa7f533fecfc39ce18c2f4c273

Comparison base: 6a6c84f9906cbdfa7f533fecfc39ce18c2f4c273

Showing up to 20 entries from this revision. If the pull request changes, reopen the first page before continuing.

## apps/web/src/components/pullRequest/PullRequestCompactFilterMenu.tsx

Status: added; +93; −0

```diff
@@ -1,0 +1,93 @@
+import { ChevronDownIcon } from "lucide-react";
+import type { ReactNode } from "react";
+
+import { cn } from "~/lib/utils";
+import { Button } from "../ui/button";
+import { Menu, MenuPopup, MenuRadioGroup, MenuRadioItem, MenuTrigger } from "../ui/menu";
+import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";
+import {
+  PullRequestFilterOptionIcon,
+  type PullRequestFilterOption,
+} from "./PullRequestListFilters";
+
+export function PullRequestCompactFilterMenu<Value extends string>({
+  label,
+  triggerIcon,
+  triggerLabel,
+  outlined = false,
+  iconOnly = false,
+  value,
+  options,
+  onChange,
+  className,
+}: {
+  label: string;
+  triggerIcon?: ReactNode;
+  triggerLabel?: string;
+  outlined?: boolean;
+  iconOnly?: boolean;
+  value: Value;
+  options: ReadonlyArray<PullRequestFilterOption<Value>>;
+  onChange: (value: Value) => void;
+  className?: string;
+}) {
+  const current = options.find((option) => option.value === value) ?? options[0];
+  if (!current) return null;
+  return (
+    <Menu>
+      <MenuTrigger
+        aria-label={triggerLabel || iconOnly ? `${label}: ${current.label}` : label}
+        title={iconOnly ? `${label}: ${current.label}` : undefined}
+        render={
+          outlined ? (
+            <Button variant="outline" size={iconOnly ? "icon" : "default"} />
+          ) : (
+            <Button variant="ghost-muted" size="sm" />
+          )
+        }
+        className={cn("min-w-0", className)}
+      >
+        {iconOnly ? (
+          <current.Icon aria-hidden className="size-4" />
+        ) : triggerLabel ? (
+          <>
+            {triggerIcon}
+            <span>{triggerLabel}</span>
+          </>
+        ) : (
+          <>
+            <span className="truncate">{current.label}</span>
+            <ChevronDownIcon aria-hidden className="size-3 shrink-0 text-muted-foreground/70" />
+          </>
+        )}
+      </MenuTrigger>
+      <MenuPopup align="start" side="bottom">
+        <MenuRadioGroup value={value} onValueChange={(next) => onChange(next as Value)}>
+          {options.map((option) => {
+            const item = (
+              <MenuRadioItem
+                key={option.value}
+                value={option.value}
+                disabled={option.unavailable !== undefined}
+                className="data-disabled:pointer-events-auto"
+              >
+                <span className="flex min-w-0 items-center gap-2">
+                  <PullRequestFilterOptionIcon option={option} />
+                  {option.label}
+                </span>
+              </MenuRadioItem>
+            );
+            return option.unavailable === undefined ? (
+              item
+            ) : (
+              <Tooltip key={option.value}>
+                <TooltipTrigger render={item} />
+                <TooltipPopup side="right">{option.unavailable}</TooltipPopup>
+              </Tooltip>
+            );
+          })}
+        </MenuRadioGroup>
+      </MenuPopup>
+    </Menu>
+  );
+}
```

## apps/web/src/components/pullRequest/PullRequestsColumn.tsx

Status: added; +293; −0

```diff
@@ -1,0 +1,293 @@
+import type { PullRequestInvolvement, PullRequestListState } from "@t3tools/contracts";
+import { Plug2Icon, SearchIcon } from "lucide-react";
+import { useEffect, useRef, useState, type ReactNode, type RefObject } from "react";
+
+import { isElectron } from "~/env";
+import { cn } from "~/lib/utils";
+import { Button } from "../ui/button";
+import { RefreshIcon } from "../ui/refresh-icon";
+import {
+  WorkspaceBreadcrumb,
+  WorkspaceBreadcrumbItem,
+  WorkspaceBreadcrumbSeparator,
+} from "../WorkspaceBreadcrumb";
+import { WorkspacePageContainer } from "../WorkspacePageContainer";
+import { WorkspacePageHeader } from "../WorkspacePageHeader";
+import { PullRequestCompactFilterMenu } from "./PullRequestCompactFilterMenu";
+import type { PullRequestFilterOption } from "./PullRequestListFilters";
+import { INVOLVEMENT_TABS, STATE_TABS } from "./pullRequestListOptions";
+
+function ExpandableSearch({
+  searchInput,
+  searchValue,
+  open,
+  onOpenChange,
+  focusToken,
+  onFocusWithin,
+}: {
+  searchInput: ReactNode;
+  searchValue: string;
+  open: boolean;
+  onOpenChange: (open: boolean) => void;
+  focusToken: number;
+  /**
+   * An unmount fires no blur, which is the point: whoever unmounted this can still see the reader
+   * was mid-typing and move the focus somewhere that continues the sentence.
+   */
+  onFocusWithin?: (focused: boolean) => void;
+}) {
+  const containerRef = useRef<HTMLDivElement | null>(null);
+  useEffect(() => {
+    if (!open) return;
+    containerRef.current?.querySelector("input")?.focus();
+  }, [open]);
+  const appliedFocusToken = useRef(focusToken);
+  useEffect(() => {
+    if (appliedFocusToken.current === focusToken) return;
+    appliedFocusToken.current = focusToken;
+    const input = containerRef.current?.querySelector("input");
+    input?.focus();
+    input?.select();
+  }, [focusToken]);
+  if (open || searchValue.length > 0) {
+    return (
+      <div
+        ref={containerRef}
+        className="w-56 min-w-24 shrink"
+        onFocus={() => onFocusWithin?.(true)}
+        onBlur={() => {
+          onFocusWithin?.(false);
+          if (searchValue.length === 0) onOpenChange(false);
+        }}
+      >
+        {searchInput}
+      </div>
+    );
+  }
+  return (
+    <Button
+      size="icon-sm"
+      variant="ghost"
+      aria-label="Search pull requests"
+      onClick={() => onOpenChange(true)}
+    >
+      <SearchIcon className="size-4" />
+    </Button>
+  );
+}
+
+export function PullRequestsColumn({
+  refreshing,
+  onRefresh,
+  searchValue,
+  involvement,
+  state,
+  host,
+  hostMenuOptions,
+  onInvolvement,
+  onState,
+  onHost,
+  searchInput,
+  sortMenu,
+  filtersMenu,
+  rightPanelControl,
+  titlebarControls,
+  rightPanelOpen,
+  maximizedAway,
+  listBody,
+  scrollRef,
+}: {
+  refreshing: boolean;
+  onRefresh: () => void;
+  searchValue: string;
+  involvement: PullRequestInvolvement;
+  state: PullRequestListState;
+  host: string | undefined;
+  hostMenuOptions: ReadonlyArray<PullRequestFilterOption<string>>;
+  onInvolvement: (involvement: PullRequestInvolvement) => void;
+  onState: (state: PullRequestListState) => void;
+  onHost: (host: string | undefined) => void;
+  searchInput: ReactNode;
+  sortMenu: ReactNode;
+  filtersMenu: ReactNode;
+  rightPanelControl: ReactNode;
+  titlebarControls: ReactNode;
+  rightPanelOpen: boolean;
+  maximizedAway: boolean;
+  listBody: ReactNode;
+  scrollRef: RefObject<HTMLDivElement | null>;
+}) {
+  const markerRef = useRef<HTMLDivElement | null>(null);
+  const [condensed, setCondensed] = useState(false);
+  useEffect(() => {
+    const marker = markerRef.current;
+    if (!marker) return;
+    const observer = new IntersectionObserver(
+      ([entry]) => setCondensed(entry ? !entry.isIntersecting : false),
+      { root: scrollRef.current },
+    );
+    observer.observe(marker);
+    return () => observer.disconnect();
+  }, [scrollRef]);
+  // Typing into the topbar search narrows the list, and a short enough list un-scrolls the
+  // page — which dissolves the condensed topbar and unmounts the very input being typed in.
+  const topbarSearchFocusedRef = useRef(false);
+  const inFlowSearchRef = useRef<HTMLDivElement | null>(null);
+  const [searchOpen, setSearchOpen] = useState(false);
+  const [searchFocusToken, setSearchFocusToken] = useState(0);
+  const searchExpanded = searchOpen || searchValue.length > 0;
+  useEffect(() => {
+    const onKeyDown = (event: KeyboardEvent) => {
+      if (event.defaultPrevented) return;
+      if (event.key.toLowerCase() !== "f" || !(event.metaKey || event.ctrlKey)) return;
+      if (event.altKey || event.shiftKey) return;
+      event.preventDefault();
+      if (condensed) {
+        setSearchOpen(true);
+        setSearchFocusToken((token) => token + 1);
+        return;
+      }
+      const input = inFlowSearchRef.current?.querySelector("input");
+      input?.focus();
+      input?.select();
+    };
+    window.addEventListener("keydown", onKeyDown);
+    return () => window.removeEventListener("keydown", onKeyDown);
+  }, [condensed]);
+  if (!condensed && searchOpen) setSearchOpen(false);
+  useEffect(() => {
+    if (condensed) return;
+    if (!topbarSearchFocusedRef.current) return;
+    topbarSearchFocusedRef.current = false;
+    const input = inFlowSearchRef.current?.querySelector("input");
+    if (!input) return;
+    input.focus();
+    input.setSelectionRange(input.value.length, input.value.length);
+  }, [condensed]);
+
+  return (
+    <div
+      className={cn(
+        "@container/pr-list flex min-h-0 min-w-0 flex-col overflow-x-hidden bg-background",
+        maximizedAway ? "w-0 flex-none" : "flex-1",
+      )}
+    >
+      <WorkspacePageHeader
+        electron={isElectron}
+        reserveNativeControls={!rightPanelOpen}
+        className="relative bg-background"
+      >
+        {titlebarControls}
+        {condensed ? (
+          <WorkspaceBreadcrumb ariaLabel="Pull request scope" className="overflow-hidden">
+            <WorkspaceBreadcrumbItem current className={cn(searchExpanded && "sr-only")}>
+              <h1 className="truncate">Pull Requests</h1>
+            </WorkspaceBreadcrumbItem>
+            {searchExpanded ? null : <WorkspaceBreadcrumbSeparator />}
+            <WorkspaceBreadcrumbItem className="shrink gap-1.5">
+              <PullRequestCompactFilterMenu
+                label="Filter by state"
+                value={state}
+                options={STATE_TABS}
+                onChange={onState}
+                className="shrink-0"
+              />
+              <PullRequestCompactFilterMenu
+                label="Filter by involvement"
+                value={involvement}
+                options={INVOLVEMENT_TABS}
+                onChange={onInvolvement}
+              />
+              {hostMenuOptions.length > 2 ? (
+                <PullRequestCompactFilterMenu
+                  label="Filter by host"
+                  value={host ?? ""}
+                  options={hostMenuOptions}
+                  onChange={(next) => onHost(next === "" ? undefined : next)}
+                />
+              ) : null}
+            </WorkspaceBreadcrumbItem>
+          </WorkspaceBreadcrumb>
+        ) : (
+          <WorkspaceBreadcrumb ariaLabel="Pull requests breadcrumb">
+            <WorkspaceBreadcrumbItem current>
+              <h1 className="truncate">Pull Requests</h1>
+            </WorkspaceBreadcrumbItem>
+          </WorkspaceBreadcrumb>
+        )}
+        <div className="min-w-0 flex-1" />
+        {condensed ? (
+          <div className="flex shrink items-center gap-1.5">
+            <ExpandableSearch
+              searchInput={searchInput}
+              searchValue={searchValue}
+              open={searchOpen}
+              onOpenChange={setSearchOpen}
+              focusToken={searchFocusToken}
+              onFocusWithin={(focused) => {
+                topbarSearchFocusedRef.current = focused;
+              }}
+            />
+            <PullRequestRefreshControl compact refreshing={refreshing} onRefresh={onRefresh} />
+          </div>
+        ) : null}
+        {rightPanelControl}
+      </WorkspacePageHeader>
+
+      <div
+        ref={scrollRef}
+        className="topbar-scroll-fade scrollbar-gutter-both min-h-0 flex-1 overflow-y-auto"
+      >
+        <WorkspacePageContainer width="expanded" className="min-h-full gap-4">
+          <div className="flex flex-col gap-3">
+            <div ref={inFlowSearchRef} className="flex flex-wrap items-center gap-2">
+              <div className="min-w-0 basis-full @lg/pr-list:basis-0 @lg/pr-list:flex-1">
+                {searchInput}
+              </div>
+              {sortMenu}
+              {filtersMenu}
+              <PullRequestCompactFilterMenu
+                label="Filter by provider"
+                outlined
+                iconOnly={host !== undefined}
+                triggerIcon={<Plug2Icon aria-hidden className="size-4" />}
+                triggerLabel="All"
+                value={host ?? ""}
+                options={hostMenuOptions}
+                onChange={(next) => onHost(next === "" ? undefined : next)}
+              />
+              {!condensed ? (
+                <PullRequestRefreshControl refreshing={refreshing} onRefresh={onRefresh} />
+              ) : null}
+            </div>
+            <div ref={markerRef} aria-hidden className="-mt-3 h-px w-full" />
+          </div>
+
+          {listBody}
+        </WorkspacePageContainer>
+      </div>
+    </div>
+  );
+}
+
+function PullRequestRefreshControl({
+  compact = false,
+  refreshing,
+  onRefresh,
+}: {
+  compact?: boolean;
+  refreshing: boolean;
+  onRefresh: () => void;
+}) {
+  return (
+    <Button
+      size={compact ? "icon-sm" : "icon"}
+      variant={compact ? "ghost" : "outline"}
+      aria-label="Refresh pull requests"
+      onClick={onRefresh}
+      disabled={refreshing}
+    >
+      <RefreshIcon size="md" refreshing={refreshing} />
+    </Button>
+  );
+}
```

## apps/web/src/components/pullRequest/pullRequestListOptions.ts

Status: added; +40; −0

```diff
@@ -1,0 +1,40 @@
+import type { PullRequestInvolvement, PullRequestListState } from "@t3tools/contracts";
+import {
+  CalendarArrowDownIcon,
+  CalendarArrowUpIcon,
+  ClockIcon,
+  EyeIcon,
+  LayersIcon,
+  ListChecksIcon,
+  Maximize2Icon,
+  Minimize2Icon,
+  PenLineIcon,
+  UserLockIcon,
+} from "lucide-react";
+
+import type { PullRequestFilterOption } from "./PullRequestListFilters";
+import type { PullRequestListSort } from "./pullRequestListPreferences";
+import { PullRequestGlyph } from "./pullRequestIcons";
+
+export const INVOLVEMENT_TABS = [
+  { value: "all", label: "All", Icon: LayersIcon },
+  { value: "reviewing", label: "Reviewing", Icon: EyeIcon },
+  { value: "authored", label: "Authored", Icon: PenLineIcon },
+] as const satisfies ReadonlyArray<PullRequestFilterOption<PullRequestInvolvement>>;
+
+export const STATE_TABS = [
+  { value: "all", label: "All", Icon: LayersIcon },
+  { value: "open", label: "Open", Icon: PullRequestGlyph.pullRequest },
+  { value: "closed", label: "Closed", Icon: PullRequestGlyph.closed },
+  { value: "merged", label: "Merged", Icon: PullRequestGlyph.merged },
+] as const satisfies ReadonlyArray<PullRequestFilterOption<PullRequestListState>>;
+
+export const SORT_OPTIONS = [
+  { value: "ready", label: "Merge readiness", Icon: ListChecksIcon },
+  { value: "blocked", label: "Blocked on me", Icon: UserLockIcon },
+  { value: "updated", label: "Recently updated", Icon: ClockIcon },
+  { value: "newest", label: "Newest shown", Icon: CalendarArrowDownIcon },
+  { value: "oldest", label: "Oldest shown", Icon: CalendarArrowUpIcon },
+  { value: "largest", label: "Largest shown", Icon: Maximize2Icon },
+  { value: "smallest", label: "Smallest shown", Icon: Minimize2Icon },
+] as const satisfies ReadonlyArray<PullRequestFilterOption<PullRequestListSort>>;
```

## apps/web/src/routes/\_chat.pull-requests.tsx

Status: modified; +9; −411

```diff
@@ -2,7 +2,6 @@
   applyPullRequestDraftFilterChange,
   parsePullRequestQuery,
 } from "@t3tools/client-runtime/pull-request-query";
-import { RefreshIcon } from "~/components/ui/refresh-icon";
 import { Spinner } from "~/components/ui/spinner";
 import { useShortcutModifierState } from "~/shortcutModifierState";
 import type { PullRequestSpeedActionResult } from "~/components/pullRequest/PullRequestSpeedActions";
@@ -27,31 +26,14 @@
 import { createFileRoute, useNavigate } from "@tanstack/react-router";
 import {
   ArrowDownUpIcon,
-  CalendarArrowDownIcon,
-  CalendarArrowUpIcon,
-  ChevronDownIcon,
-  ClockIcon,
   EyeIcon,
   LayersIcon,
-  ListChecksIcon,
   PenLineIcon,
   UsersIcon,
   Plug2Icon,
-  Maximize2Icon,
-  Minimize2Icon,
-  SearchIcon,
-  UserLockIcon,
   type LucideIcon,
 } from "lucide-react";
+import { useEffect, useEffectEvent, useRef, useState, type ComponentProps } from "react";
-import {
-  useEffect,
-  useEffectEvent,
-  useRef,
-  useState,
-  type ComponentProps,
-  type ReactNode,
-  type RefObject,
-} from "react";
 
 import {
   filterPullRequestsByInvolvement,
@@ -109,13 +91,19 @@
 import { PullRequestDetailPanel } from "../components/pullRequest/PullRequestDetailPanel";
 import {
   PullRequestFiltersMenu,
-  PullRequestFilterOptionIcon,
   PullRequestSearchInput,
   pullRequestHostLabel,
   pullRequestProjectKey,
   type PullRequestExpectedHost,
   type PullRequestFilterOption,
 } from "../components/pullRequest/PullRequestListFilters";
+import { PullRequestCompactFilterMenu } from "../components/pullRequest/PullRequestCompactFilterMenu";
+import {
+  INVOLVEMENT_TABS,
+  SORT_OPTIONS,
+  STATE_TABS,
+} from "../components/pullRequest/pullRequestListOptions";
+import { PullRequestsColumn } from "../components/pullRequest/PullRequestsColumn";
 import { PullRequestListEmptyState } from "../components/pullRequest/PullRequestListEmptyState";
 import { PullRequestListGhost } from "../components/pullRequest/PullRequestGhosts";
 import {
@@ -124,13 +112,6 @@
 } from "../components/pullRequest/PullRequestRow";
 import { PullRequestsUnavailableState } from "../components/pullRequest/PullRequestsUnavailableState";
 import { RightPanelTabs, type PullRequestTabStatusSeed } from "../components/RightPanelTabs";
-import {
-  WorkspaceBreadcrumb,
-  WorkspaceBreadcrumbItem,
-  WorkspaceBreadcrumbSeparator,
-} from "../components/WorkspaceBreadcrumb";
-import { WorkspacePageContainer } from "../components/WorkspacePageContainer";
-import { WorkspacePageHeader } from "../components/WorkspacePageHeader";
 import { isCommandPaletteOpen } from "../commandPaletteBus";
 import { isElectron } from "../env";
 import { resolveShortcutCommand, shortcutLabelForCommand } from "../keybindings";
@@ -140,9 +121,7 @@
   RightPanelMaximizeControl,
 } from "../components/chat/PanelLayoutControls";
 import { Button } from "../components/ui/button";
-import { Menu, MenuPopup, MenuRadioGroup, MenuRadioItem, MenuTrigger } from "../components/ui/menu";
 import { SidebarInset } from "../components/ui/sidebar";
-import { Tooltip, TooltipPopup, TooltipTrigger } from "../components/ui/tooltip";
 import { useLiveRefresh } from "../hooks/useLiveRefresh";
 import { useStableCallback } from "../hooks/useStableCallback";
 import { useOpenPanelPullRequestUrl } from "../hooks/useOpenPanelPullRequestUrl";
@@ -175,7 +154,6 @@
 import { Separator } from "~/components/ui/separator";
 import { primaryServerKeybindingsAtom } from "~/state/server";
 import { getSourceControlPresentationForKind } from "~/sourceControlPresentation";
-import { PullRequestGlyph } from "~/components/pullRequest/pullRequestIcons";
 
 function getShortcutContext() {
   return {
@@ -222,29 +200,6 @@
   );
 }
 
-const INVOLVEMENT_TABS = [
-  { value: "all", label: "All", Icon: LayersIcon },
-  { value: "reviewing", label: "Reviewing", Icon: EyeIcon },
-  { value: "authored", label: "Authored", Icon: PenLineIcon },
-] as const satisfies ReadonlyArray<PullRequestFilterOption<PullRequestInvolvement>>;
-
-const STATE_TABS = [
-  { value: "all", label: "All", Icon: LayersIcon },
-  { value: "open", label: "Open", Icon: PullRequestGlyph.pullRequest },
-  { value: "closed", label: "Closed", Icon: PullRequestGlyph.closed },
-  { value: "merged", label: "Merged", Icon: PullRequestGlyph.merged },
-] as const satisfies ReadonlyArray<PullRequestFilterOption<PullRequestListState>>;
-
-const SORT_OPTIONS = [
-  { value: "ready", label: "Merge readiness", Icon: ListChecksIcon },
-  { value: "blocked", label: "Blocked on me", Icon: UserLockIcon },
-  { value: "updated", label: "Recently updated", Icon: ClockIcon },
-  { value: "newest", label: "Newest shown", Icon: CalendarArrowDownIcon },
-  { value: "oldest", label: "Oldest shown", Icon: CalendarArrowUpIcon },
-  { value: "largest", label: "Largest shown", Icon: Maximize2Icon },
-  { value: "smallest", label: "Smallest shown", Icon: Minimize2Icon },
-] as const satisfies ReadonlyArray<PullRequestFilterOption<PullRequestListSort>>;
-
 const SEARCH_DEBOUNCE_MS = 250;
 const MATCHED_ELSEWHERE_SCORE = 10;
 /**
@@ -1445,7 +1400,7 @@
     })),
   ];
   const sortMenu = (
+    <PullRequestCompactFilterMenu
-    <CompactFilterMenu
       label="Sort pull requests"
       triggerIcon={<ArrowDownUpIcon aria-hidden className="size-4" />}
       triggerLabel="Sort"
@@ -2143,360 +2098,3 @@
   const projects = sortProjectsByGroupOrder(props.projects, sidebarProjectGroups);
   return <PullRequestFiltersMenu {...props} projects={projects} />;
 }
-
-function CompactFilterMenu<Value extends string>({
-  label,
-  triggerIcon,
-  triggerLabel,
-  outlined = false,
-  iconOnly = false,
-  value,
-  options,
-  onChange,
-  className,
-}: {
-  label: string;
-  triggerIcon?: ReactNode;
-  triggerLabel?: string;
-  outlined?: boolean;
-  iconOnly?: boolean;
-  value: Value;
-  options: ReadonlyArray<PullRequestFilterOption<Value>>;
-  onChange: (value: Value) => void;
-  className?: string;
-}) {
-  const current = options.find((option) => option.value === value) ?? options[0];
-  if (!current) return null;
-  return (
-    <Menu>
-      <MenuTrigger
-        aria-label={triggerLabel || iconOnly ? `${label}: ${current.label}` : label}
-        title={iconOnly ? `${label}: ${current.label}` : undefined}
-        render={
-          outlined ? (
-            <Button variant="outline" size={iconOnly ? "icon" : "default"} />
-          ) : (
-            <Button variant="ghost-muted" size="sm" />
-          )
-        }
-        className={cn("min-w-0", className)}
-      >
-        {iconOnly ? (
-          <current.Icon aria-hidden className="size-4" />
-        ) : triggerLabel ? (
-          <>
-            {triggerIcon}
-            <span>{triggerLabel}</span>
-          </>
-        ) : (
-          <>
-            <span className="truncate">{current.label}</span>
-            <ChevronDownIcon aria-hidden className="size-3 shrink-0 text-muted-foreground/70" />
-          </>
-        )}
-      </MenuTrigger>
-      <MenuPopup align="start" side="bottom">
-        <MenuRadioGroup value={value} onValueChange={(next) => onChange(next as Value)}>
-          {options.map((option) => {
-            const item = (
-              <MenuRadioItem
-                key={option.value}
-                value={option.value}
-                disabled={option.unavailable !== undefined}
-                className="data-disabled:pointer-events-auto"
-              >
-                <span className="flex min-w-0 items-center gap-2">
-                  <PullRequestFilterOptionIcon option={option} />
-                  {option.label}
-                </span>
-              </MenuRadioItem>
-            );
-            return option.unavailable === undefined ? (
-              item
-            ) : (
-              <Tooltip key={option.value}>
-                <TooltipTrigger render={item} />
-                <TooltipPopup side="right">{option.unavailable}</TooltipPopup>
-              </Tooltip>
-            );
-          })}
-        </MenuRadioGroup>
-      </MenuPopup>
-    </Menu>
-  );
-}
-
-function ExpandableSearch({
-  searchInput,
-  searchValue,
-  open,
-  onOpenChange,
-  focusToken,
-  onFocusWithin,
-}: {
-  searchInput: ReactNode;
-  searchValue: string;
-  open: boolean;
-  onOpenChange: (open: boolean) => void;
-  focusToken: number;
-  /**
-   * An unmount fires no blur, which is the point: whoever unmounted this can still see the reader
-   * was mid-typing and move the focus somewhere that continues the sentence.
-   */
-  onFocusWithin?: (focused: boolean) => void;
-}) {
-  const containerRef = useRef<HTMLDivElement | null>(null);
-  useEffect(() => {
-    if (!open) return;
-    containerRef.current?.querySelector("input")?.focus();
-  }, [open]);
-  const appliedFocusToken = useRef(focusToken);
-  useEffect(() => {
-    if (appliedFocusToken.current === focusToken) return;
-    appliedFocusToken.current = focusToken;
-    const input = containerRef.current?.querySelector("input");
-    input?.focus();
-    input?.select();
-  }, [focusToken]);
-  if (open || searchValue.length > 0) {
-    return (
-      <div
-        ref={containerRef}
-        className="w-56 min-w-24 shrink"
-        onFocus={() => onFocusWithin?.(true)}
-        onBlur={() => {
-          onFocusWithin?.(false);
-          if (searchValue.length === 0) onOpenChange(false);
-        }}
-      >
-        {searchInput}
-      </div>
-    );
-  }
-  return (
-    <Button
-      size="icon-sm"
-      variant="ghost"
-      aria-label="Search pull requests"
-      onClick={() => onOpenChange(true)}
-    >
-      <SearchIcon className="size-4" />
-    </Button>
-  );
-}
-
-function PullRequestsColumn({
-  refreshing,
-  onRefresh,
-  searchValue,
-  involvement,
-  state,
-  host,
-  hostMenuOptions,
-  onInvolvement,
-  onState,
-  onHost,
-  searchInput,
-  sortMenu,
-  filtersMenu,
-  rightPanelControl,
-  titlebarControls,
-  rightPanelOpen,
-  maximizedAway,
-  listBody,
-  scrollRef,
-}: {
-  refreshing: boolean;
-  onRefresh: () => void;
-  searchValue: string;
-  involvement: PullRequestInvolvement;
-  state: PullRequestListState;
-  host: string | undefined;
-  hostMenuOptions: ReadonlyArray<PullRequestFilterOption<string>>;
-  onInvolvement: (involvement: PullRequestInvolvement) => void;
-  onState: (state: PullRequestListState) => void;
-  onHost: (host: string | undefined) => void;
-  searchInput: ReactNode;
-  sortMenu: ReactNode;
-  filtersMenu: ReactNode;
-  rightPanelControl: ReactNode;
-  titlebarControls: ReactNode;
-  rightPanelOpen: boolean;
-  maximizedAway: boolean;
-  listBody: ReactNode;
-  scrollRef: RefObject<HTMLDivElement | null>;
-}) {
-  const markerRef = useRef<HTMLDivElement | null>(null);
-  const [condensed, setCondensed] = useState(false);
-  useEffect(() => {
-    const marker = markerRef.current;
-    if (!marker) return;
-    const observer = new IntersectionObserver(
-      ([entry]) => setCondensed(entry ? !entry.isIntersecting : false),
-      { root: scrollRef.current },
-    );
-    observer.observe(marker);
-    return () => observer.disconnect();
-  }, [scrollRef]);
-  // Typing into the topbar search narrows the list, and a short enough list un-scrolls the
-  // page — which dissolves the condensed topbar and unmounts the very input being typed in.
-  const topbarSearchFocusedRef = useRef(false);
-  const inFlowSearchRef = useRef<HTMLDivElement | null>(null);
-  const [searchOpen, setSearchOpen] = useState(false);
-  const [searchFocusToken, setSearchFocusToken] = useState(0);
-  const searchExpanded = searchOpen || searchValue.length > 0;
-  useEffect(() => {
-    const onKeyDown = (event: KeyboardEvent) => {
-      if (event.defaultPrevented) return;
-      if (event.key.toLowerCase() !== "f" || !(event.metaKey || event.ctrlKey)) return;
-      if (event.altKey || event.shiftKey) return;
-      event.preventDefault();
-      if (condensed) {
-        setSearchOpen(true);
-        setSearchFocusToken((token) => token + 1);
-        return;
-      }
-      const input = inFlowSearchRef.current?.querySelector("input");
-      input?.focus();
-      input?.select();
-    };
-    window.addEventListener("keydown", onKeyDown);
-    return () => window.removeEventListener("keydown", onKeyDown);
-  }, [condensed]);
-  if (!condensed && searchOpen) setSearchOpen(false);
-  useEffect(() => {
-    if (condensed) return;
-    if (!topbarSearchFocusedRef.current) return;
-    topbarSearchFocusedRef.current = false;
-    const input = inFlowSearchRef.current?.querySelector("input");
-    if (!input) return;
-    input.focus();
-    input.setSelectionRange(input.value.length, input.value.length);
-  }, [condensed]);
-
-  return (
-    <div
-      className={cn(
-        "@container/pr-list flex min-h-0 min-w-0 flex-col overflow-x-hidden bg-background",
-        maximizedAway ? "w-0 flex-none" : "flex-1",
-      )}
-    >
-      <WorkspacePageHeader
-        electron={isElectron}
-        reserveNativeControls={!rightPanelOpen}
-        className="relative bg-background"
-      >
-        {titlebarControls}
-        {condensed ? (
-          <WorkspaceBreadcrumb ariaLabel="Pull request scope" className="overflow-hidden">
-            <WorkspaceBreadcrumbItem current className={cn(searchExpanded && "sr-only")}>
-              <h1 className="truncate">Pull Requests</h1>
-            </WorkspaceBreadcrumbItem>
-            {searchExpanded ? null : <WorkspaceBreadcrumbSeparator />}
-            <WorkspaceBreadcrumbItem className="shrink gap-1.5">
-              <CompactFilterMenu
-                label="Filter by state"
-                value={state}
-                options={STATE_TABS}
-                onChange={onState}
-                className="shrink-0"
-              />
-              <CompactFilterMenu
-                label="Filter by involvement"
-                value={involvement}
-                options={INVOLVEMENT_TABS}
-                onChange={onInvolvement}
-              />
-              {hostMenuOptions.length > 2 ? (
-                <CompactFilterMenu
-                  label="Filter by host"
-                  value={host ?? ""}
-                  options={hostMenuOptions}
-                  onChange={(next) => onHost(next === "" ? undefined : next)}
-                />
-              ) : null}
-            </WorkspaceBreadcrumbItem>
-          </WorkspaceBreadcrumb>
-        ) : (
-          <WorkspaceBreadcrumb ariaLabel="Pull requests breadcrumb">
-            <WorkspaceBreadcrumbItem current>
-              <h1 className="truncate">Pull Requests</h1>
-            </WorkspaceBreadcrumbItem>
-          </WorkspaceBreadcrumb>
-        )}
-        <div className="min-w-0 flex-1" />
-        {condensed ? (
-          <div className="flex shrink items-center gap-1.5">
-            <ExpandableSearch
-              searchInput={searchInput}
-              searchValue={searchValue}
-              open={searchOpen}
-              onOpenChange={setSearchOpen}
-              focusToken={searchFocusToken}
-              onFocusWithin={(focused) => {
-                topbarSearchFocusedRef.current = focused;
-              }}
-            />
-            <PullRequestRefreshControl compact refreshing={refreshing} onRefresh={onRefresh} />
-          </div>
-        ) : null}
-        {rightPanelControl}
-      </WorkspacePageHeader>
-
-      <div
-        ref={scrollRef}
-        className="topbar-scroll-fade scrollbar-gutter-both min-h-0 flex-1 overflow-y-auto"
-      >
-        <WorkspacePageContainer width="expanded" className="min-h-full gap-4">
-          <div className="flex flex-col gap-3">
-            <div ref={inFlowSearchRef} className="flex flex-wrap items-center gap-2">
-              <div className="min-w-0 basis-full @lg/pr-list:basis-0 @lg/pr-list:flex-1">
-                {searchInput}
-              </div>
-              {sortMenu}
-              {filtersMenu}
-              <CompactFilterMenu
-                label="Filter by provider"
-                outlined
-                iconOnly={host !== undefined}
-                triggerIcon={<Plug2Icon aria-hidden className="size-4" />}
-                triggerLabel="All"
-                value={host ?? ""}
-                options={hostMenuOptions}
-                onChange={(next) => onHost(next === "" ? undefined : next)}
-              />
-              {!condensed ? (
-                <PullRequestRefreshControl refreshing={refreshing} onRefresh={onRefresh} />
-              ) : null}
-            </div>
-            <div ref={markerRef} aria-hidden className="-mt-3 h-px w-full" />
-          </div>
-
-          {listBody}
-        </WorkspacePageContainer>
-      </div>
-    </div>
-  );
-}
-
-function PullRequestRefreshControl({
-  compact = false,
-  refreshing,
-  onRefresh,
-}: {
-  compact?: boolean;
-  refreshing: boolean;
-  onRefresh: () => void;
-}) {
-  return (
-    <Button
-      size={compact ? "icon-sm" : "icon"}
-      variant={compact ? "ghost" : "outline"}
-      aria-label="Refresh pull requests"
-      onClick={onRefresh}
-      disabled={refreshing}
-    >
-      <RefreshIcon size="md" refreshing={refreshing} />
-    </Button>
-  );
-}
```
