ComboBox: Fall back to substring matching for symbols/operators (#100148)

This commit is contained in:
Leon Sorokin 2025-02-06 03:33:08 -06:00 committed by GitHub
parent f89da88f0f
commit d5f1f4eb5c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 18 additions and 0 deletions

View File

@ -58,4 +58,17 @@ describe('combobox filter', () => {
expect(matches.map((m) => m.value)).toEqual(['台南市', '南投縣']);
});
});
describe('operators', () => {
it('should do substring match when needle is only symbols', () => {
const needle = '=';
const stringOptions = ['=', '<=', '>', '!~'];
const options = stringOptions.map((value) => ({ value }));
const matches = fuzzyFind(options, stringOptions, needle);
expect(matches.map((m) => m.value)).toEqual(['=', '<=']);
});
});
});

View File

@ -4,6 +4,9 @@ import { ALL_OPTION_VALUE, ComboboxOption } from './types';
// https://catonmat.net/my-favorite-regex :)
const REGEXP_NON_ASCII = /[^ -~]/m;
// https://www.asciitable.com/
// matches only these: `~!@#$%^&*()_+-=[]\{}|;':",./<>?
const REGEXP_ONLY_SYMBOLS = /^[\x21-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]+$/m;
// limit max terms in needle that qualify for re-ordering
const outOfOrderLimit = 5;
// beyond 25 chars fall back to substring search
@ -51,6 +54,8 @@ export function fuzzyFind<T extends string | number>(
else if (
// contains non-ascii
REGEXP_NON_ASCII.test(needle) ||
// is only ascii symbols (operators)
REGEXP_ONLY_SYMBOLS.test(needle) ||
// too long (often copy-paste from somewhere)
needle.length > maxNeedleLength ||
uf.split(needle).length > maxFuzzyTerms