diff --git a/src/components/CountryPicker/CountrySelectorModal.js b/src/components/CountryPicker/CountrySelectorModal.js index b917e771e815..1b2615002ebe 100644 --- a/src/components/CountryPicker/CountrySelectorModal.js +++ b/src/components/CountryPicker/CountrySelectorModal.js @@ -7,6 +7,7 @@ import HeaderWithBackButton from '../HeaderWithBackButton'; import SelectionListRadio from '../SelectionListRadio'; import Modal from '../Modal'; import searchCountryOptions from '../../libs/searchCountryOptions'; +import StringUtils from '../../libs/StringUtils'; const propTypes = { /** Whether the modal is visible */ @@ -44,7 +45,7 @@ function CountrySelectorModal({currentCountry, isVisible, onClose, onCountrySele keyForList: countryISO, text: countryName, isSelected: currentCountry === countryISO, - searchValue: `${countryISO}${countryName}`.toLowerCase().replaceAll(CONST.REGEX.NON_ALPHABETIC_AND_NON_LATIN_CHARS, ''), + searchValue: StringUtils.sanitizeString(`${countryISO}${countryName}`), })), [translate, currentCountry], ); diff --git a/src/components/StatePicker/StateSelectorModal.js b/src/components/StatePicker/StateSelectorModal.js index 869c818a7009..83c9557fbf30 100644 --- a/src/components/StatePicker/StateSelectorModal.js +++ b/src/components/StatePicker/StateSelectorModal.js @@ -7,6 +7,7 @@ import HeaderWithBackButton from '../HeaderWithBackButton'; import SelectionListRadio from '../SelectionListRadio'; import useLocalize from '../../hooks/useLocalize'; import searchCountryOptions from '../../libs/searchCountryOptions'; +import StringUtils from '../../libs/StringUtils'; const propTypes = { /** Whether the modal is visible */ @@ -48,7 +49,7 @@ function StateSelectorModal({currentState, isVisible, onClose, onStateSelected, keyForList: state.stateISO, text: state.stateName, isSelected: currentState === state.stateISO, - searchValue: `${state.stateISO}${state.stateName}`.toLowerCase().replaceAll(CONST.REGEX.NON_ALPHABETIC_AND_NON_LATIN_CHARS, ''), + searchValue: StringUtils.sanitizeString(`${state.stateISO}${state.stateName}`), })), [translate, currentState], ); diff --git a/src/libs/StringUtils.js b/src/libs/StringUtils.js new file mode 100644 index 000000000000..8219f9e8077f --- /dev/null +++ b/src/libs/StringUtils.js @@ -0,0 +1,12 @@ +import _ from 'lodash'; +import CONST from '../CONST'; +/** + * Removes diacritical marks and non-alphabetic and non-latin characters from a string. + * @param {String} str - The input string to be sanitized. + * @returns {String} The sanitized string + */ +function sanitizeString(str) { + return _.chain(str).deburr().toLower().value().replaceAll(CONST.REGEX.NON_ALPHABETIC_AND_NON_LATIN_CHARS, ''); +} + +export default {sanitizeString}; diff --git a/src/libs/searchCountryOptions.js b/src/libs/searchCountryOptions.js index 84351665111d..5aa8a052374e 100644 --- a/src/libs/searchCountryOptions.js +++ b/src/libs/searchCountryOptions.js @@ -1,5 +1,5 @@ -import _ from 'underscore'; -import CONST from '../CONST'; +import _ from 'lodash'; +import StringUtils from './StringUtils'; /** * Searches the countries/states data and returns sorted results based on the search query @@ -8,15 +8,15 @@ import CONST from '../CONST'; * @returns {Object[]} An array of countries/states sorted based on the search query */ function searchCountryOptions(searchValue, countriesData) { - const trimmedSearchValue = searchValue.toLowerCase().replaceAll(CONST.REGEX.NON_ALPHABETIC_AND_NON_LATIN_CHARS, ''); - if (trimmedSearchValue.length === 0) { + const trimmedSearchValue = StringUtils.sanitizeString(searchValue); + if (_.isEmpty(trimmedSearchValue)) { return []; } - const filteredData = _.filter(countriesData, (country) => country.searchValue.includes(trimmedSearchValue)); + const filteredData = _.filter(countriesData, (country) => _.includes(country.searchValue, trimmedSearchValue)); // sort by country code - return _.sortBy(filteredData, (country) => (country.value.toLowerCase() === trimmedSearchValue ? -1 : 1)); + return _.sortBy(filteredData, (country) => (_.toLower(country.value) === trimmedSearchValue ? -1 : 1)); } export default searchCountryOptions;