From b41bb824e603faa4d16ba99b08d0de3571728a83 Mon Sep 17 00:00:00 2001 From: maria-rcks Date: Sat, 19 Sep 2026 02:38:53 +0000 Subject: [PATCH 1/3] fix(web): route keyboard submit through the primary worktree action --- .../BranchToolbarBranchSelector.tsx | 53 ++++++++++++++++++- .../components/PullRequestThreadDialog.tsx | 2 +- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/apps/web/src/components/BranchToolbarBranchSelector.tsx b/apps/web/src/components/BranchToolbarBranchSelector.tsx index d958f2f76625..7adc8dcf4dea 100644 --- a/apps/web/src/components/BranchToolbarBranchSelector.tsx +++ b/apps/web/src/components/BranchToolbarBranchSelector.tsx @@ -545,6 +545,7 @@ export function BranchToolbarBranchSelector({ setIsBranchMenuOpen(open); if (!open) { setBranchQuery(""); + highlightedBranchValueRef.current = null; } }, []); @@ -594,6 +595,9 @@ export function BranchToolbarBranchSelector({ }, [fetchNextBranchPage, hasNextPage, isBranchMenuOpen, isFetchingNextPage]); const branchListRef = useRef(null); + // Tracks the highlighted picker value so Enter can activate it even when the + // virtualized row is not mounted (Base UI Enter clicks the mounted element). + const highlightedBranchValueRef = useRef(null); const updateBranchListScrollFades = useCallback(() => { const scrollElement = branchListRef.current?.getScrollableNode?.(); if (!(scrollElement instanceof HTMLElement)) { @@ -760,7 +764,8 @@ export function BranchToolbarBranchSelector({ filteredItems={filteredBranchPickerItems} autoHighlight virtualized - onItemHighlighted={(_value, eventDetails) => { + onItemHighlighted={(value, eventDetails) => { + highlightedBranchValueRef.current = typeof value === "string" ? value : null; if (!isBranchMenuOpen || eventDetails.index < 0 || eventDetails.reason !== "keyboard") { return; } @@ -828,6 +833,52 @@ export function BranchToolbarBranchSelector({ placeholder="Search refs..." value={branchQuery} onChange={(event) => setBranchQuery(event.target.value)} + onKeyDown={(event) => { + if (event.key !== "Enter") { + return; + } + const highlightedValue = highlightedBranchValueRef.current; + if (highlightedValue === null) { + return; + } + if ( + highlightedValue === checkoutPullRequestItemValue && + prReference && + onCheckoutPullRequestRequest + ) { + ( + event as typeof event & { preventBaseUIHandler?: () => void } + ).preventBaseUIHandler?.(); + event.preventDefault(); + event.stopPropagation(); + setIsBranchMenuOpen(false); + setBranchQuery(""); + highlightedBranchValueRef.current = null; + onComposerFocusRequest?.(); + onCheckoutPullRequestRequest(prReference); + return; + } + if (highlightedValue === createBranchItemValue) { + ( + event as typeof event & { preventBaseUIHandler?: () => void } + ).preventBaseUIHandler?.(); + event.preventDefault(); + event.stopPropagation(); + highlightedBranchValueRef.current = null; + createRef(trimmedBranchQuery); + return; + } + const highlightedRef = branchByName.get(highlightedValue); + if (highlightedRef) { + ( + event as typeof event & { preventBaseUIHandler?: () => void } + ).preventBaseUIHandler?.(); + event.preventDefault(); + event.stopPropagation(); + highlightedBranchValueRef.current = null; + selectBranch(highlightedRef); + } + }} />
No refs found. diff --git a/apps/web/src/components/PullRequestThreadDialog.tsx b/apps/web/src/components/PullRequestThreadDialog.tsx index 4004b4930c27..6d010f26f357 100644 --- a/apps/web/src/components/PullRequestThreadDialog.tsx +++ b/apps/web/src/components/PullRequestThreadDialog.tsx @@ -224,7 +224,7 @@ export function PullRequestThreadDialog({ } event.preventDefault(); if (!isResolving && !preparePullRequestThreadAction.isPending) { - void handleConfirm("local"); + void handleConfirm("worktree"); } }} /> From 56c777967baba477aab775b0b9c7ceeb5d580d7e Mon Sep 17 00:00:00 2001 From: maria-rcks Date: Sat, 19 Sep 2026 02:46:33 +0000 Subject: [PATCH 2/3] fix(web): ignore Enter during IME composition in PR inputs --- apps/web/src/components/BranchToolbarBranchSelector.tsx | 3 +++ apps/web/src/components/PullRequestThreadDialog.tsx | 3 +++ 2 files changed, 6 insertions(+) diff --git a/apps/web/src/components/BranchToolbarBranchSelector.tsx b/apps/web/src/components/BranchToolbarBranchSelector.tsx index 7adc8dcf4dea..26010ee436d0 100644 --- a/apps/web/src/components/BranchToolbarBranchSelector.tsx +++ b/apps/web/src/components/BranchToolbarBranchSelector.tsx @@ -837,6 +837,9 @@ export function BranchToolbarBranchSelector({ if (event.key !== "Enter") { return; } + if (event.nativeEvent.isComposing || event.keyCode === 229) { + return; + } const highlightedValue = highlightedBranchValueRef.current; if (highlightedValue === null) { return; diff --git a/apps/web/src/components/PullRequestThreadDialog.tsx b/apps/web/src/components/PullRequestThreadDialog.tsx index 6d010f26f357..ddbd2876d4d2 100644 --- a/apps/web/src/components/PullRequestThreadDialog.tsx +++ b/apps/web/src/components/PullRequestThreadDialog.tsx @@ -222,6 +222,9 @@ export function PullRequestThreadDialog({ if (event.key !== "Enter") { return; } + if (event.nativeEvent.isComposing || event.keyCode === 229) { + return; + } event.preventDefault(); if (!isResolving && !preparePullRequestThreadAction.isPending) { void handleConfirm("worktree"); From 25b24006d82c04bf5659439357c176c02409e4a4 Mon Sep 17 00:00:00 2001 From: maria-rcks Date: Sat, 19 Sep 2026 17:59:35 +0000 Subject: [PATCH 3/3] refactor(web): share branch picker activation across inputs --- .../BranchToolbarBranchSelector.tsx | 77 +++++++------------ 1 file changed, 26 insertions(+), 51 deletions(-) diff --git a/apps/web/src/components/BranchToolbarBranchSelector.tsx b/apps/web/src/components/BranchToolbarBranchSelector.tsx index 26010ee436d0..a7fa1ce99724 100644 --- a/apps/web/src/components/BranchToolbarBranchSelector.tsx +++ b/apps/web/src/components/BranchToolbarBranchSelector.tsx @@ -680,6 +680,20 @@ export function BranchToolbarBranchSelector({ const prUrl = currentLinkedPr?.url ?? displayedPr?.url; const openPrLink = useOpenPrLink(threadRef); + function selectPickerItem(itemValue: string) { + highlightedBranchValueRef.current = null; + if (itemValue === checkoutPullRequestItemValue && prReference && onCheckoutPullRequestRequest) { + handleOpenChange(false); + onComposerFocusRequest?.(); + onCheckoutPullRequestRequest(prReference); + } else if (itemValue === createBranchItemValue) { + createRef(trimmedBranchQuery); + } else { + const refName = branchByName.get(itemValue); + if (refName) selectBranch(refName); + } + } + function renderPickerItem(itemValue: string, index: number) { if (checkoutPullRequestItemValue && itemValue === checkoutPullRequestItemValue) { return ( @@ -689,15 +703,7 @@ export function BranchToolbarBranchSelector({ index={index} value={itemValue} className="pe-2" - onClick={() => { - if (!prReference || !onCheckoutPullRequestRequest) { - return; - } - setIsBranchMenuOpen(false); - setBranchQuery(""); - onComposerFocusRequest?.(); - onCheckoutPullRequestRequest(prReference); - }} + onClick={() => selectPickerItem(itemValue)} >
@@ -719,7 +725,7 @@ export function BranchToolbarBranchSelector({ index={index} value={itemValue} className="pe-1.5" - onClick={() => createRef(trimmedBranchQuery)} + onClick={() => selectPickerItem(itemValue)} > Create new ref "{newRefName}" @@ -747,7 +753,7 @@ export function BranchToolbarBranchSelector({ index={index} value={itemValue} className="pe-1.5" - onClick={() => selectBranch(refName)} + onClick={() => selectPickerItem(itemValue)} onContextMenu={(event) => handleBranchContextMenu(event, itemValue)} >
@@ -834,53 +840,22 @@ export function BranchToolbarBranchSelector({ value={branchQuery} onChange={(event) => setBranchQuery(event.target.value)} onKeyDown={(event) => { - if (event.key !== "Enter") { - return; - } - if (event.nativeEvent.isComposing || event.keyCode === 229) { + if (event.key !== "Enter" || event.nativeEvent.isComposing || event.keyCode === 229) { return; } const highlightedValue = highlightedBranchValueRef.current; - if (highlightedValue === null) { - return; - } if ( - highlightedValue === checkoutPullRequestItemValue && - prReference && - onCheckoutPullRequestRequest + highlightedValue === null || + !filteredBranchPickerItems.includes(highlightedValue) ) { - ( - event as typeof event & { preventBaseUIHandler?: () => void } - ).preventBaseUIHandler?.(); - event.preventDefault(); - event.stopPropagation(); - setIsBranchMenuOpen(false); - setBranchQuery(""); - highlightedBranchValueRef.current = null; - onComposerFocusRequest?.(); - onCheckoutPullRequestRequest(prReference); return; } - if (highlightedValue === createBranchItemValue) { - ( - event as typeof event & { preventBaseUIHandler?: () => void } - ).preventBaseUIHandler?.(); - event.preventDefault(); - event.stopPropagation(); - highlightedBranchValueRef.current = null; - createRef(trimmedBranchQuery); - return; - } - const highlightedRef = branchByName.get(highlightedValue); - if (highlightedRef) { - ( - event as typeof event & { preventBaseUIHandler?: () => void } - ).preventBaseUIHandler?.(); - event.preventDefault(); - event.stopPropagation(); - highlightedBranchValueRef.current = null; - selectBranch(highlightedRef); - } + ( + event as typeof event & { preventBaseUIHandler?: () => void } + ).preventBaseUIHandler?.(); + event.preventDefault(); + event.stopPropagation(); + selectPickerItem(highlightedValue); }} />