Skip to content

Conversation

@NickCrews
Copy link

Fixes #1903

This was generated by copilot.

If you want I can add a test for this.

I also am just blindly trusting that this effects multiselect in addition to single select, but it might not. If not, let me know and I can fix it up.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@tea-artist tea-artist requested a review from Copilot October 11, 2025 02:34
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR enhances the search functionality in select/multiselect dropdowns by prioritizing exact matches and prefix matches in the search results ordering, addressing issue #1903.

  • Implements a sorting algorithm that prioritizes exact matches first, then prefix matches, before other substring matches
  • Replaces the simple filter-only approach with a filter-then-sort strategy for better user experience
  • Maintains original ordering for items with the same match priority level

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +61 to +81
const filtered = options.filter((v) => v.label.toLowerCase().includes(searchLower));

// Sort to prioritize exact matches and prefix matches
return filtered.sort((a, b) => {
const aLabelLower = a.label.toLowerCase();
const bLabelLower = b.label.toLowerCase();

// Check for exact matches first
if (aLabelLower === searchLower && bLabelLower !== searchLower) return -1;
if (bLabelLower === searchLower && aLabelLower !== searchLower) return 1;

// Check for prefix matches
const aStartsWith = aLabelLower.startsWith(searchLower);
const bStartsWith = bLabelLower.startsWith(searchLower);

if (aStartsWith && !bStartsWith) return -1;
if (bStartsWith && !aStartsWith) return 1;

// If both start with search or neither does, maintain original order
return 0;
});
Copy link

Copilot AI Oct 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Converting each option's label to lowercase multiple times is inefficient. Consider preprocessing the lowercase labels once before filtering and sorting to avoid repeated string operations.

Suggested change
const filtered = options.filter((v) => v.label.toLowerCase().includes(searchLower));
// Sort to prioritize exact matches and prefix matches
return filtered.sort((a, b) => {
const aLabelLower = a.label.toLowerCase();
const bLabelLower = b.label.toLowerCase();
// Check for exact matches first
if (aLabelLower === searchLower && bLabelLower !== searchLower) return -1;
if (bLabelLower === searchLower && aLabelLower !== searchLower) return 1;
// Check for prefix matches
const aStartsWith = aLabelLower.startsWith(searchLower);
const bStartsWith = bLabelLower.startsWith(searchLower);
if (aStartsWith && !bStartsWith) return -1;
if (bStartsWith && !aStartsWith) return 1;
// If both start with search or neither does, maintain original order
return 0;
});
// Preprocess options to include lowercase label
const optionsWithLower = options.map((option) => ({
option,
labelLower: option.label.toLowerCase(),
}));
const filtered = optionsWithLower.filter((v) => v.labelLower.includes(searchLower));
// Sort to prioritize exact matches and prefix matches
filtered.sort((a, b) => {
// Check for exact matches first
if (a.labelLower === searchLower && b.labelLower !== searchLower) return -1;
if (b.labelLower === searchLower && a.labelLower !== searchLower) return 1;
// Check for prefix matches
const aStartsWith = a.labelLower.startsWith(searchLower);
const bStartsWith = b.labelLower.startsWith(searchLower);
if (aStartsWith && !bStartsWith) return -1;
if (bStartsWith && !aStartsWith) return 1;
// If both start with search or neither does, maintain original order
return 0;
});
// Return the original option objects
return filtered.map((v) => v.option);

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

prioritize prefix matches when searching in select/multiselect dropdown

2 participants