recogito-client-core/src/editor/widgets/Autocomplete.js

86 lines
2.1 KiB
JavaScript

import React, { useState, useRef } from 'react'
import { useCombobox } from 'downshift'
const Autocomplete = props => {
const element = useRef();
const [ inputItems, setInputItems ] = useState(props.vocabulary);
const onInputValueChange = ({ inputValue }) => {
if (inputValue.length > 0) {
// Set suggestions to prefix matches...
const prefixMatches = props.vocabulary.filter(item => {
return item.toLowerCase().startsWith(inputValue.toLowerCase());
});
setInputItems(prefixMatches);
} else {
// ...or none, if the input is empty
setInputItems([]);
}
}
const {
isOpen,
getMenuProps,
getInputProps,
getComboboxProps,
highlightedIndex,
getItemProps,
setInputValue
} = useCombobox({
items: inputItems,
onInputValueChange,
onSelectedItemChange: ({ inputValue }) => {
onSubmit(inputValue);
setInputValue('');
}
});
const onSubmit = inputValue => {
setInputValue('');
if (inputValue.trim().length > 0)
props.onSubmit(inputValue);
}
const onKeyDown = evt => {
const { value } = evt.target;
if (evt.which == 13 && highlightedIndex == -1) {
onSubmit(value);
} else if (evt.which == 40 && value.length == 0) {
setInputItems(props.vocabulary); // Show all options on key down
} else if (evt.which == 27) {
props.onCancel && props.onCancel();
}
}
return (
<div ref={element} className="r6o-autocomplete">
<div {...getComboboxProps()}>
<input
{...getInputProps({ onKeyDown })}
placeholder={props.placeholder}
defaultValue={props.initialValue}
/>
</div>
<ul {...getMenuProps()}>
{isOpen && inputItems.map((item, index) => (
<li style={
highlightedIndex === index
? { backgroundColor: '#bde4ff' }
: {}
}
key={`${item}${index}`}
{...getItemProps({ item, index })}>
{item}
</li>
))}
</ul>
</div>
)
}
export default Autocomplete;