I'm facing a problem with Reactjs
frontend codebase. We were using a library name react-autoauggest to achieve the autocomplete functionality but lead has decided to shift from react-autoauggest to downshift. I read through the document of this and implemented this using a useCombobox
hook but he is presenting some issues and telling me to solve these issues without any guidance. I created a clean version of these issues.
First I'm resolving issue-4
the clear button should clear the input field and close the menu. But when I click on the clear button, the input field is empty but the menu is still open. Can you please give me some guidance on how to to do these things in the downshift?
Here is my codesandbox link filtering data from the array of objects: View the Code sandbox here
App.js:
const App = () => {
// Array of objects
const [inputItems, setInputItems] = useState(data);
// State for all primitive types
const [value, setValue] = useState('');
/**
* It will returns the new filtered array.
* @param data Array<Object> - The array to iterate over
* @param inputValue {string} - Your input value
* @return Array<Object> - Returns the new filtered array
*/
const filterByName = (data, inputValue) => {
return data.filter(item => {
return item.name.toLowerCase().indexOf(inputValue.toLowerCase()) !== -1;
});
};
// props for the combobox
const comboboxProps = {
className: 'search has-icons-left has-buttons-right'
};
// props for the input
const inputProps = {
type: 'text',
className: 'form-control',
placeholder: 'Enter the state'
};
// props for the menu
const menuProps = {
className: 'menu'
};
// useComboBox
const {
isOpen,
getComboboxProps,
getInputProps,
getMenuProps,
getItemProps,
highlightedIndex,
selectItem,
} = useCombobox({
items: inputItems,
onInputValueChange: ({inputValue}) => {
setValue(inputValue);
setInputItems(filterByName(data, inputValue));
},
itemToString: (item) => item ? item.name : '',
});
return (
<div className="app">
<div {...getComboboxProps(comboboxProps)}>
<input {...getInputProps(inputProps)} />
<span className="icon is-left"><MarkerIcon/></span>
{(typeof value === 'string' && value.length > 0) ?
(<span className="button is-right">
<button className="btn btn-clear" onClick={() => selectItem(null)}>Clear</button>
</span>) : null}
{/* Suggestions */}
<ul {...getMenuProps(menuProps)}>
{isOpen && inputItems.map((item, index) => (
<li key={index} {...getItemProps({item, index})}
style={highlightedIndex === index ? {backgroundColor: "#f5f5f5"} : null}>
{item.name}
</li>
))}
</ul>
</div>
</div>
);
};
export default App;
#1, To prevent opening if there is no input value:
#2 Can be tricky, because if you want to modify the state, the filter will be activated. I would suggest some layout over their input, what displays the
inputItems[highlightedIndex]
if thehighlightedIndex > -1
#3, To close the recommendations box: