fix #504: keyboard-accessible autocomplete

This commit is contained in:
antelle 2017-02-05 14:33:32 +01:00
parent 048d22775f
commit 58c8038e5b
3 changed files with 46 additions and 2 deletions

View File

@ -1,6 +1,7 @@
'use strict';
const FieldViewText = require('./field-view-text');
const Keys = require('../../const/keys');
const FieldViewAutocomplete = FieldViewText.extend({
endEdit: function(newVal, extra) {
@ -8,6 +9,7 @@ const FieldViewAutocomplete = FieldViewText.extend({
this.autocomplete.remove();
this.autocomplete = null;
}
delete this.selectedCopmletionIx;
FieldViewText.prototype.endEdit.call(this, newVal, extra);
},
@ -20,6 +22,7 @@ const FieldViewAutocomplete = FieldViewText.extend({
left: fieldRect.left,
width: fieldRect.width - 2
});
delete this.selectedCopmletionIx;
this.autocomplete.mousedown(this.autocompleteClick.bind(this));
if (this.input.val()) {
this.autocomplete.hide();
@ -34,10 +37,44 @@ const FieldViewAutocomplete = FieldViewText.extend({
FieldViewText.prototype.fieldValueInput.call(this, e);
},
fieldValueKeydown: function(e) {
switch (e.which) {
case Keys.DOM_VK_UP:
this.moveAutocomplete(false);
e.preventDefault();
break;
case Keys.DOM_VK_DOWN:
this.moveAutocomplete(true);
e.preventDefault();
break;
case Keys.DOM_VK_RETURN:
const selectedItem = this.autocomplete.find('.details__field-autocomplete-item--selected').text();
if (selectedItem) {
this.input.val(selectedItem);
this.endEdit(selectedItem);
}
break;
default:
delete this.selectedCopmletionIx;
}
FieldViewText.prototype.fieldValueKeydown.call(this, e);
},
moveAutocomplete: function(next) {
const completions = this.model.getCompletions(this.input.val());
if (typeof this.selectedCopmletionIx === 'number') {
this.selectedCopmletionIx = (completions.length + this.selectedCopmletionIx + (next ? 1 : -1)) % completions.length;
} else {
this.selectedCopmletionIx = next ? 0 : completions.length - 1;
}
this.updateAutocomplete();
},
updateAutocomplete: function() {
const completions = this.model.getCompletions(this.input.val());
const completionsHtml = completions.map(item => {
return '<div class="details__field-autocomplete-item">' + _.escape(item) + '</div>';
const completionsHtml = completions.map((item, ix) => {
const sel = ix === this.selectedCopmletionIx ? 'details__field-autocomplete-item--selected' : '';
return '<div class="details__field-autocomplete-item ' + sel + '">' + _.escape(item) + '</div>';
}).join('');
this.autocomplete.html(completionsHtml);
this.autocomplete.toggle(!!completionsHtml);

View File

@ -527,6 +527,12 @@
display: inline-block;
word-break: break-all;
@include area-selectable(bottom);
&--selected {
@include th {
background-color: secondary-background-color();
border-bottom: selected-hover-border();
}
}
}
}
}

View File

@ -3,6 +3,7 @@ Release notes
##### v1.5.0 (TBD)
`+` file path hint in recent files list
`+` cacheConfigSettings config option
`+` keyboard-accessible autocomplete
##### v1.4.0 (2017-02-04)
KDBX4 format support and minor improvements