Tag autocomplete behavior fix

This commit is contained in:
Rainer Simon 2020-07-10 15:07:04 +02:00
parent 89809ad197
commit b75564b29f
3 changed files with 39 additions and 56 deletions

View File

@ -5,14 +5,21 @@ const Autocomplete = props => {
const element = useRef();
const [ value, setValue ] = useState('');
const [ inputItems, setInputItems ] = useState(props.vocabulary);
useEffect(() =>
element.current?.querySelector('input').focus(), []);
useEffect(() => element.current?.querySelector('input')?.focus(), []);
const onSubmit = inputValue => {
setValue('');
setInputItems([]); // Force-hide the popup
if (inputValue.trim().length > 0)
props.onSubmit(inputValue);
}
const onInputValueChange = ({ inputValue }) => {
props.onChange(inputValue);
setValue(inputValue);
setInputItems(
props.vocabulary.filter(item =>
item.toLowerCase().startsWith(inputValue.toLowerCase())))
@ -25,19 +32,23 @@ const Autocomplete = props => {
getComboboxProps,
highlightedIndex,
getItemProps,
} = useCombobox({ items: inputItems, onInputValueChange });
setInputValue
} = useCombobox({
items: inputItems,
onInputValueChange,
onSelectedItemChange: ({ inputValue }) => {
onSubmit(inputValue);
setInputValue('');
}
});
// TODO onEnter?
const onKeyDown = evt => {
if (evt.which == 13) {
if (!isOpen || highlightedIndex == -1) {
setInputItems([]); // To prevent the popup from showing up afterwards
props.onKeyDown(evt);
}
} else if (evt.which == 40 && props.content.length == 0) {
// To make options appear on key down
setInputItems(props.vocabulary);
}
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 (
@ -46,7 +57,8 @@ const Autocomplete = props => {
<input
{...getInputProps({ onKeyDown })}
placeholder={props.placeholder}
value={props.content} />
defaultValue={props.initialValue}
value={value} />
</div>
<ul {...getMenuProps()}>
{isOpen && inputItems.map((item, index) => (

View File

@ -9,7 +9,6 @@ import Autocomplete from '../Autocomplete';
const TagWidget = props => {
const [ showDelete, setShowDelete ] = useState(false);
const [ newTag, setNewTag ] = useState('');
// Every body with a 'tagging' purpose is considered a tag
const tagBodies = props.annotation ?
@ -27,11 +26,8 @@ const TagWidget = props => {
props.onRemoveBody(tag);
}
const onKeyDown = evt => {
if (evt.which === 13) { // Enter
props.onAppendBody({ type: 'TextualBody', purpose: 'tagging', value: newTag.trim() });
setNewTag(''); // Clear the input
}
const onSubmit = tag => {
props.onAppendBody({ type: 'TextualBody', purpose: 'tagging', value: tag.trim() });
}
return (
@ -58,10 +54,8 @@ const TagWidget = props => {
{ !props.readOnly &&
<Autocomplete
content={newTag}
placeholder={i18n.t('Add tag...')}
onChange={setNewTag}
onKeyDown={onKeyDown}
onSubmit={onSubmit}
vocabulary={props.vocabulary || []} />
}
</div>

View File

@ -26,11 +26,6 @@ export default class RelationEditor extends Component {
constructor(props) {
super(props);
this.state = {
content: getContent(props.relation)
}
this.element = React.createRef();
}
@ -42,11 +37,6 @@ export default class RelationEditor extends Component {
this.setPosition();
}
componentWillReceiveProps(next) {
if (this.props.relation !== next.relation)
this.setState({ content : getContent(next.relation) });
}
setPosition() {
if (this.element.current) {
const el = this.element.current;
@ -57,32 +47,19 @@ export default class RelationEditor extends Component {
}
}
onChange = value =>
this.setState({ content: value });
onKeyDown = evt => {
if (evt.which === 13) { // Enter = Submit
evt.preventDefault();
this.onSubmit();
} else if (evt.which === 27) {
this.props.onCancel();
}
}
onSubmit = () => {
onSubmit = value => {
const updatedAnnotation = this.props.relation.annotation.clone({
motivation: 'linking',
body: [{
type: 'TextualBody',
value: this.state.content,
value,
purpose: 'tagging'
}]
});
const updatedRelation = { ...this.props.relation, annotation: updatedAnnotation };
if (this.state.content) {
if (value) {
// Fire create or update event
if (this.props.relation.annotation.bodies.length === 0)
this.props.onRelationCreated(updatedRelation, this.props.relation);
@ -102,10 +79,10 @@ export default class RelationEditor extends Component {
<div className="r6o-relation-editor" ref={this.element}>
<div className="input-wrapper">
<Autocomplete
content={this.state.content}
initialValue={getContent(this.props.relation)}
placeholder="Tag..."
onChange={this.onChange}
onKeyDown={this.onKeyDown}
onSubmit={this.onSubmit}
onCancel={this.props.onCancel}
vocabulary={this.props.vocabulary || []} />
</div>