mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-10 07:56:50 -04:00
<AutocompleteSelect> support keyboard control
This commit is contained in:
parent
6781244940
commit
a5dbd7c044
@ -1,10 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="select flex-grow-1">
|
<div class="select flex-grow-1">
|
||||||
<input type="text" v-model="filter" class="form-control" @focus="show" @blur="hide" :placeholder="$t('profile.timezone.placeholder')"/>
|
<input type="text" v-model="filter" class="form-control" :placeholder="$t('profile.timezone.placeholder')"
|
||||||
|
ref="filter"
|
||||||
|
@focus="show" @blur="hide" @keydown="filterKeydown"
|
||||||
|
/>
|
||||||
<div class="list-group shadow" v-show="shown">
|
<div class="list-group shadow" v-show="shown">
|
||||||
<a v-for="(display, option) in options"
|
<a v-for="(display, option) in visibleOptions"
|
||||||
v-if="!filter || option.toLowerCase().includes(filter.toLowerCase()) || display.toLowerCase().includes(filter.toLowerCase())"
|
:class="['list-group-item', 'list-group-item-action', highlightedOption === option ? 'active' : '']" href="#"
|
||||||
class="list-group-item list-group-item-action" href="#"
|
|
||||||
@click.prevent="select(option)">
|
@click.prevent="select(option)">
|
||||||
{{ display }}
|
{{ display }}
|
||||||
</a>
|
</a>
|
||||||
@ -23,17 +25,20 @@ export default {
|
|||||||
return {
|
return {
|
||||||
filter: this.options[this.value] || this.value || '',
|
filter: this.options[this.value] || this.value || '',
|
||||||
shown: false,
|
shown: false,
|
||||||
|
highlighted: -1,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
value() {
|
value() {
|
||||||
this.filter = this.options[this.value] || this.value;
|
this.filter = this.options[this.value] || this.value;
|
||||||
|
this.highlighted = -1;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
select(option) {
|
select(option) {
|
||||||
this.$emit('input', option);
|
this.$emit('input', option);
|
||||||
this.hide();
|
this.hide();
|
||||||
|
this.highlighted = -1;
|
||||||
},
|
},
|
||||||
show() {
|
show() {
|
||||||
this.shown = true;
|
this.shown = true;
|
||||||
@ -41,6 +46,42 @@ export default {
|
|||||||
hide() {
|
hide() {
|
||||||
setTimeout(() => { this.shown = false; }, 100)
|
setTimeout(() => { this.shown = false; }, 100)
|
||||||
},
|
},
|
||||||
|
filterKeydown(e) {
|
||||||
|
if (!this.shown) {
|
||||||
|
this.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (e.key) {
|
||||||
|
case 'ArrowUp':
|
||||||
|
this.highlighted--;
|
||||||
|
break;
|
||||||
|
case 'ArrowDown':
|
||||||
|
this.highlighted++;
|
||||||
|
break;
|
||||||
|
case 'Enter':
|
||||||
|
if (this.highlightedOption) {
|
||||||
|
this.select(this.highlightedOption);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
visibleOptions() {
|
||||||
|
return Object.fromEntries(Object.entries(this.options).filter(([option, display]) => {
|
||||||
|
return !this.filter
|
||||||
|
|| option.toLowerCase().includes(this.filter.toLowerCase())
|
||||||
|
|| display.toLowerCase().includes(this.filter.toLowerCase())
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
highlightedOption() {
|
||||||
|
return Object.keys(this.visibleOptions)[this.highlighted];
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user