setHighlightedIndex not working from onInputValueChange
-
downshiftversion: 6.1.3 -
nodeversion: 14.15.1 -
npmversion: 6.13.7
Relevant code or config
/**
* find the index of the item that most closely
* matches the users input
*/
const findHighlightedIndex = (inputValue) => {
if (!inputValue) {
return -1;
}
const searchValue = inputValue.toLowerCase();
for (let i = 0; i < items.length; i++) {
const item = itemToString(items[i]).toLowerCase();
if (item.indexOf(searchValue) !== -1) {
return i;
}
}
return -1;
};
/**
* manually set the current highlighted item as Downshift understands it based
* on the users input
*/
const handleOnInputValueChange = (inputValue, { setHighlightedIndex }) => {
setHighlightedIndex(findHighlightedIndex(inputValue));
};
...
<Downshift
onChange={handleOnChange}
onInputValueChange={handleOnInputValueChange} // <----
itemToString={itemToString}
itemToElement={itemToElement}
defaultSelectedItem={defaultSelectedItem}
>
...
What you did:
I am trying to manually set the highlightedIndex via setHighlightedIndex to the item that most resembles the inputValue
To do this, I am calling a function called handleOnInputValueChange when onInputValueChange is triggered. There, I find the index I'd like to be highlighted and I send it to the setHighlightedIndex function
What happened:
The handleOnInputValueChange is being called, and the correct index value is being returned from findHighlightedIndex. However, the highlighted item is not changing when it's respective index is sent to setHighlightedIndex
Note: The reason I am using <Downshift/> vs. the useComboBox hook is because I need access to getRootProps seeing as I am using a custom wrapper...let me know if this is amendable
Hi! The setHighlightedIndex function should work. If you can spend some time debugging this great, I can help you submit a fix, if any.
Though, in your current scenario, I'd use stateReducer. Just do the same search as you are doing now in the state reducer function and return the default state from Downshift along with the custom highlightedIndex. I think it's more elegant. There are many usage examples of state reducer in our github/codesandbox repo/docsite, here is one. https://www.downshift-js.com/use-combobox#state-reducer
But if you can investigate the problem you are facing then that's even better for us. Also you could consider creating a codesandbox reproducing this bug. Thanks!
Thank you for the speedy reply. Let me give stateReducer a shot!
Hello! I was able to get the highlightIndex set correctly by using the stateReducer.
However, I am running into another issue. The arrowDown and arrowUp functionality that updates the highlighted index does not work when I initially open the menu, but does once I've opened and closed the menu once.
- on initial render, if I open the menu then click the up and down arrows, nothing happens
- on initial render, if I open the menu, close it and then open it again, the arrows work as suspected
please see my stateReducer below....
const stateReducer = (state, changes) => {
setTopItems(changes.selectedItems);
switch (changes.type) {
/**
* ensure that the menu stays open when item is selected
* and that selected item is highlighted
*/
case Downshift.stateChangeTypes.keyDownEnter:
case Downshift.stateChangeTypes.clickItem:
return {
...changes,
isOpen: true,
highlightedIndex: state.highlightedIndex
}
/**
* close menu when escape key pressed
*/
case Downshift.stateChangeTypes.keyDownEscape:
return {
...changes,
isOpen: false
}
/**
* otherwise, do the default Downshift-y things
*/
default:
return changes
}
}
setTopItems(changes.selectedItems); should not be in the reducer, as it's meant to be a pure function.
Otherwise I see nothing wrong with the reducer.
FYI to maintainers – I also have this issue. setHighlightedIndex doesn't seem to work on this callback.