fix: put selected repos at the top of the repo selector list. Aslo retain scroll position

This commit is contained in:
bkellam 2025-07-25 09:32:33 -07:00
parent 1cc23818c2
commit 74e37d129c

View file

@ -49,6 +49,9 @@ export const RepoSelector = React.forwardRef<
}, },
ref ref
) => { ) => {
const scrollContainerRef = React.useRef<HTMLDivElement>(null);
const scrollPosition = React.useRef<number>(0);
const handleInputKeyDown = ( const handleInputKeyDown = (
event: React.KeyboardEvent<HTMLInputElement> event: React.KeyboardEvent<HTMLInputElement>
) => { ) => {
@ -62,6 +65,11 @@ export const RepoSelector = React.forwardRef<
}; };
const toggleRepo = (repo: string) => { const toggleRepo = (repo: string) => {
// Store current scroll position before state update
if (scrollContainerRef.current) {
scrollPosition.current = scrollContainerRef.current.scrollTop;
}
const newSelectedValues = selectedRepos.includes(repo) const newSelectedValues = selectedRepos.includes(repo)
? selectedRepos.filter((value) => value !== repo) ? selectedRepos.filter((value) => value !== repo)
: [...selectedRepos, repo]; : [...selectedRepos, repo];
@ -76,6 +84,26 @@ export const RepoSelector = React.forwardRef<
onOpenChanged(!isOpen); onOpenChanged(!isOpen);
}; };
const sortedRepos = React.useMemo(() => {
return repos
.map((repo) => ({
repo,
isSelected: selectedRepos.includes(repo)
}))
.sort((a, b) => {
if (a.isSelected && !b.isSelected) return -1;
if (!a.isSelected && b.isSelected) return 1;
return 0;
})
}, [repos, selectedRepos]);
// Restore scroll position after re-render
React.useEffect(() => {
if (scrollContainerRef.current && scrollPosition.current > 0) {
scrollContainerRef.current.scrollTop = scrollPosition.current;
}
}, [sortedRepos]);
return ( return (
<Popover <Popover
open={isOpen} open={isOpen}
@ -116,12 +144,10 @@ export const RepoSelector = React.forwardRef<
placeholder="Search repos..." placeholder="Search repos..."
onKeyDown={handleInputKeyDown} onKeyDown={handleInputKeyDown}
/> />
<CommandList> <CommandList ref={scrollContainerRef}>
<CommandEmpty>No results found.</CommandEmpty> <CommandEmpty>No results found.</CommandEmpty>
<CommandGroup> <CommandGroup>
{sortedRepos.map(({ repo, isSelected }) => {
{repos.map((repo) => {
const isSelected = selectedRepos.includes(repo);
return ( return (
<CommandItem <CommandItem
key={repo} key={repo}
@ -143,6 +169,7 @@ export const RepoSelector = React.forwardRef<
); );
})} })}
</CommandGroup> </CommandGroup>
</CommandList>
{selectedRepos.length > 0 && ( {selectedRepos.length > 0 && (
<> <>
<CommandSeparator /> <CommandSeparator />
@ -154,7 +181,6 @@ export const RepoSelector = React.forwardRef<
</CommandItem> </CommandItem>
</> </>
)} )}
</CommandList>
</Command> </Command>
</PopoverContent> </PopoverContent>
</Popover> </Popover>