Fixes #74
This commit is contained in:
parent
8f0a78a7d4
commit
fbdcdd18dd
|
@ -1,102 +1,93 @@
|
|||
import React, { Component, createRef } from 'react';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { useCombobox } from 'downshift';
|
||||
|
||||
export default class Autocomplete extends Component {
|
||||
const Autocomplete = props => {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const element = useRef();
|
||||
|
||||
this.element = createRef();
|
||||
const [ inputItems, setInputItems ] = useState(props.vocabulary || []);
|
||||
|
||||
this.state = {
|
||||
inputItems: props.vocabulary || []
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.element.current) {
|
||||
if (this.props.initialValue)
|
||||
this.element.current.querySelector('input').value = this.props.initialValue;
|
||||
|
||||
if (this.props.focus)
|
||||
this.element.current.querySelector('input').focus({ preventScroll: true });
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
if (props.initialValue)
|
||||
element.current.querySelector('input').value = props.initialValue;
|
||||
|
||||
if (props.focus)
|
||||
element.current.querySelector('input').focus({ preventScroll: true });
|
||||
}, [])
|
||||
|
||||
onInputValueChange = ({ inputValue }) => {
|
||||
const onInputValueChange = ({ inputValue }) => {
|
||||
if (inputValue.length > 0) {
|
||||
const prefixMatches = this.props.vocabulary.filter(item => {
|
||||
const prefixMatches = props.vocabulary.filter(item => {
|
||||
return item.toLowerCase().startsWith(inputValue.toLowerCase());
|
||||
});
|
||||
|
||||
this.setState({ inputItems: prefixMatches });
|
||||
setInputItems(prefixMatches);
|
||||
} else {
|
||||
// ...or none, if the input is empty
|
||||
this.setState({ inputItems: [] });
|
||||
setInputItems([]);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const {
|
||||
isOpen,
|
||||
getMenuProps,
|
||||
getInputProps,
|
||||
getComboboxProps,
|
||||
highlightedIndex,
|
||||
getItemProps,
|
||||
setInputValue
|
||||
} = useCombobox({
|
||||
items: this.state.inputItems,
|
||||
onInputValueChange: this.onInputValueChange,
|
||||
onSelectedItemChange: ({ inputValue }) => {
|
||||
onSubmit(inputValue);
|
||||
setInputValue('');
|
||||
}
|
||||
});
|
||||
|
||||
const onSubmit = inputValue => {
|
||||
const {
|
||||
isOpen,
|
||||
getMenuProps,
|
||||
getInputProps,
|
||||
getComboboxProps,
|
||||
highlightedIndex,
|
||||
getItemProps,
|
||||
setInputValue
|
||||
} = useCombobox({
|
||||
items: inputItems,
|
||||
onInputValueChange: onInputValueChange,
|
||||
onSelectedItemChange: ({ inputValue }) => {
|
||||
onSubmit(inputValue);
|
||||
setInputValue('');
|
||||
if (inputValue.trim().length > 0)
|
||||
this.props.onSubmit(inputValue);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const onKeyUp = evt => {
|
||||
const { value } = evt.target;
|
||||
|
||||
if (evt.which == 13 && highlightedIndex == -1) {
|
||||
onSubmit(value);
|
||||
} else if (evt.which == 40 && value.length == 0) {
|
||||
this.setState({ inputItems: this.props.vocabulary }); // Show all options on key down
|
||||
} else if (evt.which == 27) {
|
||||
this.props.onCancel && this.props.onCancel();
|
||||
} else {
|
||||
this.props.onChange && this.props.onChange(value);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="r6o-autocomplete" ref={this.element}>
|
||||
<div {...getComboboxProps()}>
|
||||
<input
|
||||
{...getInputProps({ onKeyUp })}
|
||||
placeholder={this.props.placeholder} />
|
||||
</div>
|
||||
<ul {...getMenuProps()}>
|
||||
{isOpen && this.state.inputItems.map((item, index) => (
|
||||
<li style={
|
||||
highlightedIndex === index
|
||||
? { backgroundColor: '#bde4ff' }
|
||||
: {}
|
||||
}
|
||||
key={`${item}${index}`}
|
||||
{...getItemProps({ item, index })}>
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
const onSubmit = inputValue => {
|
||||
setInputValue('');
|
||||
if (inputValue.trim().length > 0)
|
||||
props.onSubmit(inputValue);
|
||||
}
|
||||
|
||||
const onKeyUp = 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();
|
||||
} else {
|
||||
props.onChange && props.onChange(value);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="r6o-autocomplete" ref={element}>
|
||||
<div {...getComboboxProps()}>
|
||||
<input
|
||||
{...getInputProps({ onKeyUp })}
|
||||
placeholder={props.placeholder} />
|
||||
</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;
|
||||
|
|
Loading…
Reference in New Issue