| ... | ... | @@ -545,6 +545,7 @@ export function BranchToolbarBranchSelector({ |
| 545 | 545 | setIsBranchMenuOpen(open); |
| 546 | 546 | if (!open) { |
| 547 | 547 | setBranchQuery(""); |
| 548 | highlightedBranchValueRef.current = null; |
| 548 | 549 | } |
| 549 | 550 | }, []); |
| 550 | 551 | |
| ... | ... | @@ -594,6 +595,9 @@ export function BranchToolbarBranchSelector({ |
| 594 | 595 | }, [fetchNextBranchPage, hasNextPage, isBranchMenuOpen, isFetchingNextPage]); |
| 595 | 596 | |
| 596 | 597 | const branchListRef = useRef<LegendListRef | null>(null); |
| 598 | // Tracks the highlighted picker value so Enter can activate it even when the |
| 599 | // virtualized row is not mounted (Base UI Enter clicks the mounted element). |
| 600 | const highlightedBranchValueRef = useRef<string | null>(null); |
| 597 | 601 | const updateBranchListScrollFades = useCallback(() => { |
| 598 | 602 | const scrollElement = branchListRef.current?.getScrollableNode?.(); |
| 599 | 603 | if (!(scrollElement instanceof HTMLElement)) { |
| ... | ... | @@ -676,6 +680,20 @@ export function BranchToolbarBranchSelector({ |
| 676 | 680 | const prUrl = currentLinkedPr?.url ?? displayedPr?.url; |
| 677 | 681 | const openPrLink = useOpenPrLink(threadRef); |
| 678 | 682 | |
| 683 | function selectPickerItem(itemValue: string) { |
| 684 | highlightedBranchValueRef.current = null; |
| 685 | if (itemValue === checkoutPullRequestItemValue && prReference && onCheckoutPullRequestRequest) { |
| 686 | handleOpenChange(false); |
| 687 | onComposerFocusRequest?.(); |
| 688 | onCheckoutPullRequestRequest(prReference); |
| 689 | } else if (itemValue === createBranchItemValue) { |
| 690 | createRef(trimmedBranchQuery); |
| 691 | } else { |
| 692 | const refName = branchByName.get(itemValue); |
| 693 | if (refName) selectBranch(refName); |
| 694 | } |
| 695 | } |
| 696 | |
| 679 | 697 | function renderPickerItem(itemValue: string, index: number) { |
| 680 | 698 | if (checkoutPullRequestItemValue && itemValue === checkoutPullRequestItemValue) { |
| 681 | 699 | return ( |
| ... | ... | @@ -685,15 +703,7 @@ export function BranchToolbarBranchSelector({ |
| 685 | 703 | index={index} |
| 686 | 704 | value={itemValue} |
| 687 | 705 | className="pe-2" |
| 688 | | onClick={() => { |
| 689 | | if (!prReference || !onCheckoutPullRequestRequest) { |
| 690 | | return; |
| 691 | | } |
| 692 | | setIsBranchMenuOpen(false); |
| 693 | | setBranchQuery(""); |
| 694 | | onComposerFocusRequest?.(); |
| 695 | | onCheckoutPullRequestRequest(prReference); |
| 696 | | }} |
| 706 | onClick={() => selectPickerItem(itemValue)} |
| 697 | 707 | > |
| 698 | 708 | <div className="flex min-w-0 items-center gap-2 py-1"> |
| 699 | 709 | <SourceControlIcon className="size-3.5 shrink-0 text-muted-foreground" /> |
| ... | ... | @@ -715,7 +725,7 @@ export function BranchToolbarBranchSelector({ |
| 715 | 725 | index={index} |
| 716 | 726 | value={itemValue} |
| 717 | 727 | className="pe-1.5" |
| 718 | | onClick={() => createRef(trimmedBranchQuery)} |
| 728 | onClick={() => selectPickerItem(itemValue)} |
| 719 | 729 | > |
| 720 | 730 | <span className="truncate">Create new ref &quot;{newRefName}&quot;</span> |
| 721 | 731 | </ComboboxItem> |
| ... | ... | @@ -743,7 +753,7 @@ export function BranchToolbarBranchSelector({ |
| 743 | 753 | index={index} |
| 744 | 754 | value={itemValue} |
| 745 | 755 | className="pe-1.5" |
| 746 | | onClick={() => selectBranch(refName)} |
| 756 | onClick={() => selectPickerItem(itemValue)} |
| 747 | 757 | onContextMenu={(event) => handleBranchContextMenu(event, itemValue)} |
| 748 | 758 | > |
| 749 | 759 | <div className="flex w-full min-w-0 items-center justify-between gap-2"> |
| ... | ... | @@ -760,7 +770,8 @@ export function BranchToolbarBranchSelector({ |
| 760 | 770 | filteredItems={filteredBranchPickerItems} |
| 761 | 771 | autoHighlight |
| 762 | 772 | virtualized |
| 763 | | onItemHighlighted={(_value, eventDetails) => { |
| 773 | onItemHighlighted={(value, eventDetails) => { |
| 774 | highlightedBranchValueRef.current = typeof value === "string" ? value : null; |
| 764 | 775 | if (!isBranchMenuOpen || eventDetails.index < 0 || eventDetails.reason !== "keyboard") { |
| 765 | 776 | return; |
| 766 | 777 | } |
| ... | ... | @@ -828,6 +839,24 @@ export function BranchToolbarBranchSelector({ |
| 828 | 839 | placeholder="Search refs..." |
| 829 | 840 | value={branchQuery} |
| 830 | 841 | onChange={(event) => setBranchQuery(event.target.value)} |
| 842 | onKeyDown={(event) => { |
| 843 | if (event.key !== "Enter" || event.nativeEvent.isComposing || event.keyCode === 229) { |
| 844 | return; |
| 845 | } |
| 846 | const highlightedValue = highlightedBranchValueRef.current; |
| 847 | if ( |
| 848 | highlightedValue === null || |
| 849 | !filteredBranchPickerItems.includes(highlightedValue) |
| 850 | ) { |
| 851 | return; |
| 852 | } |
| 853 | ( |
| 854 | event as typeof event & { preventBaseUIHandler?: () => void } |
| 855 | ).preventBaseUIHandler?.(); |
| 856 | event.preventDefault(); |
| 857 | event.stopPropagation(); |
| 858 | selectPickerItem(highlightedValue); |
| 859 | }} |
| 831 | 860 | /> |
| 832 | 861 | <div className="flex min-h-0 flex-1 flex-col overflow-hidden"> |
| 833 | 862 | <ComboboxEmpty>No refs found.</ComboboxEmpty> |