diff --git a/lib/Autocomplete.js b/lib/Autocomplete.js index 1658c8bb..fa645a39 100644 --- a/lib/Autocomplete.js +++ b/lib/Autocomplete.js @@ -25,6 +25,9 @@ function getScrollOffset() { } } +const startsWithIgnoreCase = (haystack, needle) => + haystack.toLowerCase().indexOf(needle.toLowerCase()) === 0 + class Autocomplete extends React.Component { static propTypes = { @@ -137,6 +140,16 @@ class Autocomplete extends React.Component { * menu. */ autoHighlight: PropTypes.bool, + /** + * Arguments: `itemValue: String, searchValue: String, item: Any` + * + * Invoked when attempting to use an item as auto highlighted value. The + * return value is used to determine whether the item should be actually + * highlighted or not. + * By default we check whether the item value starts with the search value + * case insensitively. + */ + isItemAutoHighlightMatch: PropTypes.func, /** * Whether or not to automatically select the highlighted item when the * `` loses focus. @@ -186,6 +199,7 @@ class Autocomplete extends React.Component { maxHeight: '50%', // TODO: don't cheat, let it flow to the bottom }, autoHighlight: true, + isItemAutoHighlightMatch: startsWithIgnoreCase, selectOnBlur: false, onMenuVisibilityChange() {}, } @@ -391,7 +405,7 @@ class Autocomplete extends React.Component { maybeAutoCompleteText(state, props) { const { highlightedIndex } = state - const { value, getItemValue } = props + const { value, getItemValue, isItemAutoHighlightMatch } = props let index = highlightedIndex === null ? 0 : highlightedIndex let items = this.getFilteredItems(props) for (let i = 0; i < items.length ; i++) { @@ -400,14 +414,11 @@ class Autocomplete extends React.Component { index = (index + 1) % items.length } const matchedItem = items[index] && props.isItemSelectable(items[index]) ? items[index] : null - if (value !== '' && matchedItem) { - const itemValue = getItemValue(matchedItem) - const itemValueDoesMatch = (itemValue.toLowerCase().indexOf( - value.toLowerCase() - ) === 0) - if (itemValueDoesMatch) { - return { highlightedIndex: index } - } + if (value !== '' + && matchedItem + && isItemAutoHighlightMatch(getItemValue(matchedItem), value, matchedItem) + ) { + return { highlightedIndex: index } } return { highlightedIndex: null } }