1
1
mirror of https://github.com/Fabio286/antares.git synced 2025-06-05 21:59:22 +02:00

feat(UI): BaseSelect option list scrolls automatically using up/down keys

This commit is contained in:
Giulio Ganci
2022-05-08 18:59:00 +02:00
parent a037d0cc01
commit 0043d07708

View File

@ -26,17 +26,22 @@
@focus.prevent="activate()" @focus.prevent="activate()"
@blur.prevent="deactivate()" @blur.prevent="deactivate()"
@keyup.esc="deactivate()" @keyup.esc="deactivate()"
@keydown.down.prevent="moveDown()" @keydown.down.prevent="keyArrows('down')"
@keydown.up.prevent="moveUp()" @keydown.up.prevent="keyArrows('up')"
@keypress.enter.prevent.stop.self="select(filteredOptions[hightlightedIndex])" @keypress.enter.prevent.stop.self="select(filteredOptions[hightlightedIndex])"
> >
<span v-if="searchable && !isOpen || !searchable">{{ currentOptionLabel }}</span> <span v-if="searchable && !isOpen || !searchable">{{ currentOptionLabel }}</span>
</div> </div>
<div v-if="isOpen" class="select__list-wrapper"> <div
v-if="isOpen"
ref="optionList"
class="select__list-wrapper"
>
<ul class="select__list" @mousedown.prevent> <ul class="select__list" @mousedown.prevent>
<li <li
v-for="(opt, index) of filteredOptions" v-for="(opt, index) of filteredOptions"
:key="getOptionValue(opt)" :key="getOptionValue(opt)"
:ref="(el) => optionRefs[index] = el"
:class="{ :class="{
'select__option--highlight': index === hightlightedIndex, 'select__option--highlight': index === hightlightedIndex,
'select__option--selected': isSelected(opt) 'select__option--selected': isSelected(opt)
@ -101,6 +106,8 @@ export default defineComponent({
const isOpen = ref(false); const isOpen = ref(false);
const el = ref(null); const el = ref(null);
const searchInput = ref(null); const searchInput = ref(null);
const optionList = ref(null);
const optionRefs = [];
const searchText = ref(''); const searchText = ref('');
const filteredOptions = computed(() => { const filteredOptions = computed(() => {
const normalizedSearch = (searchText.value || '').toLowerCase().trim(); const normalizedSearch = (searchText.value || '').toLowerCase().trim();
@ -187,13 +194,21 @@ export default defineComponent({
emit('close'); emit('close');
}; };
const moveUp = () => { const keyArrows = (direction) => {
if (hightlightedIndex.value > 0) const sum = direction === 'down' ? +1 : -1;
hightlightedIndex.value--; const index = hightlightedIndex.value + sum;
}; hightlightedIndex.value = Math.max(0, index > filteredOptions.value.length - 1 ? filteredOptions.value.length - 1 : index);
const moveDown = () => {
if (hightlightedIndex.value < filteredOptions.value.length -1) const optEl = optionRefs[hightlightedIndex.value];
hightlightedIndex.value++;
const visMin = optionList.value.scrollTop;
const visMax = optionList.value.scrollTop + optionList.value.clientHeight - optEl.clientHeight;
if (optEl.offsetTop < visMin)
optionList.value.scrollTop = optEl.offsetTop;
else if (optEl.offsetTop >= visMax)
optionList.value.scrollTop = optEl.offsetTop - optionList.value.clientHeight + optEl.clientHeight;
}; };
return { return {
@ -209,10 +224,11 @@ export default defineComponent({
deactivate, deactivate,
select, select,
isSelected, isSelected,
moveUp, keyArrows,
moveDown,
isOpen, isOpen,
hightlightedIndex hightlightedIndex,
optionList,
optionRefs
}; };
} }
}); });